From 79321ffce28d52f68212ee029a14d5ae32f9645f Mon Sep 17 00:00:00 2001 From: Hugo Amnov Date: Mon, 11 May 2020 02:44:14 +0200 Subject: [PATCH] Replace freetype with stb_truetype in font examples (#2139) * Replace freetype with stb_truetype in font example * Remove freetype --- 3rdparty/freetype/FTL.TXT | 169 - 3rdparty/freetype/README.md | 5 - 3rdparty/freetype/freetype.h | 117440 ----------------------- examples/10-font/font.cpp | 6 +- examples/11-fontsdf/fontsdf.cpp | 3 +- examples/common/font/font_manager.cpp | 269 +- 6 files changed, 74 insertions(+), 117818 deletions(-) delete mode 100644 3rdparty/freetype/FTL.TXT delete mode 100644 3rdparty/freetype/README.md delete mode 100644 3rdparty/freetype/freetype.h diff --git a/3rdparty/freetype/FTL.TXT b/3rdparty/freetype/FTL.TXT deleted file mode 100644 index bbaba33f4..000000000 --- a/3rdparty/freetype/FTL.TXT +++ /dev/null @@ -1,169 +0,0 @@ - The FreeType Project LICENSE - ---------------------------- - - 2006-Jan-27 - - Copyright 1996-2002, 2006 by - David Turner, Robert Wilhelm, and Werner Lemberg - - - -Introduction -============ - - The FreeType Project is distributed in several archive packages; - some of them may contain, in addition to the FreeType font engine, - various tools and contributions which rely on, or relate to, the - FreeType Project. - - This license applies to all files found in such packages, and - which do not fall under their own explicit license. The license - affects thus the FreeType font engine, the test programs, - documentation and makefiles, at the very least. - - This license was inspired by the BSD, Artistic, and IJG - (Independent JPEG Group) licenses, which all encourage inclusion - and use of free software in commercial and freeware products - alike. As a consequence, its main points are that: - - o We don't promise that this software works. However, we will be - interested in any kind of bug reports. (`as is' distribution) - - o You can use this software for whatever you want, in parts or - full form, without having to pay us. (`royalty-free' usage) - - o You may not pretend that you wrote this software. If you use - it, or only parts of it, in a program, you must acknowledge - somewhere in your documentation that you have used the - FreeType code. (`credits') - - We specifically permit and encourage the inclusion of this - software, with or without modifications, in commercial products. - We disclaim all warranties covering The FreeType Project and - assume no liability related to The FreeType Project. - - - Finally, many people asked us for a preferred form for a - credit/disclaimer to use in compliance with this license. We thus - encourage you to use the following text: - - """ - Portions of this software are copyright © The FreeType - Project (www.freetype.org). All rights reserved. - """ - - Please replace with the value from the FreeType version you - actually use. - - -Legal Terms -=========== - -0. Definitions --------------- - - Throughout this license, the terms `package', `FreeType Project', - and `FreeType archive' refer to the set of files originally - distributed by the authors (David Turner, Robert Wilhelm, and - Werner Lemberg) as the `FreeType Project', be they named as alpha, - beta or final release. - - `You' refers to the licensee, or person using the project, where - `using' is a generic term including compiling the project's source - code as well as linking it to form a `program' or `executable'. - This program is referred to as `a program using the FreeType - engine'. - - This license applies to all files distributed in the original - FreeType Project, including all source code, binaries and - documentation, unless otherwise stated in the file in its - original, unmodified form as distributed in the original archive. - If you are unsure whether or not a particular file is covered by - this license, you must contact us to verify this. - - The FreeType Project is copyright (C) 1996-2000 by David Turner, - Robert Wilhelm, and Werner Lemberg. All rights reserved except as - specified below. - -1. No Warranty --------------- - - THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO - USE, OF THE FREETYPE PROJECT. - -2. Redistribution ------------------ - - This license grants a worldwide, royalty-free, perpetual and - irrevocable right and license to use, execute, perform, compile, - display, copy, create derivative works of, distribute and - sublicense the FreeType Project (in both source and object code - forms) and derivative works thereof for any purpose; and to - authorize others to exercise some or all of the rights granted - herein, subject to the following conditions: - - o Redistribution of source code must retain this license file - (`FTL.TXT') unaltered; any additions, deletions or changes to - the original files must be clearly indicated in accompanying - documentation. The copyright notices of the unaltered, - original files must be preserved in all copies of source - files. - - o Redistribution in binary form must provide a disclaimer that - states that the software is based in part of the work of the - FreeType Team, in the distribution documentation. We also - encourage you to put an URL to the FreeType web page in your - documentation, though this isn't mandatory. - - These conditions apply to any software derived from or based on - the FreeType Project, not just the unmodified files. If you use - our work, you must acknowledge us. However, no fee need be paid - to us. - -3. Advertising --------------- - - Neither the FreeType authors and contributors nor you shall use - the name of the other for commercial, advertising, or promotional - purposes without specific prior written permission. - - We suggest, but do not require, that you use one or more of the - following phrases to refer to this software in your documentation - or advertising materials: `FreeType Project', `FreeType Engine', - `FreeType library', or `FreeType Distribution'. - - As you have not signed this license, you are not required to - accept it. However, as the FreeType Project is copyrighted - material, only this license, or another one contracted with the - authors, grants you the right to use, distribute, and modify it. - Therefore, by using, distributing, or modifying the FreeType - Project, you indicate that you understand and accept all the terms - of this license. - -4. Contacts ------------ - - There are two mailing lists related to FreeType: - - o freetype@nongnu.org - - Discusses general use and applications of FreeType, as well as - future and wanted additions to the library and distribution. - If you are looking for support, start in this list if you - haven't found anything to help you in the documentation. - - o freetype-devel@nongnu.org - - Discusses bugs, as well as engine internals, design issues, - specific licenses, porting, etc. - - Our home page can be found at - - http://www.freetype.org - - ---- end of FTL.TXT --- diff --git a/3rdparty/freetype/README.md b/3rdparty/freetype/README.md deleted file mode 100644 index c149d1d19..000000000 --- a/3rdparty/freetype/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The Freetype code is copyright 2013 The FreeType Project. -All rights reserved. (www.freetype.org). -Distributed under the FreeType License: see FTL.TXT. - -freetype.h is an amalagmation of Freetype 2.4.11 made by Jeremie Roy in march 2013. \ No newline at end of file diff --git a/3rdparty/freetype/freetype.h b/3rdparty/freetype/freetype.h deleted file mode 100644 index fb67c097b..000000000 --- a/3rdparty/freetype/freetype.h +++ /dev/null @@ -1,117440 +0,0 @@ -#pragma once - -#if defined(_MSC_VER) && !defined(__clang__) -# pragma warning(push) -# pragma warning(disable: 4100) // DISABLE warning C4100: '' : unreferenced formal parameter -# pragma warning(disable: 4146) // DISABLE warning C4146: unary minus operator applied to unsigned type, result still unsigned -# pragma warning(disable: 4244) // DISABLE warning C4244: '+=' : conversion from '__int64' to 'FT_ULong', possible loss of data -# pragma warning(disable: 4267) // DISABLE warning C4267: 'initializing' : conversion from 'size_t' to 'FT_Long', possible loss of data -# pragma warning(disable: 4700) // DISABLE warning C4700: uninitialized local variable 'temp' used -# pragma warning(disable: 4701) // DISABLE warning C4701: potentially uninitialized local variable '' used -#elif defined(__GNUC__) -# pragma GCC system_header -#elif defined(__clang__) -# pragma clang diagnostic ignored "-Wshift-negative-value" -# pragma clang diagnostic ignored "-Wuninitialized" -#endif // defined(__GNUC__) - -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* ANSI-specific FreeType low-level system interface (body). */ -/* */ -/* Copyright 1996-2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* 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__ -/***************************************************************************/ -/* */ -/* ftheader.h */ -/* */ -/* Build macros of the FreeType 2 library. */ -/* */ -/* Copyright 1996-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 __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 -/* nothing */ -#define FT_BEGIN_HEADER -#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 -/* nothing */ -#define FT_END_HEADER -#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_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> -/***************************************************************************/ -/* */ -/* internal.h */ -/* */ -/* Internal header files (specification only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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> -/* END */ -/* FT2_BUILD_LIBRARY */ -#endif -/* __FT2_BUILD_H__ */ -#endif -/* END */ -/* __FT2_BUILD_GENERIC_H__ */ -#endif -/* END */ -/***************************************************************************/ -/* */ -/* ftconfig.h */ -/* */ -/* ANSI-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2004, 2006-2008, 2010-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 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'. */ -/* */ -/*************************************************************************/ -#define __FTCONFIG_H__ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-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 __FTOPTION_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 */ -#undef 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 */ -#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. */ -/* */ -/* #define FT_CONFIG_OPTION_USE_ZLIB */ -#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 */ - #undef 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 */ -#undef 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 */ -#undef 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. */ -/* */ -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -/*************************************************************************/ -/* */ -/* 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 */ -#undef FT_DEBUG_LEVEL_ERROR -#undef 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 */ -#undef 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 */ -#undef 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 */ -#undef 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 */ -#undef 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 */ -#undef 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 -/*************************************************************************/ -/*************************************************************************/ -/**** ****/ -/**** 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 */ -#undef AF_CONFIG_OPTION_USE_WARPER -/* */ -/* - * Define this variable if you want to keep the layout of internal - * structures that was used prior to FreeType 2.2. This also compiles in - * a few obsolete functions to avoid linking problems on typical Unix - * distributions. - * - * For embedded systems or building a new distribution from scratch, it - * is recommended to disable the macro since it reduces the library's code - * size and activates a few memory-saving optimizations as well. - */ -/* #define FT_CONFIG_OPTION_OLD_INTERNALS*/ -#undef FT_CONFIG_OPTION_OLD_INTERNALS -/* - * To detect legacy cache-lookup call from a rogue client (<= 2.1.7), - * we restrict the number of charmaps in a font. The current API of - * FTC_CMapCache_Lookup() takes cmap_index & charcode, but old API - * takes charcode only. To determine the passed value is for cmap_index - * or charcode, the possible cmap_index is restricted not to exceed - * the minimum possible charcode by a rogue client. It is also very - * unlikely that a rogue client is interested in Unicode values 0 to 15. - * - * NOTE: The original threshold was 4 deduced from popular number of - * cmap subtables in UCS-4 TrueType fonts, but now it is not - * irregular for OpenType fonts to have more than 4 subtables, - * because variation selector subtables are available for Apple - * and Microsoft platforms. - */ -/* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. - */ -#define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#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> -/* note: this cannot be a typedef since */ -#define ft_jmp_buf jmp_buf -/* jmp_buf is defined as a macro */ -/* on certain platforms */ -#define ft_longjmp longjmp -/* same thing here */ -#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) -/* 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> -/* END */ -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> -/* defined since 10.2 */ -#ifdef ECANCELED -#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; -/* */ -#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 -/* Visual C++ (and Intel C++) */ -#elif defined( _MSC_VER ) && _MSC_VER >= 900 -/* this compiler provides the __int64 type */ -#define FT_LONG64 -#define FT_INT64 __int64 -/* Borland C++ */ -#elif defined( __BORLANDC__ ) -/* 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 -/* Watcom C++ */ -#elif defined( __WATCOMC__ ) -/* Watcom doesn't provide 64-bit data types */ -/* Metrowerks CodeWarrior */ -#elif defined( __MWERKS__ ) -#define FT_LONG64 -#define FT_INT64 long long int -#elif defined( __GNUC__ ) -/* GCC provides the `long long' type */ -#define FT_LONG64 -#define FT_INT64 long long int -/* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ -#endif -/*************************************************************************/ -/* */ -/* 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 -/* __STDC__ */ -#endif -/* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ -#endif -#define FT_BEGIN_STMNT do { -#define FT_END_STMNT } while ( 0 ) -#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT -/* Provide assembler fragments for performance-critical functions. */ -/* These must be defined `static __inline__' with GCC. */ -/* RVCT */ -#if 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 - { -/* (lo=t2,hi=t) = a*b */ - smull t2, t, b, a -/* a = (hi >> 31) */ - mov a, t, asr #31 -/* a += 0x8000 */ - add a, a, #0x8000 -/* t2 += a */ - adds t2, t2, a -/* t += carry */ - adc t, t, #0 -/* a = t2 >> 16 */ - mov a, t2, lsr #16 -/* a |= t << 16 */ - orr a, a, t, lsl #16 - } - return a; - } -/* __CC_ARM || __ARMCC__ */ -#endif -#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__ ( -/* (lo=%1,hi=%2) = a*b */ - "smull %1, %2, %4, %3\n\t" -/* %0 = (hi >> 31) */ - "mov %0, %2, asr #31\n\t" -/* %0 += 0x8000 */ - "add %0, %0, #0x8000\n\t" -/* %1 += %0 */ - "adds %1, %1, %0\n\t" -/* %2 += carry */ - "adc %2, %2, #0\n\t" -/* %0 = %1 >> 16 */ - "mov %0, %1, lsr #16\n\t" -/* %0 |= %2 << 16 */ - "orr %0, %0, %2, lsl #16\n\t" - : "=r"(a), "=&r"(t2), "=&r"(t) - : "r"(a), "r"(b) - : "cc" ); - return a; - } -/* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ -#endif -#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; - } -/* i386 */ -#endif -/* __GNUC__ */ -#endif -/* Visual C++ */ -#ifdef _MSC_VER -#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; - } -/* _M_IX86 */ -#endif -/* _MSC_VER */ -#endif -#ifdef FT_MULFIX_ASSEMBLER -#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER -#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 -/* FT_MAKE_OPTION_SINGLE_OBJECT */ -#endif -#ifndef FT_BASE -#ifdef __cplusplus -#define FT_BASE( x ) extern "C" x -#else -#define FT_BASE( x ) extern x -#endif -/* !FT_BASE */ -#endif -#ifndef FT_BASE_DEF -#ifdef __cplusplus -#define FT_BASE_DEF( x ) x -#else -#define FT_BASE_DEF( x ) x -#endif -/* !FT_BASE_DEF */ -#endif -#ifndef FT_EXPORT -#ifdef __cplusplus -#define FT_EXPORT( x ) extern "C" x -#else -#define FT_EXPORT( x ) extern x -#endif -/* !FT_EXPORT */ -#endif -#ifndef FT_EXPORT_DEF -#ifdef __cplusplus -#define FT_EXPORT_DEF( x ) extern "C" x -#else -#define FT_EXPORT_DEF( x ) extern x -#endif -/* !FT_EXPORT_DEF */ -#endif -#ifndef FT_EXPORT_VAR -#ifdef __cplusplus -#define FT_EXPORT_VAR( x ) extern "C" x -#else -#define FT_EXPORT_VAR( x ) extern x -#endif -/* !FT_EXPORT_VAR */ -#endif -/* 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 -/* FT_CALLBACK_DEF */ -#endif -#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 -/* nothing */ -#define FT_CALLBACK_TABLE_DEF -#endif -/* FT_CALLBACK_TABLE */ -#endif -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* ftdebug.h */ -/* */ -/* Debugging and logging component (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTDEBUG_H__ -/***************************************************************************/ -/* */ -/* freetype.h */ -/* */ -/* FreeType high-level API and common types (specification only). */ -/* */ -/* Copyright 1996-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 __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 -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/***************************************************************************/ -/* */ -/* ftmoderr.h */ -/* */ -/* FreeType module error offsets (specification). */ -/* */ -/* Copyright 2001, 2002, 2003, 2004, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* This file is used to define the FreeType module error offsets. */ -/* */ -/* The lower byte gives the error code, the higher byte gives the */ -/* module. The base module has error offset 0. For example, the error */ -/* `FT_Err_Invalid_File_Format' has value 0x003, the error */ -/* `TT_Err_Invalid_File_Format' has value 0x1103, the error */ -/* `T1_Err_Invalid_File_Format' has value 0x1203, etc. */ -/* */ -/* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h */ -/* to make the higher byte always zero (disabling the module error */ -/* mechanism). */ -/* */ -/* 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 */ -/* } */ -/* */ -/* To use such a table, all errors must be ANDed with 0xFF00 to remove */ -/* the error code. */ -/* */ -/*************************************************************************/ -#define __FTMODERR_H__ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#ifndef FT_MODERRDEF -#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, -#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 -/* !FT_MODERRDEF */ -#endif -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -#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 -/* END */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/***************************************************************************/ -/* */ -/* fttypes.h */ -/* */ -/* FreeType simple types definitions (specification only). */ -/* */ -/* Copyright 1996-2002, 2004, 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. */ -/* */ -/***************************************************************************/ -#define __FTTYPES_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTSYSTEM_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 -/* END */ -/***************************************************************************/ -/* */ -/* ftimage.h */ -/* */ -/* FreeType glyph image formats and default raster interface */ -/* (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* Note: A `raster' is simply a scan-line converter, used to render */ -/* FT_Outlines into FT_Bitmaps. */ -/* */ -/*************************************************************************/ -#define __FTIMAGE_H__ -/* _STANDALONE_ is from ftgrays.c */ -#ifndef _STANDALONE_ -#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 float 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. */ -/* */ - 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, -/* do not remove */ - FT_PIXEL_MODE_MAX - } 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, -/* do not remove */ - ft_palette_mode_max - } 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_ - { -/* number of contours in glyph */ - short n_contours; -/* number of points in the glyph */ - short n_points; -/* the outline's points */ - FT_Vector* points; -/* the points flags */ - char* tags; -/* the contour end points */ - short* contours; -/* outline masks */ - int flags; - } 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 -/* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_X 8 -/* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_Y 16 -#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 ) -/* FT_IMAGE_TAG */ -#endif -/*************************************************************************/ -/* */ -/* <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; -/* doesn't work! */ - FT_SpanFunc black_spans; -/* doesn't work! */ - FT_Raster_BitTest_Func bit_test; -/* doesn't work! */ - FT_Raster_BitSet_Func bit_set; - 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 -/* END */ -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ -#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. */ -/* */ -/* distance in FUnits */ - typedef signed short FT_FWord; -/*************************************************************************/ -/* */ -/* <Type> */ -/* FT_UFWord */ -/* */ -/* <Description> */ -/* An unsigned 16-bit integer used to store a distance in original */ -/* font units. */ -/* */ -/* unsigned distance */ - typedef unsigned short FT_UFWord; -/*************************************************************************/ -/* */ -/* <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 float type used for unit vectors. */ -/* */ - typedef signed short FT_F2Dot14; -/*************************************************************************/ -/* */ -/* <Type> */ -/* FT_F26Dot6 */ -/* */ -/* <Description> */ -/* A signed 26.6 fixed float type used for vectorial pixel */ -/* coordinates. */ -/* */ - typedef signed long FT_F26Dot6; -/*************************************************************************/ -/* */ -/* <Type> */ -/* FT_Fixed */ -/* */ -/* <Description> */ -/* This type is used to store 16.16 fixed float 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 float 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 ) -/* return base error code (without module-specific prefix) */ -#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) -/* return module error code */ -#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) -#define FT_BOOL( x ) ( (FT_Bool)( x ) ) -FT_END_HEADER -/* END */ -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). */ -/* */ -/* For multi-threading applications each thread should have its own */ -/* FT_Library object. */ -/* */ -/* <Note> */ -/* Library objects are normally created by @FT_Init_FreeType, and */ -/* destroyed with @FT_Done_FreeType. */ -/* */ - 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) ) -/* FT_ENC_TAG */ -#endif -/*************************************************************************/ -/* */ -/* <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 :: The height is the vertical distance */ -/* between two consecutive baselines, */ -/* expressed in font units. It is always */ -/* positive. Only relevant for scalable */ -/* formats. */ -/* */ -/* 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; -/* face-specific auto-hinter data */ - FT_Generic autohint; -/* unused */ - void* extensions; - 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_ - { -/* horizontal pixels per EM */ - FT_UShort x_ppem; -/* vertical pixels per EM */ - FT_UShort y_ppem; -/* scaling values used to convert font */ - FT_Fixed x_scale; -/* units to 26.6 fractional pixels */ - FT_Fixed y_scale; -/* ascender in 26.6 frac. pixels */ - FT_Pos ascender; -/* descender in 26.6 frac. pixels */ - FT_Pos descender; -/* text height in 26.6 frac. pixels */ - FT_Pos height; -/* max horizontal advance, in 26.6 pixels */ - FT_Pos max_advance; - } 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_ - { -/* parent face object */ - FT_Face face; -/* generic pointer for client uses */ - FT_Generic generic; -/* size metrics */ - FT_Size_Metrics 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; -/* retained for binary compatibility */ - FT_UInt reserved; - 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. */ -/* */ - 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 -/* deprecated */ -#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 -/*************************************************************************/ -/* */ -/* <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. */ -/* */ - 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. - * - * @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 ) -/* */ -/* 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 float 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 float 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 4 -#define FREETYPE_PATCH 11 -/*************************************************************************/ -/* */ -/* <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 -/* END */ -FT_BEGIN_HEADER -/* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ -/* is already defined; this simplifies the following #ifdefs */ -/* */ -/*************************************************************************/ -/* */ -/* Define the trace enums as well as the trace levels array when they */ -/* are needed. */ -/* */ -/*************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/* nothing */ -#define FT_TRACE( level, varformat ) do { } while ( 0 ) -/*************************************************************************/ -/* */ -/* <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. */ -/* */ -/*************************************************************************/ -/* nothing */ -#define FT_ERROR( varformat ) do { } while ( 0 ) -/*************************************************************************/ -/* */ -/* Define the FT_ASSERT macro. */ -/* */ -/*************************************************************************/ -#define FT_ASSERT( condition ) do { } while ( 0 ) -/*************************************************************************/ -/* */ -/* Define `FT_Message' and `FT_Panic' when needed. */ -/* */ -/*************************************************************************/ - FT_BASE( void ) - ft_debug_init( void ); -/* Visual C++ (and Intel C++) */ -#if defined( _MSC_VER ) -/* We disable the warning `conditional expression is constant' here */ -/* in order to compile cleanly with the maximum level of warnings. */ -#pragma warning( disable : 4127 ) -/* _MSC_VER */ -#endif -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* ftstream.h */ -/* */ -/* Stream handling (specification). */ -/* */ -/* Copyright 1996-2002, 2004-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. */ -/* */ -/***************************************************************************/ -#define __FTSTREAM_H__ -/***************************************************************************/ -/* */ -/* ftobjs.h */ -/* */ -/* The FreeType private base classes (specification). */ -/* */ -/* Copyright 1996-2006, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* This file contains the definition of all internal FreeType classes. */ -/* */ -/*************************************************************************/ -#define __FTOBJS_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTRENDER_H__ -/***************************************************************************/ -/* */ -/* ftmodapi.h */ -/* */ -/* FreeType modules public interface (specification). */ -/* */ -/* Copyright 1996-2003, 2006, 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. */ -/* */ -/***************************************************************************/ -#define __FTMODAPI_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 */ -/* this module is a font driver */ -#define FT_MODULE_FONT_DRIVER 1 -/* this module is a renderer */ -#define FT_MODULE_RENDERER 2 -/* this module is a glyph hinter */ -#define FT_MODULE_HINTER 4 -/* this module is a styler */ -#define FT_MODULE_STYLER 8 -/* the driver supports */ -#define FT_MODULE_DRIVER_SCALABLE 0x100 -/* scalable fonts */ -/* the driver does not */ -#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 -/* support vector outlines */ -/* the driver provides its */ -#define FT_MODULE_DRIVER_HAS_HINTER 0x400 -/* 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 ); - * } - * - * It is not possible to set properties of the FreeType Cache - * sub-system with FT_Property_Set; use @FTC_Property_Set instead. - * - * @since: - * 2.4.11 - * - */ - 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_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __FTGLYPH_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 float 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 -/* END */ -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __FTSIZES_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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__ -#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. - */ -/**************************************************************************** - * - * @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, -/* do not remove */ - FT_LCD_FILTER_MAX - } 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 -/* __FT_LCD_FILTER_H__ */ -#endif -/* END */ -/***************************************************************************/ -/* */ -/* ftmemory.h */ -/* */ -/* The FreeType memory management macros (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 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. */ -/* */ -/***************************************************************************/ -#define __FTMEMORY_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 -#define FT_DEBUG_INNER( exp ) (exp) -#define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) -/* - * 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, (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, \ - (cursz), (newsz), \ - (ptr), &error ) ) -#define FT_MEM_QALLOC( ptr, size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (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, \ - (cursz), (newsz), \ - (ptr), &error ) ) -#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ - (cursz), (newsz), \ - (ptr), &error ) ) -#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \ - 0, (count), \ - NULL, &error ) ) -#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz), \ - (oldcnt), (newcnt), \ - (ptr), &error ) ) -#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \ - 0, (count), \ - NULL, &error ) ) -#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz), \ - (oldcnt), (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, (count), \ - NULL, &error ) ) -#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ - (cursz), (newsz), \ - (ptr), &error ) ) -#define FT_MEM_QNEW_ARRAY( ptr, count ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ - 0, (count), \ - NULL, &error ) ) -#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ - FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ - (cursz), (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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTGLOADR_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 ; -/* moved to freetype.h in version 2.2 */ -#if 0 -#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_ - { -/* outline */ - FT_Outline outline; -/* extra points table */ - FT_Vector* extra_points; -/* second extra points table */ - FT_Vector* extra_points2; -/* number of subglyphs */ - FT_UInt num_subglyphs; -/* subglyphs */ - FT_SubGlyph 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; -/* for possible future extension? */ - void* other; - } 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 -/* END */ -/***************************************************************************/ -/* */ -/* ftdriver.h */ -/* */ -/* FreeType font driver interface (specification). */ -/* */ -/* Copyright 1996-2003, 2006, 2008, 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. */ -/* */ -/***************************************************************************/ -#define __FTDRIVER_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; -/* - * The following functions are used as stubs for `set_char_sizes' and - * `set_pixel_sizes'; the code uses `request_size' and `select_size' - * functions instead. - * - * Implementation is in `src/base/ftobjs.c'. - */ -/*************************************************************************/ -/* */ -/* <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). */ -/* */ -/* empty */ -#define FT_DEFINE_DRIVERS_OLD_INTERNALS( a_, b_ ) -#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_, \ - old_set_char_sizes_, \ - old_set_pixel_sizes_, \ - 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_, \ - \ - FT_DEFINE_DRIVERS_OLD_INTERNALS( old_set_char_sizes_, \ - old_set_pixel_sizes_ ) \ - \ - load_glyph_, \ - \ - get_kerning_, \ - attach_file_, \ - get_advances_, \ - \ - request_size_, \ - select_size_ \ - }; -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#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. */ -/* */ -/*************************************************************************/ -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; -#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_ \ - }; -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* ftserv.h */ -/* */ -/* The FreeType services (specification only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). */ -/* */ -/*************************************************************************/ -#define __FTSERV_H__ -FT_BEGIN_HEADER -/* Visual C++ (and Intel C++) */ -#if defined( _MSC_VER ) -/* we disable the warning `conditional expression is constant' here */ -/* in order to compile cleanly with the maximum level of warnings */ -#pragma warning( disable : 4127 ) -/* _MSC_VER */ -#endif -/* - * @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 -/* !C++ */ -#else -#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 -/* !C++ */ -#endif -/* - * @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 -/* !C++ */ -#else -#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 -/* !C++ */ -#endif -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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_ - { -/* service name */ - const char* serv_id; -/* service pointer/data */ - const void* serv_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 */ -/* */ -/* <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). */ -/* */ -#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 } \ - }; -/* - * 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. - */ -/* magic number */ -#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~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 -/* !C++ */ -#else -#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 -/* !C++ */ -#endif -/* - * 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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __FTPIC_H__ -FT_BEGIN_HEADER -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTINCREM_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; -/* since 2.3.12 */ - FT_Long advance_v; - } 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 -/* END */ -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; -#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_ \ - }; -/* 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; - FT_Incremental_InterfaceRec* incremental_interface; - FT_Bool ignore_unpatented_hinter; - FT_UInt 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_ - { -/* library's memory manager */ - FT_Memory memory; - FT_Int version_major; - FT_Int version_minor; - FT_Int version_patch; - FT_UInt num_modules; -/* module objects */ - FT_Module modules[FT_MAX_MODULES]; -/* list of renderers */ - FT_ListRec renderers; -/* current outline renderer */ - FT_Renderer cur_renderer; - FT_Module auto_hinter; -/* scan-line conversion */ - FT_Byte* raster_pool; -/* render pool */ -/* size of render pool in bytes */ - FT_ULong raster_pool_size; - FT_DebugHook_Func debug_hooks[4]; - FT_LcdFilter lcd_filter; -/* number of extra pixels */ - FT_Int lcd_extra; -/* filter weights, if any */ - FT_Byte lcd_weights[7]; -/* filtering callback */ - FT_Bitmap_LcdFilterFunc lcd_filter_func; - FT_UInt 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 ); -/* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ -#endif -/* 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). */ -/* */ -#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_ \ - }; -/*************************************************************************/ -/* */ -/* <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). */ -/* */ -#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_ \ - }; -/* 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). */ -/* */ -#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_ \ - }; -/*************************************************************************/ -/* */ -/* <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). */ -/* */ -#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_ \ - }; -/* PIC support macros for ftmodapi.h **/ -/*************************************************************************/ -/* */ -/* <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. */ -/* */ -#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_, \ - }; -FT_END_HEADER -/* END */ -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 -/* start a new frame */ -#define FT_FRAME_OP_START 1 -/* read 1-byte value */ -#define FT_FRAME_OP_BYTE 2 -/* read 2-byte value */ -#define FT_FRAME_OP_SHORT 3 -/* read 4-byte value */ -#define FT_FRAME_OP_LONG 4 -/* read 3-byte value */ -#define FT_FRAME_OP_OFF3 5 -/* read a bytes sequence */ -#define FT_FRAME_OP_BYTES 6 - 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_INT8_( p, i ) ( ((const FT_Char*)(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_I16( p, i, s ) ( FT_INT16( FT_BYTE_( p, i ) ) << (s) ) -#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) -#define FT_BYTE_I32( p, i, s ) ( FT_INT32( FT_BYTE_( p, i ) ) << (s) ) -#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) -#define FT_INT8_I16( p, i, s ) ( FT_INT16( FT_INT8_( p, i ) ) << (s) ) -#define FT_INT8_U16( p, i, s ) ( FT_UINT16( FT_INT8_( p, i ) ) << (s) ) -#define FT_INT8_I32( p, i, s ) ( FT_INT32( FT_INT8_( p, i ) ) << (s) ) -#define FT_INT8_U32( p, i, s ) ( FT_UINT32( FT_INT8_( p, i ) ) << (s) ) -#define FT_PEEK_SHORT( p ) FT_INT16( FT_INT8_I16( p, 0, 8) | \ - FT_BYTE_I16( 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_INT8_I32( p, 0, 24 ) | \ - FT_BYTE_I32( p, 1, 16 ) | \ - FT_BYTE_I32( p, 2, 8 ) | \ - FT_BYTE_I32( 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_INT8_I32( p, 0, 16 ) | \ - FT_BYTE_I32( p, 1, 8 ) | \ - FT_BYTE_I32( 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_INT8_I16( p, 1, 8 ) | \ - FT_BYTE_I16( 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_INT8_I32( p, 3, 24 ) | \ - FT_BYTE_I32( p, 2, 16 ) | \ - FT_BYTE_I32( p, 1, 8 ) | \ - FT_BYTE_I32( 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_INT8_I32( p, 2, 16 ) | \ - FT_BYTE_I32( p, 1, 8 ) | \ - FT_BYTE_I32( 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 ); -/* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ -#endif -/* 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, position ) ) -#define FT_STREAM_SKIP( distance ) \ - FT_SET_ERROR( FT_Stream_Skip( stream, distance ) ) -#define FT_STREAM_READ( buffer, count ) \ - FT_SET_ERROR( FT_Stream_Read( stream, \ - (FT_Byte*)buffer, \ - count ) ) -#define FT_STREAM_READ_AT( position, buffer, count ) \ - FT_SET_ERROR( FT_Stream_ReadAt( stream, \ - position, \ - (FT_Byte*)buffer, \ - 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, 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, size, \ - (FT_Byte**)&(bytes) ) ) ) -#define FT_FRAME_RELEASE( bytes ) \ - FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream, \ - (FT_Byte**)&(bytes) ) ) -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/*************************************************************************/ -/* */ -/* 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 */ -/* */ -/*************************************************************************/ -/*************************************************************************/ -/* */ -/* 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_Err_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_Err_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_Err_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; - } -/* 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; - } - return memory; - } -/* documentation is in ftobjs.h */ - FT_BASE_DEF( void ) - FT_Done_Memory( FT_Memory memory ) - { - ft_sfree( memory ); - } -/* END */ -/***************************************************************************/ -/* */ -/* ftinit.c */ -/* */ -/* FreeType initialization layer (body). */ -/* */ -/* Copyright 1996-2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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'. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __BASEPIC_H__ -FT_BEGIN_HEADER -#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 -#define FT_RACCESS_GUESS_TABLE_GET ft_raccess_guess_table -/* */ -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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 -#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 -/* - * 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 */ -#undef FT_USE_MODULE -#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x), - static - const FT_Module_Class* const ft_default_modules[] = - { -/* - * 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 */ - 0 - }; -/* 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 */ -/* 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_Err_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 */ -/***************************************************************************/ -/* */ -/* ftdebug.c */ -/* */ -/* Debugging and logging component (body). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ - 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; - } -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define FT_MAKE_OPTION_SINGLE_OBJECT -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/* END */ -/***************************************************************************/ -/* */ -/* ftadvanc.c */ -/* */ -/* Quick computation of advance widths (body). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* ftadvanc.h */ -/* */ -/* Quick computation of advance widths (specification only). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -#define __FTADVANC_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. By default, the unhinted advance is returned in font */ -/* units. */ -/* */ -/* <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, in either font units or 16.16 */ -/* format. */ -/* */ -/* 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. By default, the unhinted advances are returned in font */ -/* units. */ -/* */ -/* <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 advances, in either font units or 16.16 format. */ -/* This array must contain at least `count' elements. */ -/* */ -/* 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 -/* END */ - 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_Err_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_Err_Invalid_Face_Handle; - if ( gindex >= (FT_UInt)face->num_glyphs ) - return FT_Err_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 ( error != FT_ERROR_BASE( FT_Err_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_Err_Invalid_Face_Handle; - num = (FT_UInt)face->num_glyphs; - end = start + count; - if ( start >= num || end < start || end > num ) - return FT_Err_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 ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) - return error; - } - error = FT_Err_Ok; - if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) - return FT_Err_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 */ -/***************************************************************************/ -/* */ -/* ftcalc.c */ -/* */ -/* Arithmetic computations (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* ftcalc.h */ -/* */ -/* Arithmetic computations (specification). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -#define __FTCALC_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 ); -#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 -/* END */ -#ifdef FT_MULFIX_INLINED -#undef FT_MulFix -#endif -/* we need to define a 64-bits data type here */ -#ifdef FT_LONG64 - typedef FT_INT64 FT_Int64; -#else - typedef struct FT_Int64_ - { - FT_UInt32 lo; - FT_UInt32 hi; - } FT_Int64; -/* FT_LONG64 */ -#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_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 ); - } -#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; -/* FT_MULFIX_ASSEMBLER */ -#endif - } -/* 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_Int64)a << 16 ) + ( b >> 1 ) ) / b ); - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); - } -/* !FT_LONG64 */ -#else - 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; -/* 0 */ -#else - 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 ); -/* 0 */ -#endif - } -/* 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)( ( 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; -/* we know y is to be treated as unsigned here */ - if ( r >= (FT_UInt32)y ) - 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 ); - } -/* 0 */ -#else - 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 ); - } -/* 0 */ -#endif -/* 0 */ -#endif -/* FT_LONG64 */ -#endif -/* 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_Err_Invalid_Argument; -/* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - if ( !delta ) -/* matrix can't be inverted */ - return FT_Err_Invalid_Argument; - 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 ) - { -/* avoid overflow on 16-bit system */ - FT_Long 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; - } -/* general case */ - else - { -#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 */ -/***************************************************************************/ -/* */ -/* ftdbgmem.c */ -/* */ -/* Memory debugger (body). */ -/* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* ANSI C doesn't like empty source files */ - typedef int _debug_mem_dummy; -/* END */ -/***************************************************************************/ -/* */ -/* ftgloadr.c */ -/* */ -/* The FreeType glyph loader (body). */ -/* */ -/* Copyright 2002, 2003, 2004, 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. */ -/* */ -/***************************************************************************/ -#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_Err_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_Err_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: - 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 */ -/***************************************************************************/ -/* */ -/* ftobjs.c */ -/* */ -/* The FreeType private base classes (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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'. */ -/* */ -/*************************************************************************/ -#define __FTLIST_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTOUTLN_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. */ -/* */ -/* numContours :: The maximum number of contours within the outline. */ -/* */ -/* <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 -/* END */ -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ -/***************************************************************************/ -/* */ -/* ftvalid.h */ -/* */ -/* FreeType validation support (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. */ -/* */ -/***************************************************************************/ -#define __FTVALID_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; -/* validator structure */ - typedef struct FT_ValidatorRec_ - { -/* address of table in memory */ - const FT_Byte* base; -/* `base' + sizeof(table) in memory */ - const FT_Byte* limit; -/* validation level */ - FT_ValidationLevel level; -/* error returned. 0 means success */ - FT_Error error; -/* used for exception handling */ - ft_jmp_buf jump_buffer; - } FT_ValidatorRec; -#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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/***************************************************************************/ -#define __FTRFORK_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; - 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, -/* -1 */ - FT_RFork_Rule_uknown, - 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; -/* 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 }; -/*************************************************************************/ -/* */ -/* <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 -/* END */ -/* for SFNT_Load_Table_Func */ -/***************************************************************************/ -/* */ -/* sfnt.h */ -/* */ -/* High-level `sfnt' driver interface (specification). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -#define __SFNT_H__ -/***************************************************************************/ -/* */ -/* tttypes.h */ -/* */ -/* Basic SFNT/TrueType type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2002, 2004-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. */ -/* */ -/***************************************************************************/ -#define __TTTYPES_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTTABLES_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; -/* advance width maximum */ - FT_UShort advance_Width_Max; -/* minimum left-sb */ - FT_Short min_Left_Side_Bearing; -/* minimum right-sb */ - FT_Short min_Right_Side_Bearing; -/* xmax extents */ - FT_Short xMax_Extent; - 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; -/* advance height maximum */ - FT_UShort advance_Height_Max; -/* minimum left-sb or top-sb */ - FT_Short min_Top_Side_Bearing; -/* minimum right-sb or bottom-sb */ - FT_Short min_Bottom_Side_Bearing; -/* xmax or ymax extents */ - FT_Short yMax_Extent; - 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_ - { -/* 0x0001 - more or 0xFFFF */ - FT_UShort version; - 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]; -/* Bits 0-31 */ - FT_ULong ulUnicodeRange1; -/* Bits 32-63 */ - FT_ULong ulUnicodeRange2; -/* Bits 64-95 */ - FT_ULong ulUnicodeRange3; -/* Bits 96-127 */ - FT_ULong ulUnicodeRange4; - 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: */ -/* Bits 0-31 */ - FT_ULong ulCodePageRange1; -/* Bits 32-63 */ - FT_ULong ulCodePageRange2; -/* 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_ - { -/* TT_Header */ - ft_sfnt_head = 0, -/* TT_MaxProfile */ - ft_sfnt_maxp = 1, -/* TT_OS2 */ - ft_sfnt_os2 = 2, -/* TT_HoriHeader */ - ft_sfnt_hhea = 3, -/* TT_VertHeader */ - ft_sfnt_vhea = 4, -/* TT_Postscript */ - ft_sfnt_post = 5, -/* TT_PCLT */ - ft_sfnt_pclt = 6, -/* internal end mark */ - sfnt_max - } 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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTMM_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1TABLES_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; -/* including std width */ - FT_Short snap_widths [13]; -/* including std height */ - FT_Short snap_heights[13]; - 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 */ -/* FT_Byte */ - PS_DICT_FONT_TYPE, -/* FT_Fixed */ - PS_DICT_FONT_MATRIX, -/* FT_Fixed */ - PS_DICT_FONT_BBOX, -/* FT_Byte */ - PS_DICT_PAINT_TYPE, -/* FT_String* */ - PS_DICT_FONT_NAME, -/* FT_Int */ - PS_DICT_UNIQUE_ID, -/* FT_Int */ - PS_DICT_NUM_CHAR_STRINGS, -/* FT_String* */ - PS_DICT_CHAR_STRING_KEY, -/* FT_String* */ - PS_DICT_CHAR_STRING, -/* T1_EncodingType */ - PS_DICT_ENCODING_TYPE, -/* FT_String* */ - PS_DICT_ENCODING_ENTRY, -/* conventionally in the font Private dictionary */ -/* FT_Int */ - PS_DICT_NUM_SUBRS, -/* FT_String* */ - PS_DICT_SUBR, -/* FT_UShort */ - PS_DICT_STD_HW, -/* FT_UShort */ - PS_DICT_STD_VW, -/* FT_Byte */ - PS_DICT_NUM_BLUE_VALUES, -/* FT_Short */ - PS_DICT_BLUE_VALUE, -/* FT_Int */ - PS_DICT_BLUE_FUZZ, -/* FT_Byte */ - PS_DICT_NUM_OTHER_BLUES, -/* FT_Short */ - PS_DICT_OTHER_BLUE, -/* FT_Byte */ - PS_DICT_NUM_FAMILY_BLUES, -/* FT_Short */ - PS_DICT_FAMILY_BLUE, -/* FT_Byte */ - PS_DICT_NUM_FAMILY_OTHER_BLUES, -/* FT_Short */ - PS_DICT_FAMILY_OTHER_BLUE, -/* FT_Fixed */ - PS_DICT_BLUE_SCALE, -/* FT_Int */ - PS_DICT_BLUE_SHIFT, -/* FT_Byte */ - PS_DICT_NUM_STEM_SNAP_H, -/* FT_Short */ - PS_DICT_STEM_SNAP_H, -/* FT_Byte */ - PS_DICT_NUM_STEM_SNAP_V, -/* FT_Short */ - PS_DICT_STEM_SNAP_V, -/* FT_Bool */ - PS_DICT_FORCE_BOLD, -/* FT_Bool */ - PS_DICT_RND_STEM_UP, -/* FT_Short */ - PS_DICT_MIN_FEATURE, -/* FT_Int */ - PS_DICT_LEN_IV, -/* FT_Long */ - PS_DICT_PASSWORD, -/* FT_Long */ - PS_DICT_LANGUAGE_GROUP, -/* conventionally in the font FontInfo dictionary */ -/* FT_String* */ - 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_Bool */ - PS_DICT_IS_FIXED_PITCH, -/* FT_Short */ - PS_DICT_UNDERLINE_POSITION, -/* FT_UShort */ - PS_DICT_UNDERLINE_THICKNESS, -/* FT_UShort */ - PS_DICT_FS_TYPE, -/* FT_Long */ - PS_DICT_ITALIC_ANGLE, - 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 -/* END */ -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 -/* END */ -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; -/* not in file */ - FT_ULong offset; - } 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_ - { -/* table type */ - FT_ULong Tag; -/* table checksum */ - FT_ULong CheckSum; -/* table file offset */ - FT_ULong Offset; -/* table length */ - FT_ULong 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 ***/ -/*** ***/ -/*** ***/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ - typedef struct GX_BlendRec_ *GX_Blend; -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/*** ***/ -/*** ***/ -/*** 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. - * - */ - 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; -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/*** ***/ -/*** ***/ -/*** 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; -/* TrueType header table */ - TT_Header header; -/* TrueType horizontal header */ - TT_HoriHeader horizontal; - TT_MaxProfile max_profile; - FT_Bool vertical_info; -/* TT Vertical header, if present */ - TT_VertHeader vertical; -/* number of name records */ - FT_UShort num_names; -/* name table */ - TT_NameTableRec name_table; -/* TrueType OS/2 table */ - TT_OS2 os2; -/* TrueType Postscript table */ - TT_Postscript postscript; -/* extracted `cmap' table */ - FT_Byte* 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 */ -/* */ -/***********************************************************************/ -/* horizontal device metrics */ -/* grid-fitting and scaling table */ -/* the `gasp' table */ - TT_GaspRec gasp; -/* 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 glyph locations */ -/* 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; -/***********************************************************************/ -/* */ -/* Other tables or fields. This is used by derivative formats like */ -/* OpenType. */ -/* */ -/***********************************************************************/ - FT_Generic extra; - const char* postscript_name; -/* since version 2.1.8, but was originally placed after */ -/* `glyph_locations_stub' */ - FT_ULong glyf_len; -/* since version 2.1.8, but was originally placed before `extra' */ - FT_Bool doblend; - GX_Blend blend; -/* since version 2.2 */ - FT_Byte* horz_metrics; - FT_ULong horz_metrics_size; - FT_Byte* vert_metrics; - FT_ULong vert_metrics_size; -/* in broken TTF, gid > 0xFFFF */ - FT_ULong num_locations; - 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; - TT_BDFRec bdf; -/* since 2.3.0 */ - FT_ULong horz_metrics_offset; - FT_ULong vert_metrics_offset; - } 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; -/* number of points in zone */ - FT_UShort n_points; -/* number of contours */ - FT_Short n_contours; -/* original point coordinates */ - FT_Vector* org; -/* current point coordinates */ - FT_Vector* cur; -/* original (unscaled) point coordinates */ - FT_Vector* orus; -/* current touch flags */ - FT_Byte* tags; -/* contour end points */ - FT_UShort* contours; -/* offset of first (#0) point */ - FT_UShort first_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 -/* END */ -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; -/* optional tables */ -/* 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; -/* empty */ -#define FT_DEFINE_DRIVERS_OLD_INTERNAL( a ) -#define FT_INTERNAL( a ) \ - a, -#define FT_DEFINE_SFNT_INTERFACE( \ - class_, \ - goto_table_, \ - init_face_, \ - load_face_, \ - done_face_, \ - get_interface_, \ - load_any_, \ - load_sfnt_header_, \ - load_directory_, \ - load_head_, \ - load_hhea_, \ - load_cmap_, \ - load_maxp_, \ - load_os2_, \ - load_post_, \ - load_name_, \ - free_name_, \ - load_hdmx_stub_, \ - free_hdmx_stub_, \ - load_kern_, \ - load_gasp_, \ - load_pclt_, \ - load_bhed_, \ - set_sbit_strike_stub_, \ - load_sbits_stub_, \ - find_sbit_image_, \ - load_sbit_metrics_, \ - load_sbit_image_, \ - free_sbits_stub_, \ - get_psname_, \ - free_psnames_, \ - load_charmap_stub_, \ - free_charmap_stub_, \ - get_kerning_, \ - load_font_dir_, \ - load_hmtx_, \ - load_eblc_, \ - free_eblc_, \ - set_sbit_strike_, \ - load_strike_metrics_, \ - get_metrics_ ) \ - static const SFNT_Interface class_ = \ - { \ - FT_INTERNAL( goto_table_ ) \ - FT_INTERNAL( init_face_ ) \ - FT_INTERNAL( load_face_ ) \ - FT_INTERNAL( done_face_ ) \ - FT_INTERNAL( get_interface_ ) \ - FT_INTERNAL( load_any_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( load_sfnt_header_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( load_directory_ ) \ - FT_INTERNAL( load_head_ ) \ - FT_INTERNAL( load_hhea_ ) \ - FT_INTERNAL( load_cmap_ ) \ - FT_INTERNAL( load_maxp_ ) \ - FT_INTERNAL( load_os2_ ) \ - FT_INTERNAL( load_post_ ) \ - FT_INTERNAL( load_name_ ) \ - FT_INTERNAL( free_name_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( load_hdmx_stub_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( free_hdmx_stub_ ) \ - FT_INTERNAL( load_kern_ ) \ - FT_INTERNAL( load_gasp_ ) \ - FT_INTERNAL( load_pclt_ ) \ - FT_INTERNAL( load_bhed_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( set_sbit_strike_stub_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( load_sbits_stub_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( find_sbit_image_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( load_sbit_metrics_ ) \ - FT_INTERNAL( load_sbit_image_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( free_sbits_stub_ ) \ - FT_INTERNAL( get_psname_ ) \ - FT_INTERNAL( free_psnames_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( load_charmap_stub_ ) \ - FT_DEFINE_DRIVERS_OLD_INTERNAL( free_charmap_stub_ ) \ - FT_INTERNAL( get_kerning_ ) \ - FT_INTERNAL( load_font_dir_ ) \ - FT_INTERNAL( load_hmtx_ ) \ - FT_INTERNAL( load_eblc_ ) \ - FT_INTERNAL( free_eblc_ ) \ - FT_INTERNAL( set_sbit_strike_ ) \ - FT_INTERNAL( load_strike_metrics_ ) \ - FT_INTERNAL( get_metrics_ ) \ - }; -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* tttags.h */ -/* */ -/* Tags for TrueType and OpenType tables (specification only). */ -/* */ -/* Copyright 1996-2001, 2004, 2005, 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. */ -/* */ -/***************************************************************************/ -#ifndef __TTAGS_H__ -#define __TTAGS_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_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 -/* __TTAGS_H__ */ -#endif -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTNAMEID_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 -/* deprecated */ -#define TT_PLATFORM_ISO 2 -#define TT_PLATFORM_MICROSOFT 3 -#define TT_PLATFORM_CUSTOM 4 -/* artificial */ -#define TT_PLATFORM_ADOBE 7 -/*********************************************************************** - * - * @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. - */ -/* Unicode 1.0 */ -#define TT_APPLE_ID_DEFAULT 0 -/* specify Hangul at U+34xx */ -#define TT_APPLE_ID_UNICODE_1_1 1 -/* deprecated */ -#define TT_APPLE_ID_ISO_10646 2 -/* or later */ -#define TT_APPLE_ID_UNICODE_2_0 3 -/* 2.0 or later, full repertoire */ -#define TT_APPLE_ID_UNICODE_32 4 -/* variation selector data */ -#define TT_APPLE_ID_VARIANT_SELECTOR 5 -/*********************************************************************** - * - * @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 -/* these seem to be errors that have been dropped */ -#if 0 -#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 -/* this looks like the correct value */ -#if 1 -#define TT_MS_LANGID_CHINESE_MACAU 0x1404 -/* but beware, Microsoft may change its mind... - the most recent Word reference has the following: */ -#else -#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG -#endif -/* used only with .NET `cultures'; commented out */ -#if 0 -#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 -/* this used to be this value, but it looks like we were wrong */ -#if 0 -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a -/* current sources say */ -#else -#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 -/* this seems to be a previous inversion */ -#if 0 -#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 -/* Cyrillic*/#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN 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 -/* Cyrillic */#define TT_MS_LANGID_MONGOLIAN_MONGOLIA 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 -/* Bengali */#define TT_MS_LANGID_MANIPURI_INDIA 0x0458 -/* Arabic */#define TT_MS_LANGID_SINDHI_INDIA 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 -/* Arabic */#define TT_MS_LANGID_TAMAZIGHT_MOROCCO 0x045f -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f -/* Missing a LCID for Tifinagh script */ -/* Arabic */#define TT_MS_LANGID_KASHMIRI_PAKISTAN 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 -/* not deemed useful for fonts */ -#if 0 -#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 */ -/* U+0020-U+007E */ -#define TT_UCR_BASIC_LATIN (1L << 0) -/* Bit 1 C1 Controls and Latin-1 Supplement */ -/* U+0080-U+00FF */ -#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) -/* Bit 2 Latin Extended-A */ -/* U+0100-U+017F */ -#define TT_UCR_LATIN_EXTENDED_A (1L << 2) -/* Bit 3 Latin Extended-B */ -/* U+0180-U+024F */ -#define TT_UCR_LATIN_EXTENDED_B (1L << 3) -/* Bit 4 IPA Extensions */ -/* Phonetic Extensions */ -/* Phonetic Extensions Supplement */ -/* U+0250-U+02AF */ -#define TT_UCR_IPA_EXTENSIONS (1L << 4) -/* U+1D00-U+1D7F */ -/* U+1D80-U+1DBF */ -/* Bit 5 Spacing Modifier Letters */ -/* Modifier Tone Letters */ -/* U+02B0-U+02FF */ -#define TT_UCR_SPACING_MODIFIER (1L << 5) -/* U+A700-U+A71F */ -/* Bit 6 Combining Diacritical Marks */ -/* Combining Diacritical Marks Supplement */ -/* U+0300-U+036F */ -#define TT_UCR_COMBINING_DIACRITICS (1L << 6) -/* U+1DC0-U+1DFF */ -/* Bit 7 Greek and Coptic */ -/* U+0370-U+03FF */ -#define TT_UCR_GREEK (1L << 7) -/* Bit 8 Coptic */ -/* U+2C80-U+2CFF */ -#define TT_UCR_COPTIC (1L << 8) -/* Bit 9 Cyrillic */ -/* Cyrillic Supplement */ -/* Cyrillic Extended-A */ -/* Cyrillic Extended-B */ -/* U+0400-U+04FF */ -#define TT_UCR_CYRILLIC (1L << 9) -/* U+0500-U+052F */ -/* U+2DE0-U+2DFF */ -/* U+A640-U+A69F */ -/* Bit 10 Armenian */ -/* U+0530-U+058F */ -#define TT_UCR_ARMENIAN (1L << 10) -/* Bit 11 Hebrew */ -/* U+0590-U+05FF */ -#define TT_UCR_HEBREW (1L << 11) -/* Bit 12 Vai */ -/* U+A500-U+A63F */ -#define TT_UCR_VAI (1L << 12) -/* Bit 13 Arabic */ -/* Arabic Supplement */ -/* U+0600-U+06FF */ -#define TT_UCR_ARABIC (1L << 13) -/* U+0750-U+077F */ -/* Bit 14 NKo */ -/* U+07C0-U+07FF */ -#define TT_UCR_NKO (1L << 14) -/* Bit 15 Devanagari */ -/* U+0900-U+097F */ -#define TT_UCR_DEVANAGARI (1L << 15) -/* Bit 16 Bengali */ -/* U+0980-U+09FF */ -#define TT_UCR_BENGALI (1L << 16) -/* Bit 17 Gurmukhi */ -/* U+0A00-U+0A7F */ -#define TT_UCR_GURMUKHI (1L << 17) -/* Bit 18 Gujarati */ -/* U+0A80-U+0AFF */ -#define TT_UCR_GUJARATI (1L << 18) -/* Bit 19 Oriya */ -/* U+0B00-U+0B7F */ -#define TT_UCR_ORIYA (1L << 19) -/* Bit 20 Tamil */ -/* U+0B80-U+0BFF */ -#define TT_UCR_TAMIL (1L << 20) -/* Bit 21 Telugu */ -/* U+0C00-U+0C7F */ -#define TT_UCR_TELUGU (1L << 21) -/* Bit 22 Kannada */ -/* U+0C80-U+0CFF */ -#define TT_UCR_KANNADA (1L << 22) -/* Bit 23 Malayalam */ -/* U+0D00-U+0D7F */ -#define TT_UCR_MALAYALAM (1L << 23) -/* Bit 24 Thai */ -/* U+0E00-U+0E7F */ -#define TT_UCR_THAI (1L << 24) -/* Bit 25 Lao */ -/* U+0E80-U+0EFF */ -#define TT_UCR_LAO (1L << 25) -/* Bit 26 Georgian */ -/* Georgian Supplement */ -/* U+10A0-U+10FF */ -#define TT_UCR_GEORGIAN (1L << 26) -/* U+2D00-U+2D2F */ -/* Bit 27 Balinese */ -/* U+1B00-U+1B7F */ -#define TT_UCR_BALINESE (1L << 27) -/* Bit 28 Hangul Jamo */ -/* U+1100-U+11FF */ -#define TT_UCR_HANGUL_JAMO (1L << 28) -/* Bit 29 Latin Extended Additional */ -/* Latin Extended-C */ -/* Latin Extended-D */ -/* U+1E00-U+1EFF */ -#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) -/* U+2C60-U+2C7F */ -/* U+A720-U+A7FF */ -/* Bit 30 Greek Extended */ -/* U+1F00-U+1FFF */ -#define TT_UCR_GREEK_EXTENDED (1L << 30) -/* Bit 31 General Punctuation */ -/* Supplemental Punctuation */ -/* U+2000-U+206F */ -#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) -/* U+2E00-U+2E7F */ -/* Bit 32 Superscripts And Subscripts */ -/* U+2070-U+209F */ -#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) -/* Bit 33 Currency Symbols */ -/* U+20A0-U+20CF */ -#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) -/* Bit 34 Combining Diacritical Marks For Symbols */ -/* U+20D0-U+20FF */ -#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) -/* Bit 35 Letterlike Symbols */ -/* U+2100-U+214F */ -#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) -/* Bit 36 Number Forms */ -/* U+2150-U+218F */ -#define TT_UCR_NUMBER_FORMS (1L << 4) -/* Bit 37 Arrows */ -/* Supplemental Arrows-A */ -/* Supplemental Arrows-B */ -/* Miscellaneous Symbols and Arrows */ -/* U+2190-U+21FF */ -#define TT_UCR_ARROWS (1L << 5) -/* 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 */ -/* U+2200-U+22FF */ -#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) -/* U+2A00-U+2AFF */ -/* U+27C0-U+27EF */ -/* U+2980-U+29FF */ -/* Bit 39 Miscellaneous Technical */ -/* U+2300-U+23FF */ -#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) -/* Bit 40 Control Pictures */ -/* U+2400-U+243F */ -#define TT_UCR_CONTROL_PICTURES (1L << 8) -/* Bit 41 Optical Character Recognition */ -/* U+2440-U+245F */ -#define TT_UCR_OCR (1L << 9) -/* Bit 42 Enclosed Alphanumerics */ -/* U+2460-U+24FF */ -#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) -/* Bit 43 Box Drawing */ -/* U+2500-U+257F */ -#define TT_UCR_BOX_DRAWING (1L << 11) -/* Bit 44 Block Elements */ -/* U+2580-U+259F */ -#define TT_UCR_BLOCK_ELEMENTS (1L << 12) -/* Bit 45 Geometric Shapes */ -/* U+25A0-U+25FF */ -#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) -/* Bit 46 Miscellaneous Symbols */ -/* U+2600-U+26FF */ -#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) -/* Bit 47 Dingbats */ -/* U+2700-U+27BF */ -#define TT_UCR_DINGBATS (1L << 15) -/* Bit 48 CJK Symbols and Punctuation */ -/* U+3000-U+303F */ -#define TT_UCR_CJK_SYMBOLS (1L << 16) -/* Bit 49 Hiragana */ -/* U+3040-U+309F */ -#define TT_UCR_HIRAGANA (1L << 17) -/* Bit 50 Katakana */ -/* Katakana Phonetic Extensions */ -/* U+30A0-U+30FF */ -#define TT_UCR_KATAKANA (1L << 18) -/* U+31F0-U+31FF */ -/* Bit 51 Bopomofo */ -/* Bopomofo Extended */ -/* U+3100-U+312F */ -#define TT_UCR_BOPOMOFO (1L << 19) -/* U+31A0-U+31BF */ -/* Bit 52 Hangul Compatibility Jamo */ -/* U+3130-U+318F */ -#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) -/* Bit 53 Phags-Pa */ -/* U+A840-U+A87F */ -#define TT_UCR_CJK_MISC (1L << 21) -/* deprecated */ -#define TT_UCR_KANBUN TT_UCR_CJK_MISC -#define TT_UCR_PHAGSPA -/* Bit 54 Enclosed CJK Letters and Months */ -/* U+3200-U+32FF */ -#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) -/* Bit 55 CJK Compatibility */ -/* U+3300-U+33FF */ -#define TT_UCR_CJK_COMPATIBILITY (1L << 23) -/* Bit 56 Hangul Syllables */ -/* U+AC00-U+D7A3 */ -#define TT_UCR_HANGUL (1L << 24) -/* 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 */ -/* U+D800-U+DB7F */ -#define TT_UCR_SURROGATES (1L << 25) -/* U+DB80-U+DBFF */ -/* U+DC00-U+DFFF */ -#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES -/* Bit 58 Phoenician */ -/*U+10900-U+1091F*/ -#define TT_UCR_PHOENICIAN (1L << 26) -/* Bit 59 CJK Unified Ideographs */ -/* CJK Radicals Supplement */ -/* Kangxi Radicals */ -/* Ideographic Description Characters */ -/* CJK Unified Ideographs Extension A */ -/* CJK Unified Ideographs Extension B */ -/* Kanbun */ -/* U+4E00-U+9FFF */ -#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) -/* 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 */ -/* U+E000-U+F8FF */ -#define TT_UCR_PRIVATE_USE (1L << 28) -/* Bit 61 CJK Strokes */ -/* CJK Compatibility Ideographs */ -/* CJK Compatibility Ideographs Supplement */ -/* U+31C0-U+31EF */ -#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) -/* U+F900-U+FAFF */ -/*U+2F800-U+2FA1F*/ -/* Bit 62 Alphabetic Presentation Forms */ -/* U+FB00-U+FB4F */ -#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) -/* Bit 63 Arabic Presentation Forms-A */ -/* U+FB50-U+FDFF */ -#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) -/* Bit 64 Combining Half Marks */ -/* U+FE20-U+FE2F */ -#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) -/* Bit 65 Vertical forms */ -/* CJK Compatibility Forms */ -/* U+FE10-U+FE1F */ -#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) -/* U+FE30-U+FE4F */ -/* Bit 66 Small Form Variants */ -/* U+FE50-U+FE6F */ -#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) -/* Bit 67 Arabic Presentation Forms-B */ -/* U+FE70-U+FEFE */ -#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) -/* Bit 68 Halfwidth and Fullwidth Forms */ -/* U+FF00-U+FFEF */ -#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) -/* Bit 69 Specials */ -/* U+FFF0-U+FFFD */ -#define TT_UCR_SPECIALS (1L << 5) -/* Bit 70 Tibetan */ -/* U+0F00-U+0FFF */ -#define TT_UCR_TIBETAN (1L << 6) -/* Bit 71 Syriac */ -/* U+0700-U+074F */ -#define TT_UCR_SYRIAC (1L << 7) -/* Bit 72 Thaana */ -/* U+0780-U+07BF */ -#define TT_UCR_THAANA (1L << 8) -/* Bit 73 Sinhala */ -/* U+0D80-U+0DFF */ -#define TT_UCR_SINHALA (1L << 9) -/* Bit 74 Myanmar */ -/* U+1000-U+109F */ -#define TT_UCR_MYANMAR (1L << 10) -/* Bit 75 Ethiopic */ -/* Ethiopic Supplement */ -/* Ethiopic Extended */ -/* U+1200-U+137F */ -#define TT_UCR_ETHIOPIC (1L << 11) -/* U+1380-U+139F */ -/* U+2D80-U+2DDF */ -/* Bit 76 Cherokee */ -/* U+13A0-U+13FF */ -#define TT_UCR_CHEROKEE (1L << 12) -/* Bit 77 Unified Canadian Aboriginal Syllabics */ -/* U+1400-U+167F */ -#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) -/* Bit 78 Ogham */ -/* U+1680-U+169F */ -#define TT_UCR_OGHAM (1L << 14) -/* Bit 79 Runic */ -/* U+16A0-U+16FF */ -#define TT_UCR_RUNIC (1L << 15) -/* Bit 80 Khmer */ -/* Khmer Symbols */ -/* U+1780-U+17FF */ -#define TT_UCR_KHMER (1L << 16) -/* U+19E0-U+19FF */ -/* Bit 81 Mongolian */ -/* U+1800-U+18AF */ -#define TT_UCR_MONGOLIAN (1L << 17) -/* Bit 82 Braille Patterns */ -/* U+2800-U+28FF */ -#define TT_UCR_BRAILLE (1L << 18) -/* Bit 83 Yi Syllables */ -/* Yi Radicals */ -/* U+A000-U+A48F */ -#define TT_UCR_YI (1L << 19) -/* U+A490-U+A4CF */ -/* Bit 84 Tagalog */ -/* Hanunoo */ -/* Buhid */ -/* Tagbanwa */ -/* U+1700-U+171F */ -#define TT_UCR_PHILIPPINE (1L << 20) -/* U+1720-U+173F */ -/* U+1740-U+175F */ -/* U+1760-U+177F */ -/* Bit 85 Old Italic */ -/*U+10300-U+1032F*/ -#define TT_UCR_OLD_ITALIC (1L << 21) -/* Bit 86 Gothic */ -/*U+10330-U+1034F*/ -#define TT_UCR_GOTHIC (1L << 22) -/* Bit 87 Deseret */ -/*U+10400-U+1044F*/ -#define TT_UCR_DESERET (1L << 23) -/* Bit 88 Byzantine Musical Symbols */ -/* Musical Symbols */ -/* Ancient Greek Musical Notation */ -/*U+1D000-U+1D0FF*/ -#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) -/*U+1D100-U+1D1FF*/ -/*U+1D200-U+1D24F*/ -/* Bit 89 Mathematical Alphanumeric Symbols */ -/*U+1D400-U+1D7FF*/ -#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) -/* Bit 90 Private Use (plane 15) */ -/* Private Use (plane 16) */ -/*U+F0000-U+FFFFD*/ -#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) -/*U+100000-U+10FFFD*/ -/* Bit 91 Variation Selectors */ -/* Variation Selectors Supplement */ -/* U+FE00-U+FE0F */ -#define TT_UCR_VARIATION_SELECTORS (1L << 27) -/*U+E0100-U+E01EF*/ -/* Bit 92 Tags */ -/*U+E0000-U+E007F*/ -#define TT_UCR_TAGS (1L << 28) -/* Bit 93 Limbu */ -/* U+1900-U+194F */ -#define TT_UCR_LIMBU (1L << 29) -/* Bit 94 Tai Le */ -/* U+1950-U+197F */ -#define TT_UCR_TAI_LE (1L << 30) -/* Bit 95 New Tai Lue */ -/* U+1980-U+19DF */ -#define TT_UCR_NEW_TAI_LUE (1L << 31) -/* Bit 96 Buginese */ -/* U+1A00-U+1A1F */ -#define TT_UCR_BUGINESE (1L << 0) -/* Bit 97 Glagolitic */ -/* U+2C00-U+2C5F */ -#define TT_UCR_GLAGOLITIC (1L << 1) -/* Bit 98 Tifinagh */ -/* U+2D30-U+2D7F */ -#define TT_UCR_TIFINAGH (1L << 2) -/* Bit 99 Yijing Hexagram Symbols */ -/* U+4DC0-U+4DFF */ -#define TT_UCR_YIJING (1L << 3) -/* Bit 100 Syloti Nagri */ -/* U+A800-U+A82F */ -#define TT_UCR_SYLOTI_NAGRI (1L << 4) -/* Bit 101 Linear B Syllabary */ -/* Linear B Ideograms */ -/* Aegean Numbers */ -/*U+10000-U+1007F*/ -#define TT_UCR_LINEAR_B (1L << 5) -/*U+10080-U+100FF*/ -/*U+10100-U+1013F*/ -/* Bit 102 Ancient Greek Numbers */ -/*U+10140-U+1018F*/ -#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) -/* Bit 103 Ugaritic */ -/*U+10380-U+1039F*/ -#define TT_UCR_UGARITIC (1L << 7) -/* Bit 104 Old Persian */ -/*U+103A0-U+103DF*/ -#define TT_UCR_OLD_PERSIAN (1L << 8) -/* Bit 105 Shavian */ -/*U+10450-U+1047F*/ -#define TT_UCR_SHAVIAN (1L << 9) -/* Bit 106 Osmanya */ -/*U+10480-U+104AF*/ -#define TT_UCR_OSMANYA (1L << 10) -/* Bit 107 Cypriot Syllabary */ -/*U+10800-U+1083F*/ -#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) -/* Bit 108 Kharoshthi */ -/*U+10A00-U+10A5F*/ -#define TT_UCR_KHAROSHTHI (1L << 12) -/* Bit 109 Tai Xuan Jing Symbols */ -/*U+1D300-U+1D35F*/ -#define TT_UCR_TAI_XUAN_JING (1L << 13) -/* Bit 110 Cuneiform */ -/* Cuneiform Numbers and Punctuation */ -/*U+12000-U+123FF*/ -#define TT_UCR_CUNEIFORM (1L << 14) -/*U+12400-U+1247F*/ -/* Bit 111 Counting Rod Numerals */ -/*U+1D360-U+1D37F*/ -#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) -/* Bit 112 Sundanese */ -/* U+1B80-U+1BBF */ -#define TT_UCR_SUNDANESE (1L << 16) -/* Bit 113 Lepcha */ -/* U+1C00-U+1C4F */ -#define TT_UCR_LEPCHA (1L << 17) -/* Bit 114 Ol Chiki */ -/* U+1C50-U+1C7F */ -#define TT_UCR_OL_CHIKI (1L << 18) -/* Bit 115 Saurashtra */ -/* U+A880-U+A8DF */ -#define TT_UCR_SAURASHTRA (1L << 19) -/* Bit 116 Kayah Li */ -/* U+A900-U+A92F */ -#define TT_UCR_KAYAH_LI (1L << 20) -/* Bit 117 Rejang */ -/* U+A930-U+A95F */ -#define TT_UCR_REJANG (1L << 21) -/* Bit 118 Cham */ -/* U+AA00-U+AA5F */ -#define TT_UCR_CHAM (1L << 22) -/* Bit 119 Ancient Symbols */ -/*U+10190-U+101CF*/ -#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) -/* Bit 120 Phaistos Disc */ -/*U+101D0-U+101FF*/ -#define TT_UCR_PHAISTOS_DISC (1L << 24) -/* Bit 121 Carian */ -/* Lycian */ -/* Lydian */ -/*U+102A0-U+102DF*/ -#define TT_UCR_OLD_ANATOLIAN (1L << 25) -/*U+10280-U+1029F*/ -/*U+10920-U+1093F*/ -/* Bit 122 Domino Tiles */ -/* Mahjong Tiles */ -/*U+1F030-U+1F09F*/ -#define TT_UCR_GAME_TILES (1L << 26) -/*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 -/* !HAVE_LIMIT_ON_IDENTS */ -#endif -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#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; - }; -#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ - set_property_, \ - get_property_ ) \ - static const FT_Service_PropertiesRec class_ = \ - { \ - set_property_, \ - get_property_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVSFNT_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; - }; -#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ - static const FT_Service_SFNT_TableRec class_ = \ - { \ - load_, get_, info_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVPOSTNM_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; - }; -#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ - static const FT_Service_PsFontNameRec class_ = \ - { \ - get_ps_font_name_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVGLDICT_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; -/* optional */ - FT_GlyphDict_NameIndexFunc name_index; - }; -#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ - get_name_, \ - name_index_) \ - static const FT_Service_GlyphDictRec class_ = \ - { \ - get_name_, name_index_ \ - }; -/* */ -FT_END_HEADER -/***************************************************************************/ -/* */ -/* 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. */ -#define __SVTTCMAP_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; - }; -#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ - static const FT_Service_TTCMapsRec class_ = \ - { \ - get_cmap_info_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVKERN_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVTTENG_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTBASE_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 -/* END */ -#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_Err_Invalid_Library_Handle; - if ( !args ) - return FT_Err_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 ); - } - 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; - } - else - error = FT_Err_Invalid_Argument; - if ( error ) - FT_FREE( stream ); - else -/* just to be certain */ - stream->memory = memory; - *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_Err_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 ); - } -/* GRID_FIT_METRICS */ -#endif -/* 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_Err_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_Err_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_Err_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! */ -/* points after the last one */ - cur = first + face->num_charmaps; - 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_Err_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; -/* points after the last one */ - end = first + face->num_charmaps; - 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; - if ( FT_NEW( internal ) ) - goto Fail; - face->internal = internal; - face->driver = driver; - face->memory = memory; - face->stream = stream; - { - 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; - } - 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 && error2 != FT_Err_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_Err_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_Err_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 ); - } -/* 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_Err_Invalid_Library_Handle; - if ( !base ) - return FT_Err_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_Err_Unknown_File_Format; - if ( FT_READ_USHORT( numTables ) ) - return error; -/* skip binary search header */ - if ( FT_STREAM_SKIP( 2 * 3 ) ) - 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_Err_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, - face_index < 0 ? face_index : 0, - is_sfnt_cid ? "cid" : "type1", - aface ); - Exit: - { - FT_Error error1; - if ( error == FT_Err_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; -/* Ascii section */ - pfb_data[1] = 1; -/* 4-byte length, fill in later */ - pfb_data[2] = 0; - 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() */ -/* Comment, should not be loaded */ - if ( ( flags >> 8 ) == 0 ) - 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 ); -/* End of font mark */ - if ( ( flags >> 8 ) == 5 ) - 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; -/* 4-byte length, fill in later */ - pfb_data[pfb_pos++] = 0; - 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_Err_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_Err_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_Err_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_Err_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]; -/* 0 */ -#endif - 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]; -/* not tested */ - FT_Bool is_darwin_vfs, vfs_rfork_has_no_font = FALSE; - 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 && error == FT_Err_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_ERROR_BASE( error ) == FT_Err_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_ERROR_BASE( error ) == FT_Err_Unknown_File_Format || - FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) && - ( args->flags & FT_OPEN_PATHNAME ) ) - error = load_face_in_embedded_rfork( library, stream, - face_index, aface, args ); - return error; - } -#endif -/* 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; - FT_Memory memory; - 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_Err_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_Err_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; - if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && - FT_ERROR_BASE( error ) == FT_Err_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; - } - } - if ( FT_ERROR_BASE( error ) != FT_Err_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_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream && - FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && - FT_ERROR_BASE( error ) != FT_Err_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_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) - goto Fail2; -/* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ -#endif -/* no driver is able to handle this format */ - error = FT_Err_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: - FT_Done_Face( face ); - 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_Err_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_Err_Invalid_Face_Handle; - driver = face->driver; - if ( !driver ) - return FT_Err_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_Err_Invalid_Face_Handle; - if ( !asize ) - return FT_Err_Invalid_Size_Handle; - if ( !face->driver ) - return FT_Err_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_Err_Invalid_Size_Handle; - face = size->face; - if ( !face ) - return FT_Err_Invalid_Face_Handle; - driver = face->driver; - if ( !driver ) - return FT_Err_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_Err_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_Err_Invalid_Face_Handle; -/* FT_Bitmap_Size doesn't provide enough info... */ - if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) - return FT_Err_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 ) - { - if ( size_index ) - *size_index = (FT_ULong)i; - return FT_Err_Ok; - } - } - return FT_Err_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 ) ); -/* !GRID_FIT_METRICS */ -#else - 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 ); -/* !GRID_FIT_METRICS */ -#endif - } - 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_Err_Invalid_Face_Handle; - if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) - return FT_Err_Invalid_Argument; - clazz = face->driver->clazz; - if ( clazz->select_size ) - { - FT_Error error; - error = clazz->select_size( face->size, (FT_ULong)strike_index ); - 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_Err_Invalid_Face_Handle; - if ( !req || req->width < 0 || req->height < 0 || - req->type >= FT_SIZE_REQUEST_TYPE_MAX ) - return FT_Err_Invalid_Argument; - clazz = face->driver->clazz; - if ( clazz->request_size ) - { - FT_Error error; - error = clazz->request_size( face->size, req ); - 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; - FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n", - strike_index )); - 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_Err_Invalid_Face_Handle; - if ( !akerning ) - return FT_Err_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_Err_Invalid_Face_Handle; - if ( !akerning ) - return FT_Err_Invalid_Argument; - FT_FACE_FIND_SERVICE( face, service, KERNING ); - if ( !service ) - return FT_Err_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_Err_Invalid_Face_Handle; - if ( encoding == FT_ENCODING_NONE ) - return FT_Err_Invalid_Argument; -/* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ -/* charmap available, i.e., one with UCS-4 characters, if possible. */ -/* */ -/* 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_Err_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_Err_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_Err_Invalid_Face_Handle; - cur = face->charmaps; - if ( !cur ) - return FT_Err_Invalid_CharMap_Handle; - if ( FT_Get_CMap_Format( charmap ) == 14 ) - return FT_Err_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_Err_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_Err_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_Err_Invalid_Face_Handle; - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) - return FT_Err_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_Err_Invalid_Face_Handle; - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) - return FT_Err_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_Err_Invalid_Argument; - face = size->face; - if ( face == NULL || face->driver == NULL ) - return FT_Err_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_Err_Invalid_Library_Handle; - if ( !renderer ) - return FT_Err_Invalid_Argument; - node = FT_List_Find( &library->renderers, renderer ); - if ( !node ) - { - error = FT_Err_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 ) - { -/* already a bitmap, don't do anything */ - case FT_GLYPH_FORMAT_BITMAP: - 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_ERROR_BASE( error ) != FT_Err_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 ); - } - } - 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_Err_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 = NULL; - FT_UInt nn; -#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ - FREETYPE_MINOR ) - if ( !library ) - return FT_Err_Invalid_Library_Handle; - if ( !clazz ) - return FT_Err_Invalid_Argument; -/* check freetype version */ - if ( clazz->module_requires > FREETYPE_VER_FIXED ) - return FT_Err_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_Err_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_Err_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->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_Err_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_Err_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; - FT_Bool missing_func; - if ( !library ) - return FT_Err_Invalid_Library_Handle; - if ( !module_name || !property_name || !value ) - return FT_Err_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_Err_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_Err_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_Err_Unimplemented_Feature; - } - service = (FT_Service_Properties)interface; - if ( set ) - missing_func = !service->set_property; - else - missing_func = !service->get_property; - if ( missing_func ) - { - FT_ERROR(( "%s: property service of module `%s' is broken\n", - func_name, module_name )); - return FT_Err_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_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_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_Err_Invalid_Argument; -/* first of all, allocate the library object */ - if ( FT_NEW( library ) ) - return error; - library->memory = memory; -/* 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: - 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_Err_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; - 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 */ -/***************************************************************************/ -/* */ -/* ftoutln.c */ -/* */ -/* FreeType outline management (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* All functions are declared in freetype.h. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* fttrigon.h */ -/* */ -/* FreeType trigonometric functions (specification). */ -/* */ -/* Copyright 2001, 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. */ -/* */ -/***************************************************************************/ -#define __FTTRIGON_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 float 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 -/* END */ -/*************************************************************************/ -/* */ -/* 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; -/* index of contour in outline */ - FT_Int n; -/* index of first point in contour */ - FT_UInt first; -/* current point's state */ - FT_Int tag; - FT_Int shift; - FT_Pos delta; - if ( !outline || !func_interface ) - return FT_Err_Invalid_Argument; - shift = func_interface->shift; - delta = func_interface->delta; - first = 0; - for ( n = 0; n < outline->n_contours; n++ ) - { -/* index of last point in contour */ - FT_Int last; - 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 ) - { -/* emit a single line_to */ - case FT_CURVE_TAG_ON: - { - 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; - } -/* consume conic arcs */ - case FT_CURVE_TAG_CONIC: - 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; -/* FT_CURVE_TAG_CUBIC */ - default: - { - 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_Err_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_Err_Invalid_Argument; - *anoutline = null_outline; - 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_Err_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_Err_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_Err_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_Err_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_Err_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_Err_Invalid_Library_Handle; - if ( !outline || !params ) - return FT_Err_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_ERROR_BASE( error ) != FT_Err_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_Err_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; - } -/* 0 */ -#endif -/* 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_Err_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_Err_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 the incoming vector and its length */ - in.x = v_cur.x - v_prev.x; - in.y = v_cur.y - v_prev.y; - l_in = FT_Vector_Length( &in ); - for ( n = first; n <= last; n++ ) - { - if ( n < last ) - v_next = points[n + 1]; - else - v_next = v_first; -/* compute the outgoing vector and its length */ - out.x = v_next.x - v_cur.x; - out.y = v_next.y - v_cur.y; - l_out = FT_Vector_Length( &out ); - d = l_in * l_out + in.x * out.x + in.y * out.y; -/* shift only if turn is less then ~160 degrees */ - if ( 16 * d > l_in * l_out ) - { -/* shift components are aligned along bisector */ -/* and directed according to the outline orientation. */ - shift.x = l_out * in.y + l_in * out.y; - shift.y = l_out * in.x + l_in * out.x; - if ( orientation == FT_ORIENTATION_TRUETYPE ) - shift.x = -shift.x; - else - shift.y = -shift.y; -/* threshold strength to better handle collapsing segments */ - l = FT_MIN( l_in, l_out ); - q = out.x * in.y - out.y * in.x; - if ( orientation == FT_ORIENTATION_TRUETYPE ) - q = -q; - if ( FT_MulDiv( xstrength, q, l ) < d ) - shift.x = FT_MulDiv( shift.x, xstrength, d ); - else - shift.x = FT_MulDiv( shift.x, l, q ); - if ( FT_MulDiv( ystrength, q, l ) < d ) - 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_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. */ - 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 ) * ( v_cur.x + v_prev.x ); - 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 */ -/***************************************************************************/ -/* */ -/* ftrfork.c */ -/* */ -/* Embedded resource forks accessor (body). */ -/* */ -/* Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010 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. */ -/***************************************************************************/ -#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_Err_Unknown_File_Format; - error = FT_Stream_Seek( stream, map_pos ); - if ( error ) - return error; -/* make it be different */ - head2[15] = (FT_Byte)( head[15] + 1 ); - 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_Err_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. */ -/* skip handle to next resource map */ - (void)FT_STREAM_SKIP( 4 -/* skip file resource number */ - + 2 -/* skip attributes */ - + 2 ); - if ( FT_READ_USHORT( type_list ) ) - return error; - if ( type_list == -1 ) - return FT_Err_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; -/* resource name */ - if ( FT_STREAM_SKIP( 2 ) ) - goto Exit; - if ( FT_READ_LONG( temp ) ) - goto Exit; -/* mbz */ - if ( FT_STREAM_SKIP( 4 ) ) - 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_Err_Cannot_Open_Resource; - } -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/**** ****/ -/**** ****/ -/**** 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_Err_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_Err_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_Err_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_strlen( base_file_name ); - FT_UNUSED( stream ); - memory = library->memory; - if ( base_file_len + 6 > FT_INT_MAX ) - return FT_Err_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_strlen( base_file_name ); - FT_UNUSED( stream ); - memory = library->memory; - if ( base_file_len + 18 > FT_INT_MAX ) - return FT_Err_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_Err_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_Err_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_Err_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_Err_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_Err_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_Err_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 - { -/* offset + length */ - error = FT_Stream_Skip( stream, 4 + 4 ); - if ( error ) - return error; - } - } - return FT_Err_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; - } -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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__ -#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; -/* this string is *not* null-terminated! */ - FT_Byte* string; -/* in bytes */ - FT_UInt string_len; - } 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 -/* __FT_SFNT_NAMES_H__ */ -#endif -/* END */ -/* 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; - } -/* END */ -/***************************************************************************/ -/* */ -/* ftstream.c */ -/* */ -/* I/O stream support (body). */ -/* */ -/* Copyright 2000-2002, 2004-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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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_Err_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_Err_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_Err_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_Err_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_Err_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; - FT_FREE( *pbytes ); - } - *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_Err_Invalid_Stream_Operation; - goto Exit; - } - if ( FT_QALLOC( stream->base, count ) ) - goto Exit; -/* 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_Err_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_Err_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; - FT_FREE( stream->base ); - } - 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_Err_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_Err_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_Err_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_Err_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_Err_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_Err_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_Err_Invalid_Argument; - cursor = stream->cursor; - error = FT_Err_Ok; - do - { - FT_ULong value; - FT_Int sign_shift; - FT_Byte* p; - switch ( fields->value ) - { -/* access a new frame */ - case ft_frame_start: - error = FT_Stream_EnterFrame( stream, fields->offset ); - if ( error ) - goto Exit; - frame_accessed = 1; - cursor = stream->cursor; - fields++; -/* loop! */ - continue; -/* read a byte sequence */ - case ft_frame_bytes: -/* skip some bytes */ - case ft_frame_skip: - { - FT_UInt len = fields->size; - if ( cursor + len > stream->limit ) - { - error = FT_Err_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: -/* read a single byte */ - case ft_frame_schar: - value = FT_NEXT_BYTE(cursor); - sign_shift = 24; - break; - case ft_frame_short_be: -/* read a 2-byte big-endian short */ - case ft_frame_ushort_be: - value = FT_NEXT_USHORT(cursor); - sign_shift = 16; - break; - case ft_frame_short_le: -/* read a 2-byte little-endian short */ - case ft_frame_ushort_le: - value = FT_NEXT_USHORT_LE(cursor); - sign_shift = 16; - break; - case ft_frame_long_be: -/* read a 4-byte big-endian long */ - case ft_frame_ulong_be: - value = FT_NEXT_ULONG(cursor); - sign_shift = 0; - break; - case ft_frame_long_le: -/* read a 4-byte little-endian long */ - case ft_frame_ulong_le: - value = FT_NEXT_ULONG_LE(cursor); - sign_shift = 0; - break; - case ft_frame_off3_be: -/* read a 3-byte big-endian long */ - case ft_frame_uoff3_be: - value = FT_NEXT_UOFF3(cursor); - sign_shift = 8; - break; - case ft_frame_off3_le: -/* read a 3-byte little-endian long */ - case ft_frame_uoff3_le: - 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; -/* for 64-bit systems */ - default: - *(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 */ -/***************************************************************************/ -/* */ -/* fttrigon.c */ -/* */ -/* FreeType trigonometric functions (body). */ -/* */ -/* Copyright 2001-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. */ -/* */ -/***************************************************************************/ -#ifdef FT_LONG64 - typedef FT_INT64 FT_Int64; -#endif -/* the Cordic shrink factor 0.607252935008887 * 2^32 */ -#define FT_TRIG_SCALE 0x9B74EDA8UL -/* the following is 0.607252935008887 * 2^30 */ -#define FT_TRIG_COSCALE 0x26DD3B6AUL -/* 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[23] = - { - 2949120L, 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 = ( val >= 0 ) ? val : -val; - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); - return ( s >= 0 ) ? val : -val; - } -/* !FT_LONG64 */ -#else -/* 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 = ( val >= 0 ) ? val : -val; - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)( val & 0xFFFFL ); -/* constant */ - k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; -/* constant */ - k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL ); - hi = k1 * v1; -/* can't overflow */ - lo1 = k1 * v2 + k2 * v1; - lo2 = ( k2 * v2 ) >> 16; - lo3 = ( lo1 >= lo2 ) ? lo1 : lo2; - lo1 += lo2; - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += (FT_UInt32)0x10000UL; - val = (FT_Fixed)hi; - return ( s >= 0 ) ? val : -val; - } -/* !FT_LONG64 */ -#endif - static FT_Int - ft_trig_prenorm( FT_Vector* vec ) - { - FT_Fixed x, y, z; - FT_Int shift; - x = vec->x; - y = vec->y; - z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); - shift = 0; -#if 1 -/* 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; - } - if ( shift <= 27 ) - { - shift = 27 - shift; - vec->x = x << shift; - vec->y = y << shift; - } - else - { - shift -= 27; - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } -/* 0 */ -#else - if ( z < ( 1L << 27 ) ) - { - do - { - shift++; - z <<= 1; - } while ( z < ( 1L << 27 ) ); - vec->x = x << shift; - vec->y = y << shift; - } - else if ( z > ( 1L << 28 ) ) - { - do - { - shift++; - z >>= 1; - } while ( z > ( 1L << 28 ) ); - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } -/* 0 */ -#endif - return shift; - } - static void - ft_trig_pseudo_rotate( FT_Vector* vec, - FT_Angle theta ) - { - FT_Int i; - FT_Fixed x, y, xtemp; - const FT_Fixed *arctanptr; - x = vec->x; - y = vec->y; -/* Get angle between -90 and 90 degrees */ - while ( theta <= -FT_ANGLE_PI2 ) - { - x = -x; - y = -y; - theta += FT_ANGLE_PI; - } - while ( theta > FT_ANGLE_PI2 ) - { - x = -x; - y = -y; - theta -= FT_ANGLE_PI; - } - arctanptr = ft_trig_arctan_table; -/* Pseudorotations, with right shifts */ - i = 0; - do - { - if ( theta < 0 ) - { - xtemp = x + ( y >> i ); - y = y - ( x >> i ); - x = xtemp; - theta += *arctanptr++; - } - else - { - xtemp = x - ( y >> i ); - y = y + ( x >> i ); - x = xtemp; - theta -= *arctanptr++; - } - } while ( ++i < FT_TRIG_MAX_ITERS ); - 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; - const FT_Fixed *arctanptr; - x = vec->x; - y = vec->y; -/* Get the vector into the right half plane */ - theta = 0; - if ( x < 0 ) - { - x = -x; - y = -y; - theta = 2 * FT_ANGLE_PI2; - } - if ( y > 0 ) - theta = - theta; - arctanptr = ft_trig_arctan_table; -/* Pseudorotations, with right shifts */ - i = 0; - do - { - if ( y > 0 ) - { - xtemp = x + ( y >> i ); - y = y - ( x >> i ); - x = xtemp; - theta += *arctanptr++; - } - else - { - xtemp = x - ( y >> i ); - y = y + ( x >> i ); - x = xtemp; - theta -= *arctanptr++; - } - } while ( ++i < FT_TRIG_MAX_ITERS ); -/* 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_COSCALE >> 2; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); - return v.x / ( 1 << 12 ); - } -/* 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_COSCALE >> 2; - 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_COSCALE >> 2; - vec->y = 0; - ft_trig_pseudo_rotate( vec, angle ); - vec->x >>= 12; - vec->y >>= 12; - } -/* 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 = v.x << shift; - vec->y = 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 ( v.y >= 0 ) ? v.y : -v.y; - } - else if ( v.y == 0 ) - { - return ( v.x >= 0 ) ? v.x : -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 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 ) : ( 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 */ -/***************************************************************************/ -/* */ -/* ftutil.c */ -/* */ -/* FreeType utility file for memory and list management (body). */ -/* */ -/* Copyright 2002, 2004, 2005, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.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 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_Err_Out_Of_Memory; - } - else if ( size < 0 ) - { -/* may help catch/prevent security issues */ - error = FT_Err_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_Err_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_Err_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_Err_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--; - } -/* always zero-terminate */ - *dst = 0; - 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 ( ;; ) - { -/* clear lowest bit */ - value2 = value & (value - 1); - if ( value2 == 0 ) - break; - value = value2; - } - return value; - } -/* END */ -#ifdef FT_MACINTOSH -/***************************************************************************/ -/* */ -/* 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-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, */ -/* 2009 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. - */ -/* 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 -/* !HAVE_TYPE_RESOURCE_INDEX */ -#endif -#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) - typedef short ResourceIndex; -#endif -#include <CoreServices/CoreServices.h> -#include <ApplicationServices/ApplicationServices.h> -/* PATH_MAX */ -#include <sys/syslimits.h> -/* Don't want warnings about our own use of deprecated functions. */ -#define FT_DEPRECATED_ATTRIBUTE -/***************************************************************************/ -/* */ -/* 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.) */ -/* */ -/***************************************************************************/ -#define __FTMAC_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 -/* END */ -/* since Mac OS X 10.1 */ -#ifndef kATSOptionFlagsUnRestrictedScope -#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_Err_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; -/* No 64bit Carbon API on legacy platforms */ -#elif __LP64__ - FT_UNUSED( ats_font_id ); - FT_UNUSED( ats_font_ref ); - return fnfErr; -/* 32bit Carbon API on legacy platforms */ -#else - 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_Err_Unknown_File_Format; - if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) ) - return FT_Err_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 ( FT_Err_Ok != err ) - return err; - if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) ) - return FT_Err_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_Err_Unimplemented_Feature; -#else - FSRef ref; - FT_Error err; - err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); - if ( FT_Err_Ok != err ) - return err; - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, - pathSpec, NULL ) ) - return FT_Err_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_Err_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; - FamRec* fond; - short i, face, face_all; - fond = (FamRec*)fond_data; - 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 ) ) - { -/* add on the face_index! */ - assoc += 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_Err_Invalid_Argument; - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, - NULL, NULL, NULL, &par_ref ) ) - return FT_Err_Invalid_Argument; - if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) ) - return FT_Err_Invalid_Argument; - if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size ) - return FT_Err_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_Err_Cannot_Open_Resource; - if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, - NULL, NULL, NULL, NULL ) ) - return FT_Err_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 ( FT_Err_Ok == 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 ) -/* we are done */ - break; - code = (*post_data)[0]; - if ( code != last_code ) - { - if ( code == 5 ) -/* just the end code */ - total_size += 2; - else -/* code + 4 bytes chunk length */ - total_size += 6; - } - total_size += GetHandleSize( post_data ) - 2; - last_code = code; -/* detect integer overflows */ - if ( total_size < old_total_size ) - { - error = FT_Err_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 ) -/* we are done */ - break; - 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 ) -/* the end */ - *p++ = 0x03; - else if ( code == 2 ) -/* binary segment */ - *p++ = 0x02; - else -/* ASCII segment */ - *p++ = 0x01; - if ( code != 5 ) - { -/* save for later */ - size_p = p; -/* make space for size field */ - p += 4; - } - } - 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_Err_Cannot_Open_Resource; - pfb_data = NULL; - pfb_size = 0; - error = read_lwfn( library->memory, res, &pfb_data, &pfb_size ); -/* PFB is already loaded, useless anymore */ - CloseResFile( res ); - 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_Err_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, num_faces_in_fond; - if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) - return FT_Err_Cannot_Open_Resource; - UseResFile( res_ref ); - if ( ResError() ) - return FT_Err_Cannot_Open_Resource; - num_faces_in_res = 0; - for ( res_index = 1; ; ++res_index ) - { - 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 ( FT_Err_Ok == error && NULL != aface && NULL != *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_Err_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 ( FT_Err_Ok == 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_Err_Unknown_File_Format; - found_no_lwfn_file: - if ( have_sfnt && FT_Err_Ok != 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_Err_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_Err_Invalid_Argument; - err = FSRefMakePath( ref, pathname, sizeof ( pathname ) ); - if ( err ) - error = FT_Err_Cannot_Open_Resource; - error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); - if ( error != 0 || *aface != NULL ) - return error; -/* fallback to datafork font */ - args.flags = FT_OPEN_PATHNAME; - args.pathname = (char*)pathname; - return FT_Open_Face( library, &args, face_index, aface ); - } -/*************************************************************************/ -/* */ -/* <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_Err_Unimplemented_Feature; -#else - FSRef ref; - if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) - return FT_Err_Invalid_Argument; - else - return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); -#endif - } -/* FT_MACINTOSH */ -#endif -/* END */ -#endif -/* END */ -/***************************************************************************/ -/* */ -/* ftbbox.c */ -/* */ -/* FreeType bbox computation (body). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* This component has a _single_ role: to compute exact outline bounding */ -/* boxes. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __FTBBOX_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 -/* END */ -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ - 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 ) - { -/* flat arc */ - if ( y1 <= y3 && y2 == y1 ) - goto Suite; - if ( y1 < y3 ) - { -/* ascending arc */ - if ( y2 >= y1 && y2 <= y3 ) - goto Suite; - } - else - { -/* descending arc */ - if ( y2 >= y3 && y2 <= y1 ) - { - 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 stack[32*3 + 1], *arc; - arc = stack; - arc[0] = p1; - arc[1] = p2; - arc[2] = p3; - arc[3] = p4; - do - { - FT_Pos y1 = arc[0]; - FT_Pos y2 = arc[1]; - FT_Pos y3 = arc[2]; - FT_Pos y4 = arc[3]; - if ( y1 == y4 ) - { -/* flat */ - if ( y1 == y2 && y1 == y3 ) - goto Test; - } - else if ( y1 < y4 ) - { -/* ascending */ - if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) - goto Test; - } - else - { -/* descending */ - if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) - { - y2 = y1; - y1 = y4; - y4 = y2; - goto Test; - } - } -/* unknown direction -- split the arc in two */ - arc[6] = y4; - arc[1] = y1 = ( y1 + y2 ) / 2; - arc[5] = y4 = ( y4 + y3 ) / 2; - y2 = ( y2 + y3 ) / 2; - arc[2] = y1 = ( y1 + y2 ) / 2; - arc[4] = y4 = ( y4 + y2 ) / 2; - arc[3] = ( y1 + y4 ) / 2; - arc += 3; - goto Suite; - Test: - if ( y1 < *min ) *min = y1; - if ( y4 > *max ) *max = y4; - arc -= 3; - Suite: - ; - } while ( arc >= stack ); - } -#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; - } -/* y1 > y4 */ - else - { -/* descending arc test */ - if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) - return; - } -/* There are some split points. Find them. */ - { - 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; -/* 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 float values to ensure */ -/* that its product is held in a `16.16' value. */ - { - FT_ULong t1, t2; - int shift = 0; -/* The following computation is based on the fact that for */ -/* any value `y', if `n' is the position of the most */ -/* significant bit of `abs(y)' (starting from 0 for the */ -/* least significant bit), then `y' is in the range */ -/* */ -/* -2^n..2^n-1 */ -/* */ -/* We want to shift `a', `b', and `c' concurrently in order */ -/* to ensure that they all fit in 8.16 values, which maps */ -/* to the integer range `-2^23..2^23-1'. */ -/* */ -/* Necessarily, we need to shift `a', `b', and `c' so that */ -/* the most significant bit of its absolute values is at */ -/* _most_ at position 23. */ -/* */ -/* We begin by computing `t1' as the bitwise `OR' of the */ -/* absolute values of `a', `b', `c'. */ - t1 = (FT_ULong)( ( a >= 0 ) ? a : -a ); - t2 = (FT_ULong)( ( b >= 0 ) ? b : -b ); - t1 |= t2; - t2 = (FT_ULong)( ( c >= 0 ) ? c : -c ); - t1 |= t2; -/* Now we can be sure that the most significant bit of `t1' */ -/* is the most significant bit of either `a', `b', or `c', */ -/* depending on the greatest integer range of the particular */ -/* variable. */ -/* */ -/* Next, we compute the `shift', by shifting `t1' as many */ -/* times as necessary to move its MSB to position 23. This */ -/* corresponds to a value of `t1' that is in the range */ -/* 0x40_0000..0x7F_FFFF. */ -/* */ -/* Finally, we shift `a', `b', and `c' by the same amount. */ -/* This ensures that all values are now in the range */ -/* -2^23..2^23, i.e., they are now expressed as 8.16 */ -/* fixed-float numbers. This also means that we are using */ -/* 24 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). */ -/* all coefficients are 0! */ - if ( t1 == 0 ) - return; - if ( t1 > 0x7FFFFFUL ) - { - do - { - shift++; - t1 >>= 1; - } while ( t1 > 0x7FFFFFUL ); -/* this loses some bits of precision, but we use 24 of them */ -/* for the computation anyway */ - a >>= shift; - b >>= shift; - c >>= shift; - } - else if ( t1 < 0x400000UL ) - { - do - { - shift++; - t1 <<= 1; - } while ( t1 < 0x400000UL ); - 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_Err_Invalid_Argument; - if ( !outline ) - return FT_Err_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; - 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 */ -/***************************************************************************/ -/* */ -/* ftglyph.c */ -/* */ -/* FreeType convenience functions to handle glyphs (body). */ -/* */ -/* Copyright 1996-2005, 2007, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* ftbitmap.h */ -/* */ -/* FreeType utility functions for bitmaps (specification). */ -/* */ -/* Copyright 2004, 2005, 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. */ -/* */ -/***************************************************************************/ -#define __FTBITMAP_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, or 8bpp to a */ -/* bitmap object with depth 8bpp, making the number of used bytes per */ -/* 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 -/* END */ -/*************************************************************************/ -/* */ -/* 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_Err_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, -/* FT_Glyph_TransformFunc */ - 0, - ft_bitmap_glyph_bbox, -/* FT_Glyph_PrepareFunc */ - 0 - ) -/*************************************************************************/ -/*************************************************************************/ -/**** ****/ -/**** 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_Err_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_Err_Invalid_Argument; - goto Exit; - } - *target = 0; - if ( !source || !source->clazz ) - { - error = FT_Err_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_Err_Invalid_Slot_Handle; - library = slot->library; - if ( !aglyph ) - return FT_Err_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_Err_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_Err_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_Err_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_Err_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 */ -/***************************************************************************/ -/* */ -/* ftbitmap.c */ -/* */ -/* FreeType utility functions for bitmaps (body). */ -/* */ -/* Copyright 2004-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. */ -/* */ -/***************************************************************************/ - 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_Err_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_Err_Invalid_Library_Handle; - if ( !bitmap || !bitmap->buffer ) - return FT_Err_Invalid_Argument; - if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || - ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) - return FT_Err_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_Err_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; - } - 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; - } -/* 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_Err_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: - { - 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_Err_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_Err_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-- ) - { -/* avoid a byte->int cast on each line */ - FT_Int val = ss[0]; - 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; - 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_Err_Invalid_Library_Handle; - if ( !bitmap ) - return FT_Err_Invalid_Argument; - memory = library->memory; - FT_FREE( bitmap->buffer ); - *bitmap = null_bitmap; - return FT_Err_Ok; - } -/* END */ -/***************************************************************************/ -/* */ -/* ftbdf.c */ -/* */ -/* FreeType API for accessing BDF-specific strings (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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVBDF_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTBDF_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 -/* END */ -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; - }; -#define FT_DEFINE_SERVICE_BDFRec( class_, \ - get_charset_id_, \ - get_property_ ) \ - static const FT_Service_BDFRec class_ = \ - { \ - get_charset_id_, get_property_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/* 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 */ -/***************************************************************************/ -/* */ -/* ftcid.c */ -/* */ -/* FreeType API for accessing CID font information. */ -/* */ -/* Copyright 2007, 2009 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTCID_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVCID_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; - }; -#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_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/* 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVPSINFO_H__ -/***************************************************************************/ -/* */ -/* t1types.h */ -/* */ -/* Basic Type1/Type2 type 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. */ -/* */ -/***************************************************************************/ -#define __T1TYPES_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSHINTS_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; -#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_ \ - }; -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVPSCMAP_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_ - { -/* bit 31 set: is glyph variant */ - FT_UInt32 unicode; - 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; - }; -#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_ \ - }; -/* */ -FT_END_HEADER -/* END */ -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_ - { -/* font info dictionary */ - PS_FontInfoRec font_info; -/* font info extra fields */ - PS_FontExtraRec font_extra; -/* private dictionary */ - PS_PrivateRec private_dict; -/* top-level dictionary */ - FT_String* font_name; - 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; -/* array of glyph names */ - FT_String** glyph_names; -/* array of glyph charstrings */ - FT_Byte** 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; -/* free if non-NULL */ - AFM_TrackKern TrackKerns; - FT_Int NumTrackKern; -/* free if non-NULL */ - AFM_KernPair KernPairs; - 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' */ -/* used if hex data has been converted */ - FT_Byte* binary_data; - FT_Stream cid_stream; - } CID_FaceRec; -FT_END_HEADER -/* END */ -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; - }; -#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_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/* 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/* 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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_ -#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 ); -/* */ -/* _FT_GASP_H_ */ -#endif -/* END */ - 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 */ -/***************************************************************************/ -/* */ -/* ftgxval.c */ -/* */ -/* FreeType API for validating TrueTyepGX/AAT tables (body). */ -/* */ -/* Copyright 2004, 2005, 2006, 2010 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVGXVAL_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTGXVAL_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 -/* END */ -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 -/* END */ -/* 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_Err_Invalid_Face_Handle; - goto Exit; - } - if ( tables == NULL ) - { - error = FT_Err_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_Err_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_Err_Invalid_Face_Handle; - goto Exit; - } - if ( ckern_table == NULL ) - { - error = FT_Err_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_Err_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 */ -/***************************************************************************/ -/* */ -/* ftlcdfil.c */ -/* */ -/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ -/* */ -/* Copyright 2006, 2008, 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. */ -/* */ -/***************************************************************************/ -/* 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 ); - } - } - } - } -/* USE_LEGACY */ -#endif - FT_EXPORT_DEF( FT_Error ) - FT_Library_SetLcdFilterWeights( FT_Library library, - unsigned char *weights ) - { - if ( !library || !weights ) - return FT_Err_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_Err_Invalid_Argument; - switch ( filter ) - { - case FT_LCD_FILTER_NONE: - library->lcd_filter_func = NULL; - library->lcd_extra = 0; - break; - case FT_LCD_FILTER_DEFAULT: -#if defined( FT_FORCE_LEGACY_LCD_FILTER ) - library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; -#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - 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_Err_Invalid_Argument; - } - library->lcd_filter = filter; - return FT_Err_Ok; - } -/* END */ -/***************************************************************************/ -/* */ -/* ftmm.c */ -/* */ -/* Multiple Master font support (body). */ -/* */ -/* Copyright 1996-2001, 2003, 2004, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVMM_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; - }; -#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_ \ - }; -/* */ -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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_Err_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 */ -/***************************************************************************/ -/* */ -/* ftotval.c */ -/* */ -/* FreeType API for validating OpenType tables (body). */ -/* */ -/* Copyright 2004, 2006, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVOTVAL_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/* */ -/***************************************************************************/ -#define __FTOTVAL_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 -/* END */ -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 -/* END */ -/* 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_Err_Invalid_Face_Handle; - goto Exit; - } - if ( !( BASE_table && - GDEF_table && - GPOS_table && - GSUB_table && - JSTF_table ) ) - { - error = FT_Err_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_Err_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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVTTGLYF_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; - }; -#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ - static const FT_Service_TTGlyfRec class_ = \ - { \ - get_location_ \ - }; -/* */ -FT_END_HEADER -/* END */ - 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]) - { -/* SPvTL // */ - case 0x06: -/* SPvTL + */ - case 0x07: -/* SFvTL // */ - case 0x08: -/* SFvTL + */ - case 0x09: -/* SPvFS */ - case 0x0A: -/* SFvFS */ - case 0x0B: - 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; -/* DELTAP2 */ - case 0x71: -/* DELTAP3 */ - case 0x72: -/* DELTAC0 */ - case 0x73: -/* DELTAC1 */ - case 0x74: -/* DELTAC2 */ - case 0x75: - 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; -/* simple glyph */ - if ( num_contours >= 0 ) - { - if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) - continue; - } -/* compound glyph */ - else - { - 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; -/* ARGS_ARE_WORDS */ - if ( ( flags & ( 1 << 0 ) ) != 0 ) - toskip += 2; -/* WE_HAVE_A_SCALE */ - if ( ( flags & ( 1 << 3 ) ) != 0 ) - toskip += 2; -/* WE_HAVE_X_Y_SCALE */ - else if ( ( flags & ( 1 << 6 ) ) != 0 ) - toskip += 4; -/* WE_HAVE_A_2x2 */ - else if ( ( flags & ( 1 << 7 ) ) != 0 ) - toskip += 8; -/* WE_HAVE_INSTRUCTIONS */ - if ( ( flags & ( 1 << 8 ) ) != 0 ) - has_instr = 1; - if ( FT_STREAM_SKIP( toskip ) ) - goto NextGlyph; -/* MORE_COMPONENTS */ - if ( ( flags & ( 1 << 5 ) ) == 0 ) - 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 */ -/***************************************************************************/ -/* */ -/* ftpfr.c */ -/* */ -/* FreeType API for accessing PFR-specific data (body). */ -/* */ -/* Copyright 2002, 2003, 2004, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVPFR_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTPFR_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 -/* END */ -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 -/* END */ -/* 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_Err_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_Err_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_Err_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_Err_Invalid_Argument; - return error; - } -/* END */ -/***************************************************************************/ -/* */ -/* ftstroke.c */ -/* */ -/* FreeType path stroker (body). */ -/* */ -/* Copyright 2002-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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__ -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 -/* __FT_STROKE_H__ */ -#endif -/* END */ -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ -/* 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 ); - } - } -/* !close1 */ - else - { - 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 */ - } -/* !close3 */ - else - { - *angle_in = - *angle_mid = - *angle_out = FT_Atan2( d3.x, d3.y ); - } - } -/* !close2 */ - else - { - if ( close3 ) - { - *angle_in = - *angle_mid = - *angle_out = FT_Atan2( d2.x, d2.y ); - } -/* !close3 */ - else - { - *angle_in = - *angle_mid = FT_Atan2( d2.x, d2.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - } - } - } -/* !close1 */ - else - { - if ( close2 ) - { - if ( close3 ) - { - *angle_in = - *angle_mid = - *angle_out = FT_Atan2( d1.x, d1.y ); - } -/* !close3 */ - else - { - *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 ); - } - } -/* !close2 */ - else - { - if ( close3 ) - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_mid = - *angle_out = FT_Atan2( d2.x, d2.y ); - } -/* !close3 */ - else - { - *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_ - { -/* on-curve point */ - FT_STROKE_TAG_ON = 1, -/* cubic off-point */ - FT_STROKE_TAG_CUBIC = 2, -/* sub-path start */ - FT_STROKE_TAG_BEGIN = 4, -/* sub-path end */ - FT_STROKE_TAG_END = 8 - } 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; -/* TRUE for ends of lineto borders */ - FT_Bool movable; -/* index of current sub-path start point */ - FT_Int start; - 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_ - { -/* direction into curr join */ - FT_Angle angle_in; -/* direction out of join */ - FT_Angle angle_out; -/* current position */ - FT_Vector center; -/* length of last lineto */ - FT_Fixed line_length; -/* is this the start? */ - FT_Bool first_point; -/* is the subpath open? */ - FT_Bool subpath_open; -/* subpath start direction */ - FT_Angle subpath_angle; -/* subpath start position */ - FT_Vector subpath_start; -/* subpath start lineto len */ - FT_Fixed subpath_line_length; -/* use wide strokes logic? */ - FT_Bool handle_wide_strokes; - 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 ) - { -/* assigned in FT_NEW */ - FT_Error error; - FT_Memory memory; - FT_Stroker stroker = NULL; - if ( !library ) - return FT_Err_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; -/* use intersection of lines? */ - FT_Bool intersect; - 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; - } - } -/* this is a bevel (broken angle) */ - if ( bevel ) - { - 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 ); - } -/* variable bevel */ - else - { -/* 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 ); - } - } - } -/* this is a miter (intersection) */ - else - { - 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_Err_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; -/* index of contour in outline */ - FT_Int n; -/* index of first point in contour */ - FT_UInt first; -/* current point's state */ - FT_Int tag; - if ( !outline || !stroker ) - return FT_Err_Invalid_Argument; - FT_Stroker_Rewind( stroker ); - first = 0; - for ( n = 0; n < outline->n_contours; n++ ) - { -/* index of last point in contour */ - FT_UInt last; - 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 ) - { -/* emit a single line_to */ - case FT_CURVE_TAG_ON: - { - FT_Vector vec; - vec.x = point->x; - vec.y = point->y; - error = FT_Stroker_LineTo( stroker, &vec ); - if ( error ) - goto Exit; - continue; - } -/* consume conic arcs */ - case FT_CURVE_TAG_CONIC: - 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; -/* FT_CURVE_TAG_CUBIC */ - default: - { - 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_Err_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 */ - extern const FT_Glyph_Class ft_outline_glyph_class; -/* 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -#define __FTSYNTH_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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 ); - } -/* slot->format == FT_GLYPH_FORMAT_BITMAP */ - else - { -/* 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTWINFNT_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 -/* END */ -/* Local Variables: */ -/* coding: utf-8 */ -/* End: */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVWINFNT_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 -/* END */ -/* 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTXF86_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 -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SVXF86NM_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 -/* END */ -/* 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 */ -/* 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 -/* - * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001-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 based on bdf.c,v 1.22 2000/03/16 20:08:50 */ -/* */ -/* taken from Mark Leisher's xmbdfed package */ -/* */ -/*************************************************************************/ -/* - * 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. - */ -#define __BDF_H__ -/* - * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher - */ -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. */ -/* */ -/*************************************************************************/ -/* Correct invalid metrics when loading. */ -#define BDF_CORRECT_METRICS 0x01 -/* Preserve the font comments. */ -#define BDF_KEEP_COMMENTS 0x02 -/* Keep the unencoded glyphs. */ -#define BDF_KEEP_UNENCODED 0x04 -/* Font has proportional spacing. */ -#define BDF_PROPORTIONAL 0x08 -/* Font has mono width. */ -#define BDF_MONOWIDTH 0x10 -/* Font has charcell spacing. */ -#define BDF_CHARCELL 0x20 -#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_ - { -/* Name of the property. */ - char* name; -/* Format of the property. */ - int format; -/* A builtin property. */ - int builtin; - union - { - char* atom; - long l; - unsigned long ul; -/* Value of the property. */ - } value; - } 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_ - { -/* Glyph name. */ - char* name; -/* Glyph encoding. */ - long encoding; -/* Scalable width. */ - unsigned short swidth; -/* Device width. */ - unsigned short dwidth; -/* Glyph bounding box. */ - bdf_bbx_t bbx; -/* Glyph bitmap. */ - unsigned char* bitmap; -/* Number of bytes used per row. */ - unsigned long bpr; -/* Number of bytes used for the bitmap. */ - unsigned short bytes; - } 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_ - { -/* Pad to 4-byte boundary. */ - unsigned short pad; -/* Bits per pixel. */ - unsigned short bpp; -/* Beginning encoding value of glyphs. */ - long start; -/* Ending encoding value of glyphs. */ - long end; -/* Glyphs themselves. */ - bdf_glyph_t* glyphs; -/* Glyph structures allocated. */ - unsigned long glyphs_size; -/* Glyph structures used. */ - unsigned long glyphs_used; -/* Overall bounding box of glyphs. */ - bdf_bbx_t bbx; - } bdf_glyphlist_t; - typedef struct bdf_font_t_ - { -/* Name of the font. */ - char* name; -/* Font bounding box. */ - bdf_bbx_t bbx; -/* Point size of the font. */ - long point_size; -/* Font horizontal resolution. */ - unsigned long resolution_x; -/* Font vertical resolution. */ - unsigned long resolution_y; -/* Font spacing value. */ - int spacing; -/* Logical width for monowidth font. */ - unsigned short monowidth; -/* Encoding of the default glyph. */ - long default_char; -/* Font ascent. */ - long font_ascent; -/* Font descent. */ - long font_descent; -/* Glyph structures allocated. */ - unsigned long glyphs_size; -/* Glyph structures used. */ - unsigned long glyphs_used; -/* Glyphs themselves. */ - bdf_glyph_t* glyphs; -/* Unencoded glyph struct. allocated. */ - unsigned long unencoded_size; -/* Unencoded glyph struct. used. */ - unsigned long unencoded_used; -/* Unencoded glyphs themselves. */ - bdf_glyph_t* unencoded; -/* Font properties allocated. */ - unsigned long props_size; -/* Font properties used. */ - unsigned long props_used; -/* Font properties themselves. */ - bdf_property_t* props; -/* Font comments. */ - char* comments; -/* Length of comment string. */ - unsigned long comments_len; -/* Storage used for glyph insertion. */ - bdf_glyphlist_t overflow; -/* Internal data for the font. */ - void* internal; -/* The size of the next two arrays must be in sync with the */ -/* size of the `have' array in the `bdf_parse_t' structure. */ -/* Bitmap indicating modified glyphs. */ - unsigned long nmod[34816]; -/* Bitmap indicating modified */ - unsigned long umod[34816]; -/* unencoded glyphs. */ -/* Boolean indicating font modified. */ - unsigned short modified; -/* Bits per pixel. */ - unsigned short bpp; - 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 -/* END */ -/* - * 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. */ -/* */ -/*************************************************************************/ -#define __BDFERROR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX BDF_Err_ -#define FT_ERR_BASE FT_Mod_Err_BDF -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/*************************************************************************/ -/* */ -/* 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 = - { -/* Correct metrics. */ - 1, -/* Preserve unencoded glyphs. */ - 1, -/* Preserve comments. */ - 0, -/* Default spacing. */ - BDF_PROPORTIONAL - }; -/*************************************************************************/ -/* */ -/* 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. */ -/* no \n */ -#define DBGMSG1 " [%6ld] %s" -#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 = BDF_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 = BDF_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, *bp = hash_bucket( key, ht ); - FT_Error error = BDF_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; -/* must be in sync with `nmod' and `umod' */ - unsigned long have[34816]; -/* 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, -/* same as _bdf_list_t.used */ - unsigned long num_items ) - { - FT_Error error = BDF_Err_Ok; - if ( num_items > list->size ) - { -/* same as _bdf_list_t.size */ - unsigned long oldsize = list->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 = BDF_Err_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. */ -/* XXX eliminate this */ - static const char ft_empty[1] = { 0 }; - static char * - _bdf_list_join( _bdf_list_t* list, - int c, - unsigned long *alen ) - { - unsigned long i, j; - char *fp, *dp; - *alen = 0; - if ( list == 0 || list->used == 0 ) - return 0; - dp = list->field[0]; - for ( i = j = 0; i < list->used; i++ ) - { - fp = list->field[i]; - while ( *fp ) - dp[j++] = *fp++; - if ( i + 1 < list->used ) - dp[j++] = (char)c; - } - if ( dp != ft_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 = BDF_Err_Ok; -/* Initialize the list. */ - list->used = 0; - if ( list->size ) - { - list->field[0] = (char*)ft_empty; - list->field[1] = (char*)ft_empty; - list->field[2] = (char*)ft_empty; - list->field[3] = (char*)ft_empty; - list->field[4] = (char*)ft_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 = BDF_Err_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*)ft_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*)ft_empty; - list->field[list->used] = 0; - Exit: - return error; - } -/* this value cannot be stored in a 'char' */ -#define NO_SKIP 256 - 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 = BDF_Err_Ok; - if ( callback == 0 ) - { - error = BDF_Err_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; -/* make compiler happy */ - bytes = 0; - 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 ) - { -/* last line in file doesn't end in \r or \n */ - if ( bytes == 0 ) -/* ignore it then exit */ - break; - if ( start == 0 ) - { -/* this line is definitely too long; try resizing the input */ -/* buffer a bit to handle it. */ - FT_ULong new_size; -/* limit ourselves to 64KByte */ - if ( buf_size >= 65536UL ) - { - FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno )); - error = BDF_Err_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_COPY( 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 = BDF_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 BDF_Err_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 = BDF_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 = BDF_Err_Ok; - if ( font == 0 || font->name == 0 || font->name[0] == 0 ) - { - error = BDF_Err_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 = BDF_Err_Invalid_Argument; - goto Exit; - } - FT_MEM_COPY( name, font->name, len ); - error = _bdf_list_split( &list, (char *)"-", name, 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 = BDF_Err_Ok; -/* 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 = BDF_Err_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 = BDF_Err_Ok; - FT_UNUSED( call_data ); -/* only used in debug mode */ - FT_UNUSED( lineno ); - 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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_Invalid_File_Format; - goto Exit; - Missing_Encoding: -/* Missing ENCODING field. */ - FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); - error = BDF_Err_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 = BDF_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 = BDF_Err_Ok; -/* only used in debug mode */ - FT_UNUSED( lineno ); - 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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 = BDF_Err_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 ) - { -/* make compiler happy */ - unsigned long lineno = 0; - _bdf_parse_t *p = NULL; - FT_Memory memory = extmemory; - FT_Error error = BDF_Err_Ok; - if ( FT_NEW( p ) ) - goto Exit; - memory = NULL; - p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); - p->minlb = 32767; -/* only during font creation */ - p->memory = extmemory; - _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 = BDF_Err_Corrupted_Font_Header; - goto Exit; - } - else - { -/* Error happened when parsing glyphs. */ - FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); - error = BDF_Err_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 == BDF_Err_Ok ) - error = BDF_Err_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 */ -/* bdfdrivr.c - - FreeType font driver for bdf files - - Copyright (C) 2001-2008, 2011 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. -*/ -/* 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. -*/ -#define __BDFDRIVR_H__ -FT_BEGIN_HEADER - 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; -/* a single charmap per face */ - FT_CharMapRec charmap; - FT_UInt default_glyph; - } BDF_FaceRec, *BDF_Face; - FT_EXPORT_VAR( const FT_Driver_ClassRec ) bdf_driver_class; -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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; -/* ftobjs.h: FT_CMap->clazz->size */ - FT_ULong num_encodings; - 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 BDF_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; -/* num_encodings */ - FT_ULong min, max, mid; -/* encodings->glyph */ - FT_UShort 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 ) - { -/* 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; -/* num_encodings */ - FT_ULong min, max, mid; -/* encodings->glyph */ - FT_UShort result = 0; - FT_ULong charcode = *acharcode + 1; - min = 0; - max = cmap->num_encodings; - while ( min < max ) - { -/* same as BDF_encoding_el.enc */ - 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; - 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 = BDF_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 */ - BDF_Face_Done( FT_Face bdfface ) - { - 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, -/* BDF_Face */ - FT_Face bdfface, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error = BDF_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; -/* FZ XXX: options semantics */ - options.correct_metrics = 1; - options.keep_unencoded = 1; - options.keep_comments = 0; - options.font_spacing = BDF_PROPORTIONAL; - error = bdf_load_font( stream, memory, &options, &font ); - if ( error == BDF_Err_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 BDF_Err_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 BDF_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 = BDF_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 = BDF_Err_Ok; - break; - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - if ( height == ( bdffont->font_ascent + - bdffont->font_descent ) ) - error = BDF_Err_Ok; - break; - default: - error = BDF_Err_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 = BDF_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 = BDF_Err_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 )); -/* same as FT_Bitmap.pitch */ - bitmap->pitch = (int)glyph.bpr; -/* 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 BDF_Err_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, -/* FT_Module_Constructor */ - 0, -/* FT_Module_Destructor */ - 0, - bdf_driver_requester - }, - sizeof ( BDF_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - BDF_Face_Init, - BDF_Face_Done, -/* FT_Size_InitFunc */ - 0, -/* FT_Size_DoneFunc */ - 0, -/* FT_Slot_InitFunc */ - 0, -/* FT_Slot_DoneFunc */ - 0, - BDF_Glyph_Load, -/* FT_Face_GetKerningFunc */ - 0, -/* FT_Face_AttachFunc */ - 0, -/* FT_Face_GetAdvancesFunc */ - 0, - BDF_Size_Request, - BDF_Size_Select - }; -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* cff.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define FT_MAKE_OPTION_SINGLE_OBJECT -/***************************************************************************/ -/* */ -/* cffpic.c */ -/* */ -/* The FreeType position independent code services for cff module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CFFCMAP_H__ -/***************************************************************************/ -/* */ -/* cffobjs.h */ -/* */ -/* OpenType objects manager (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 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. */ -/* */ -/***************************************************************************/ -#define __CFFOBJS_H__ -/***************************************************************************/ -/* */ -/* cfftypes.h */ -/* */ -/* Basic OpenType/CFF type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2003, 2006-2008, 2010-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 __CFFTYPES_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; -/* avoid dynamic allocations */ - FT_UShort sids [256]; - FT_UShort codes[256]; - } CFF_EncodingRec, *CFF_Encoding; - typedef struct CFF_CharsetRec_ - { - FT_UInt format; - FT_ULong offset; - FT_UShort* sids; -/* the inverse mapping of `sids'; only needed */ - FT_UShort* cids; -/* 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; -/* temporarily used as scaling value also */ - FT_ULong units_per_em; - 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; -/* array of pointers into Local Subrs INDEX data */ - FT_Byte** local_subrs; - } 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 */ -/* font info dictionary */ - PS_FontInfoRec* font_info; -/* since version 2.3.6 */ - FT_String* registry; - FT_String* ordering; - } CFF_FontRec, *CFF_Font; -FT_END_HEADER -/* END */ -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; -/* 0xFFFFFFFF to indicate invalid */ - FT_ULong strike_index; - } 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_ - { -/* transformation matrix coefficients */ - FT_Fixed xx, xy; - FT_Fixed yx, yy; -/* offsets */ - FT_F26Dot6 ox, oy; - } CFF_Transform; -/***********************************************************************/ -/* */ -/* TrueType driver class. */ -/* */ - typedef struct CFF_DriverRec_ - { - FT_DriverRec root; - void* extension_component; - } CFF_DriverRec; - FT_LOCAL( FT_Error ) -/* CFF_Size */ - cff_size_init( FT_Size size ); - FT_LOCAL( void ) -/* CFF_Size */ - cff_size_done( FT_Size size ); - FT_LOCAL( FT_Error ) - cff_size_request( FT_Size size, - FT_Size_Request req ); - FT_LOCAL( FT_Error ) - cff_size_select( FT_Size size, - FT_ULong strike_index ); - 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, -/* CFF_Face */ - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - FT_LOCAL( void ) -/* CFF_Face */ - cff_face_done( FT_Face face ); -/*************************************************************************/ -/* */ -/* Driver functions */ -/* */ - FT_LOCAL( FT_Error ) - cff_driver_init( FT_Module module ); - FT_LOCAL( void ) - cff_driver_done( FT_Module module ); -FT_END_HEADER -/* END */ -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; -/* up to 256 elements */ - FT_UShort* gids; - } 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 -/* END */ -/***************************************************************************/ -/* */ -/* cffpic.h */ -/* */ -/* The FreeType position independent code services for cff 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. */ -/* */ -/***************************************************************************/ -#define __CFFPIC_H__ -FT_BEGIN_HEADER -#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_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 -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __CFFERRS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX CFF_Err_ -#define FT_ERR_BASE FT_Mod_Err_CFF -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* cffdrivr.c */ -/* */ -/* OpenType font driver implementation (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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__ -FT_BEGIN_HEADER - FT_DECLARE_DRIVER( cff_driver_class ) -FT_END_HEADER -/* __CFFDRIVER_H__ */ -#endif -/* END */ -/***************************************************************************/ -/* */ -/* cffgload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CFFGLOAD_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; -/* bounding box */ - FT_BBox bbox; - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - FT_Bool metrics_only; -/* hinter-specific */ - void* hints_funcs; -/* hinter-specific */ - void* hints_globals; - } CFF_Builder; -/* 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; -/* for pure CFF fonts only */ - FT_Byte** glyph_names; -/* number of glyphs in font */ - FT_UInt num_glyphs; - FT_Render_Mode hint_mode; - FT_Bool seac; - } 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 ); -/* unused until we support pure CFF fonts */ -#if 0 -/* 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 ); -/* 0 */ -#endif - FT_LOCAL( FT_Error ) - cff_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ); - FT_LOCAL( FT_Error ) - cff_slot_load( CFF_GlyphSlot glyph, - CFF_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CFFLOAD_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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__ -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, -/* do not remove */ - cff_kind_max - }; -/* 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; - } CFF_Field_Handler; -FT_END_HEADER -/* __CFF_PARSE_H__ */ -#endif -/* END */ -/*************************************************************************/ -/* */ -/* 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 ) -/* TT_Face */ - cff_get_kerning( FT_Face ttface, - 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 CFF_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_GlyphSlot */ - cff_glyph_load( FT_GlyphSlot cffslot, -/* CFF_Size */ - FT_Size cffsize, - 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 CFF_Err_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 CFF_Err_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 = CFF_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 = CFF_Err_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 = CFF_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 = CFF_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, -/* unsupported with CFF fonts */ - (PS_GetFontPrivateFunc)NULL, -/* not implemented */ - (PS_GetFontValueFunc) NULL - ) -/* - * 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 = CFF_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 = CFF_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 = CFF_Err_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 = CFF_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 = CFF_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 = CFF_Err_Invalid_Argument; - goto Fail; - } - if ( glyph_index > cff->num_glyphs ) - { - error = CFF_Err_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 - ) -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/**** ****/ -/**** ****/ -/**** D R I V E R I N T E R F A C E ****/ -/**** ****/ -/**** ****/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - 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_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 - ) -#else - FT_DEFINE_SERVICEDESCREC5(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 - ) -#endif - FT_CALLBACK_DEF( FT_Module_Interface ) -/* CFF_Driver */ - cff_get_interface( FT_Module driver, - const char* module_interface ) - { - FT_Library library; - FT_Module sfnt; - FT_Module_Interface result; -/* CFF_SERVICES_GET derefers `library' in PIC mode */ - result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); - if ( result != NULL ) - return result; -/* `driver' is not yet evaluated in non-PIC mode */ - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -/* 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. */ -#define CFF_SIZE_SELECT cff_size_select - 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, -/* module-specific interface */ - 0, - 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, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - ft_stub_set_char_sizes, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - ft_stub_set_pixel_sizes, - cff_glyph_load, - cff_get_kerning, -/* FT_Face_AttachFunc */ - 0, - cff_get_advances, - cff_size_request, - CFF_SIZE_SELECT - ) -/* END */ -/***************************************************************************/ -/* */ -/* cffparse.c */ -/* */ -/* CFF token stream parser (body) */ -/* */ -/* Copyright 1996-2004, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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_Int)p[0] << 8 ) | p[1] ); - p += 2; - } - else if ( v == 29 ) - { - if ( p + 4 > limit ) - goto Bad; - val = ( (FT_Long)p[0] << 24 ) | - ( (FT_Long)p[1] << 16 ) | - ( (FT_Long)p[2] << 8 ) | - 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 = 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 = 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 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 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 = CFF_Err_Stack_Underflow; - if ( parser->top >= parser->stack + 6 ) - { - FT_Long scaling; - error = CFF_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 = CFF_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 = CFF_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 = CFF_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 = CFF_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 = CFF_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 = CFF_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 -#undef CFF_FIELD -#undef CFF_FIELD_DELTA -#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[] = - { -/***************************************************************************/ -/* */ -/* 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 */ - { 0, 0, 0, 0, 0, 0, 0 } - }; - FT_LOCAL_DEF( FT_Error ) - cff_parser_run( CFF_Parser parser, - FT_Byte* start, - FT_Byte* limit ) - { - FT_Byte* p = start; - FT_Error error = CFF_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; -/* 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; -/* for 64-bit systems */ - default: - *(FT_Long*)q = val; - } - 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; -/* for 64-bit systems */ - default: - *(FT_Long*)q = val; - } - FT_TRACE4(( " %ld", val )); - q += field->size; - num_args--; - } - FT_TRACE4(( "]\n" )); - } - break; -/* callback */ - default: - 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 = CFF_Err_Invalid_Argument; - goto Exit; - Stack_Underflow: - error = CFF_Err_Invalid_Argument; - goto Exit; - Syntax_Error: - error = CFF_Err_Invalid_Argument; - goto Exit; - } -/* END */ -/***************************************************************************/ -/* */ -/* cffload.c */ -/* */ -/* OpenType and CFF data/program tables loader (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -#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 - }; -/* 1 */ -#endif - 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 = CFF_Err_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 = CFF_Err_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 = CFF_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 = CFF_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 = CFF_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 ); - } - } -/* use offsets table */ - else - { - 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 = CFF_Err_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; -/* clear cache */ - fdselect->cache_count = 0; - switch ( format ) - { -/* format 0, that's simple */ - case 0: - fdselect->data_size = num_glyphs; - goto Load_Data; -/* format 3, a tad more complex */ - case 3: - 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; -/* hmm... that's wrong */ - default: - error = CFF_Err_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 = CFF_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 = CFF_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 = CFF_Err_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. */ -/* record charset type */ - charset->offset = offset; - 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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 = CFF_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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 = CFF_Err_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 ); - } -/* END */ -/***************************************************************************/ -/* */ -/* cffobjs.c */ -/* */ -/* OpenType objects manager (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/*************************************************************************/ -/* */ -/* 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 */ - cff_size_done( FT_Size cffsize ) - { - 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 */ - cff_size_init( FT_Size cffsize ) - { - CFF_Size size = (CFF_Size)cffsize; - FT_Error error = CFF_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; - } - 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 CFF_Err_Ok; - } - 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; - 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 ); - } - 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 CFF_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 CFF_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 = 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 = strlen( family_name ); - style_name_length = 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, -/* CFF_Face */ - FT_Face cffface, - 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 = CFF_Err_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 ) - { -/* `OTTO'; OpenType/CFF font */ - if ( face->format_tag != TTAG_OTTO ) - { - FT_TRACE2(( " not an OpenType/CFF font\n" )); - error = CFF_Err_Unknown_File_Format; - goto Exit; - } -/* if we are performing a simple font format check, exit immediately */ - if ( face_index < 0 ) - return CFF_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 = CFF_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 = CFF_Err_Missing_Module; - goto Exit; - } - 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. */ -/* */ -/* scalable outlines */ - flags = FT_FACE_FLAG_SCALABLE | -/* horizontal data */ - FT_FACE_FLAG_HORIZONTAL | -/* has native hinter */ - FT_FACE_FLAG_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 ) -/* Apple Unicode */ - goto Skip_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_No_Unicode_Glyph_Name != error ) - 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; -/* Adobe platform id */ - cmaprec.platform_id = TT_PLATFORM_ADOBE; - 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 */ - cff_face_done( FT_Face cffface ) - { - 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 ) - { - FT_UNUSED( module ); - return CFF_Err_Ok; - } - FT_LOCAL_DEF( void ) - cff_driver_done( FT_Module module ) - { - FT_UNUSED( module ); - } -/* END */ -/***************************************************************************/ -/* */ -/* cffgload.c */ -/* */ -/* OpenType Glyph Loader (body). */ -/* */ -/* Copyright 1996-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 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 - 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, -/* deprecated, acts as no-op */ - cff_op_dotsection, - 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[] = - { -/* unknown */ - 0, -/* rmoveto */ - 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, - 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, - 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, -/* 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, - 0 | CFF_COUNT_CLEAR_STACK, -/* flex */ - 13, - 7, - 9, - 11, -/* endchar */ - 0 | CFF_COUNT_CHECK_WIDTH, -/* hstem */ - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, -/* hintmask */ - 0 | CFF_COUNT_CHECK_WIDTH, -/* cntrmask */ - 0 | CFF_COUNT_CHECK_WIDTH, -/* dotsection */ - 0, -/* abs */ - 1, - 2, - 2, - 2, - 1, - 0, - 2, - 1, -/* blend */ - 1, -/* drop */ - 1, - 2, - 1, - 2, - 1, -/* put */ - 2, - 1, - 4, - 3, -/* and */ - 2, - 2, - 1, - 2, - 4, -/* callsubr */ - 1, - 1, - 0, -/* hsbw */ - 2, - 0, - 0, - 0, -/* seac */ - 5, -/* sbw */ - 4, -/* setcurrentpoint */ - 2 - }; -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/********** *********/ -/********** *********/ -/********** 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 = CFF_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 = CFF_Err_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]; - } - } - 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; - Exit: - return error; - } -/* check that there is enough space for `count' more points */ - static FT_Error - 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 */ - static 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; - point->x = x >> 16; - point->y = y >> 16; - *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 */ - static FT_Error - cff_builder_add_point1( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - error = 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 CFF_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 */ - static FT_Error - cff_builder_start_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error = CFF_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 */ - static 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 ); - } - } - static 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; - } - static FT_Error - cff_get_glyph_data( TT_Face face, - FT_UInt glyph_index, - FT_Byte** pointer, - FT_ULong* length ) - { -/* 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 - { - CFF_Font cff = (CFF_Font)(face->extra.data); - return cff_index_access_element( &cff->charstrings_index, glyph_index, - pointer, length ); - } - } - static void - cff_free_glyph_data( TT_Face face, - FT_Byte** pointer, - FT_ULong length ) - { -/* 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 - { - CFF_Font cff = (CFF_Font)(face->extra.data); - cff_index_forget_element( &cff->charstrings_index, pointer ); - } - } - 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 CFF_Err_Syntax_Error; - } - adx += decoder->builder.left_bearing.x; - ady += decoder->builder.left_bearing.y; -/* 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 - { - 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 CFF_Err_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 = CFF_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 ( v == 28 ) - { - if ( ip + 1 >= limit ) - goto Syntax_Error; - val = (FT_Short)( ( (FT_Short)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)ip[0] << 24 ) | - ( (FT_Int32)ip[1] << 16 ) | - ( (FT_Int32)ip[2] << 8 ) | - ip[3]; - ip += 4; - if ( charstring_type == 2 ) - shift = 0; - } - if ( decoder->top - stack >= CFF_MAX_OPERANDS ) - goto Stack_Overflow; - val <<= shift; - *decoder->top++ = val; - } - 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; -/* this is actually the Type1 vstem3 operator */ - case 1: - op = cff_op_vstem; - break; -/* this is actually the Type1 hstem3 operator */ - case 2: - 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 ); - } - ip += ( decoder->num_hints + 7 ) >> 3; - 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 ) || - 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 ) || - 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 ) || - 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 ( 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 ( 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 ( 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 ) || - 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 ) || - 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 ) || - 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 ) || - 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: - { -/* record start x, y values for */ - FT_Pos start_x, start_y; -/* alter use */ -/* used in horizontal/vertical */ - FT_Fixed dx = 0, dy = 0; -/* 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 ) || - 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 ) || - 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 = CFF_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; - } -/* save current instruction pointer */ - zone->cursor = ip; - 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; - } -/* save current instruction pointer */ - zone->cursor = ip; - 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 CFF_Err_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 CFF_Err_Invalid_File_Format; - Stack_Underflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); - return CFF_Err_Too_Few_Arguments; - Stack_Overflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); - return CFF_Err_Stack_Overflow; - } -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/********** *********/ -/********** *********/ -/********** 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. *********/ -/********** *********/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/* unused until we support pure CFF fonts */ -#if 0 - FT_LOCAL_DEF( FT_Error ) - cff_compute_max_advance( TT_Face face, - FT_Int* max_advance ) - { - FT_Error error = CFF_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 = CFF_Err_Ok; - } - *max_advance = decoder.builder.advance.x; - return CFF_Err_Ok; - } -/* 0 */ -#endif - 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, 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 CFF_Err_Invalid_Argument; - } - } - else if ( glyph_index >= cff->num_glyphs ) - return CFF_Err_Invalid_Argument; - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - 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; - } -/* 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 ) - { - 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; - } - return error; - } - } - } -/* return immediately if we only want the embedded bitmaps */ - if ( load_flags & FT_LOAD_SBITS_ONLY ) - return CFF_Err_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; - hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); -/* by default */ - glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; - { - 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; - error = cff_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); - cff_free_glyph_data( face, &charstring, charstring_len ); - if ( error ) - goto Glyph_Build_Finished; -/* 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 -/* 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? */ - } -/* 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; - } - 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 */ -/***************************************************************************/ -/* */ -/* cffcmap.c */ -/* */ -/* CFF character mapping table (cmap) support (body). */ -/* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 CFF_Err_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 */ -/* END */ -/***************************************************************************/ -/* */ -/* sfnt.c */ -/* */ -/* Single object library component. */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.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 -/***************************************************************************/ -/* */ -/* sfntpic.c */ -/* */ -/* The FreeType position independent code services for sfnt module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SFNTPIC_H__ -FT_BEGIN_HEADER -#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 -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* sferrors.h */ -/* */ -/* SFNT error codes (specification only). */ -/* */ -/* Copyright 2001, 2004, 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 SFNT error enumeration constants. */ -/* */ -/*************************************************************************/ -#define __SFERRORS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX SFNT_Err_ -#define FT_ERR_BASE FT_Mod_Err_SFNT -#define FT_KEEP_ERR_PREFIX -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* ttload.c */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTLOAD_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 ); - FT_LOCAL( FT_Error ) - tt_face_load_bhed( TT_Face face, - FT_Stream stream ); -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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; - 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; - } - } - } - 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 = SFNT_Err_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; - 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 = SFNT_Err_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 = SFNT_Err_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 = SFNT_Err_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 = SFNT_Err_Ok; - goto Exit; - } - else - { - FT_TRACE2(( "check_table_dir:" )); - FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); - error = SFNT_Err_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 SFNT_Err_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 = SFNT_Err_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 SFNT_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 ); - } - 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 ); - } -/*************************************************************************/ -/* */ -/* <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 = SFNT_Err_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 SFNT_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 = SFNT_Err_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 */ -/***************************************************************************/ -/* */ -/* ttmtx.c */ -/* */ -/* Load the metrics tables common to TTF and OTF fonts (body). */ -/* */ -/* Copyright 2006-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTMTX_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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 -/* - * Unfortunately, we can't enable our memory optimizations if - * FT_CONFIG_OPTION_OLD_INTERNALS is defined. This is because at least - * one rogue client (libXfont in the X.Org XServer) is directly accessing - * the metrics. - */ -/*************************************************************************/ -/* */ -/* <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 SFNT_Err_Ok; - } -/* END */ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* Copyright 2002-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. */ -/* */ -/***************************************************************************/ -/* must come before FT_INTERNAL_VALIDATE_H */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTCMAP_H__ -FT_BEGIN_HEADER -#define TT_CMAP_FLAG_UNSORTED 1 -#define TT_CMAP_FLAG_OVERLAPPING 2 - typedef struct TT_CMapRec_ - { - FT_CMapRec cmap; -/* pointer to in-memory cmap table */ - FT_Byte* data; -/* for format 4 only */ - FT_Int flags; - } 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; -#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_ \ - }; - 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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 SFNT_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 */ -/* */ - 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 SFNT_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; -/* go to glyph IDs */ - table += 6; - 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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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). */ -/* */ - FT_CALLBACK_DEF( FT_Error ) - tt_cmap2_validate( FT_Byte* table, - FT_Validator valid ) - { -/* skip format */ - FT_Byte* p = table + 2; - FT_UInt length = TT_PEEK_USHORT( p ); - FT_UInt n, max_subs; -/* keys table */ - FT_Byte* keys; -/* sub-headers */ - FT_Byte* subs; -/* glyph ID array */ - FT_Byte* glyph_ids; - 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 SFNT_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 ); -/* keys table */ - FT_Byte* p = table + 6; -/* subheaders table */ - FT_Byte* subs = table + 518; - 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 */ -/* */ -/* jump to first sub-header */ - sub = subs; -/* 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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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. */ -/* */ - typedef struct TT_CMap4Rec_ - { - TT_CMapRec cmap; -/* current charcode */ - FT_UInt32 cur_charcode; -/* current glyph index */ - FT_UInt cur_gindex; - 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 SFNT_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 ) - { -/* skip format */ - FT_Byte* p = table + 2; - FT_UInt length = TT_NEXT_USHORT( p ); - FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; - FT_UInt num_segs; - FT_Error error = SFNT_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; -/* read segCountX2 */ - num_segs = TT_NEXT_USHORT( p ); - 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 ); -/* must be even values */ - if ( ( search_range | range_shift ) & 1 ) - 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 ) - { -/* start of glyph ID array */ - p += offset; -/* 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; -/* ends table */ - p = cmap->data + 14; -/* starts table */ - q = cmap->data + 16 + num_segs2; - 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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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. */ -/* */ - 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 ); -/* skip language and start index */ - p = table + 8; - 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 SFNT_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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 */ -/* */ - 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; -/* skip `is32' array */ - p = is32 + 8192; - 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 SFNT_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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 */ -/* */ - 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 SFNT_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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 */ -/* */ - 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 SFNT_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 SFNT_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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 */ -/* */ - 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 SFNT_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 SFNT_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 SFNT_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 ) -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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'. */ - 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 = SFNT_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 SFNT_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 ); -/* end of Unicode */ - if ( base + cnt >= 0x110000UL ) - 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 ); -/* end of Unicode */ - if ( uni >= 0x110000UL ) - 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 SFNT_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 SFNT_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; -/* point to the first `cnt' field */ - p += 3; - 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 ) - static const TT_CMap_Class tt_cmap_classes[] = - { -#define TTCMAPCITEM( a ) &a, -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - TTCMAPCITEM( tt_cmap0_class_rec ) - TTCMAPCITEM( tt_cmap2_class_rec ) - TTCMAPCITEM( tt_cmap4_class_rec ) - TTCMAPCITEM( tt_cmap6_class_rec ) - TTCMAPCITEM( tt_cmap8_class_rec ) - TTCMAPCITEM( tt_cmap10_class_rec ) - TTCMAPCITEM( tt_cmap12_class_rec ) - TTCMAPCITEM( tt_cmap13_class_rec ) - TTCMAPCITEM( tt_cmap14_class_rec ) -/* END */ - NULL, - }; -/* 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 SFNT_Err_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 SFNT_Err_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 ); -/* will be filled later */ - charmap.encoding = FT_ENCODING_NONE; - 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 = SFNT_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 SFNT_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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTKERN_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 -/* END */ -/*************************************************************************/ -/* */ -/* 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; -/* the case of a malformed table */ - if ( table_size < 4 ) - { - FT_ERROR(( "tt_face_load_kern:" - " kerning table is too small - ignored\n" )); - error = SFNT_Err_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; -/* skip version */ - p += 2; - num_tables = FT_NEXT_USHORT( p ); -/* we only support up to 32 sub-tables */ - if ( num_tables > 32 ) - 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; -/* skip version */ - p += 2; - length = FT_NEXT_USHORT( p ); - coverage = FT_NEXT_USHORT( p ); - if ( length <= 6 ) - break; - p_next += length; -/* handle broken table */ - if ( p_next > p_limit ) - 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; -/* handle broken count */ - if ( ( p_next - p ) < 6 * (int)num_pairs ) - 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; -/* handle broken table */ - if ( next > p_limit ) - 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; -/* handle broken count */ - if ( ( next - p ) < 6 * (int)num_pairs ) - num_pairs = (FT_UInt)( ( next - p ) / 6 ); - switch ( coverage >> 8 ) - { - case 0: - { - FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); -/* binary search */ - if ( face->kern_order_bits & mask ) - { - 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; - } - } -/* linear search */ - else - { - 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: -/* override or add */ - if ( coverage & 8 ) - result = value; - else - result += value; - NextTable: - p = next; - } - return result; - } -#undef TT_KERN_INDEX -/* END */ -/***************************************************************************/ -/* */ -/* sfobjs.c */ -/* */ -/* SFNT object management (base). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SFOBJS_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTBDF_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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 = SFNT_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 ), -/* this is ULong in the specs */ - FT_FRAME_LONG( count ), - 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 SFNT_Err_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 SFNT_Err_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 SFNT_Err_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 SFNT_Err_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 SFNT_Err_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" \ - : ( error == SFNT_Err_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" \ - : ( error == SFNT_Err_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; - FT_Error psnames_error; - 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? */ - 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 ); - 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 = SFNT_Err_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 ); - psnames_error = error; -/* 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 ( error == SFNT_Err_Table_Missing ) - { - error = SFNT_Err_Hmtx_Table_Missing; -/* 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 = SFNT_Err_Ok; - } - } - } - else if ( error == SFNT_Err_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 = SFNT_Err_Ok; - } - else - { - error = SFNT_Err_Horiz_Header_Missing; -/* 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 = SFNT_Err_Ok; - } - } - } - 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 && error != SFNT_Err_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 ( error == SFNT_Err_Table_Missing ) - error = SFNT_Err_Ok; - else - goto Exit; - } - } - LOAD_( pclt ); - if ( error ) - { - if ( error != SFNT_Err_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 ) -/* scalable outlines */ - flags |= FT_FACE_FLAG_SCALABLE; -/* The sfnt driver only supports bitmap fonts natively, thus we */ -/* don't set FT_FACE_FLAG_HINTER. */ -/* SFNT file format */ - flags |= FT_FACE_FLAG_SFNT | -/* horizontal data */ - FT_FACE_FLAG_HORIZONTAL; - if ( psnames_error == SFNT_Err_Ok && - face->postscript.FormatType != 0x00030000L ) - flags |= FT_FACE_FLAG_GLYPH_NAMES; -/* 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; -/* 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; - 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. */ -/* bit 9 */ - if ( face->os2.fsSelection & 512 ) - flags |= FT_STYLE_FLAG_ITALIC; -/* bit 0 */ - else if ( face->os2.fsSelection & 1 ) - flags |= FT_STYLE_FLAG_ITALIC; -/* bit 5 */ - if ( face->os2.fsSelection & 32 ) - 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. */ -/* */ -/* ignore errors */ - tt_face_build_cmaps( face ); -/* 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 - } - } -/* - * 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; - } - } -/* 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 ); - } -/* freeing the embedded BDF properties */ - tt_face_free_bdf_props( face ); -/* 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 */ -/***************************************************************************/ -/* */ -/* sfdriver.c */ -/* */ -/* High-level SFNT driver interface (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __SFDRIVER_H__ -FT_BEGIN_HEADER - FT_DECLARE_MODULE( sfnt_module_class ) -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* ttsbit.h */ -/* */ -/* TrueType and OpenType embedded bitmap support (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 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. */ -/* */ -/***************************************************************************/ -#define __TTSBIT_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTPOST_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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 SFNT_Err_Invalid_Argument; - if ( !tag ) - *length = face->num_tables; - else - { - if ( idx >= face->num_tables ) - return SFNT_Err_Table_Missing; - *tag = face->dir_tables[idx].Tag; - *offset = face->dir_tables[idx].Offset; - *length = face->dir_tables[idx].Length; - } - return SFNT_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 ) -/* - * 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 ) -/* - * 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 = SFNT_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 = SFNT_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 ) - 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 = SFNT_Err_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 ) -/* - * SERVICE LIST - */ - 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 ) - FT_CALLBACK_DEF( FT_Module_Interface ) - sfnt_get_interface( FT_Module module, - const char* module_interface ) - { -/* SFNT_SERVICES_GET derefers `library' in PIC mode */ - FT_UNUSED( module ); - return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface ); - } -#define PUT_EMBEDDED_BITMAPS( a ) a -#define PUT_PS_NAMES( a ) a - 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, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_load_sfnt_header_stub, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_load_directory_stub, - 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, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_load_hdmx_stub, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_free_hdmx_stub, - tt_face_load_kern, - tt_face_load_gasp, - tt_face_load_pclt, -/* see `ttload.h' */ - PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_set_sbit_strike_stub, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_load_sbit_stub, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_find_sbit_image, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_load_sbit_metrics, - PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_free_sbit_stub, -/* see `ttpost.h' */ - PUT_PS_NAMES( tt_face_get_ps_name ), - PUT_PS_NAMES( tt_face_free_ps_names ), -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_load_charmap_stub, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_face_free_charmap_stub, -/* 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, -/* not a font driver or renderer */ - 0, - sizeof ( FT_ModuleRec ), -/* driver name */ - "sfnt", -/* driver version 1.0 */ - 0x10000L, -/* driver requires FreeType 2.0 or higher */ - 0x20000L, -/* module specific interface */ - (const void*)&SFNT_INTERFACE_GET, - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) sfnt_get_interface ) -/* END */ -/***************************************************************************/ -/* */ -/* ttsbit.c */ -/* */ -/* TrueType and OpenType embedded bitmap support (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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. */ -/* */ -/***************************************************************************/ -/* - * Alas, the memory-optimized sbit loader can't be used when implementing - * the `old internals' hack - */ -/***************************************************************************/ -/* */ -/* ttsbit0.c */ -/* */ -/* TrueType and OpenType embedded bitmap support (body). */ -/* This is a heap-optimized version. */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -/* This file is included by ttsbit.c */ -/*************************************************************************/ -/* */ -/* 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 = SFNT_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_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 = SFNT_Err_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 = SFNT_Err_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 SFNT_Err_Invalid_Argument; - strike = face->sbit_table + 8 + strike_index * 48; - metrics->x_ppem = (FT_UShort)strike[44]; - metrics->y_ppem = (FT_UShort)strike[45]; -/* hori.ascender */ - metrics->ascender = (FT_Char)strike[16] << 6; -/* hori.descender */ - metrics->descender = (FT_Char)strike[17] << 6; - metrics->height = metrics->ascender - metrics->descender; -/* XXX: Is this correct? */ -/* min_origin_SB */ - metrics->max_advance = ( (FT_Char)strike[22] + -/* max_width */ - strike[18] + -/* min_advance_SB */ - (FT_Char)strike[23] - ) << 6; - return SFNT_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_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 = SFNT_Err_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 = SFNT_Err_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_Error error = SFNT_Err_Ok; - FT_UInt width, height; - FT_Bitmap* map = decoder->bitmap; - FT_Long size; - if ( !decoder->metrics_loaded ) - { - error = SFNT_Err_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; - break; - case 2: - map->pixel_mode = FT_PIXEL_MODE_GRAY2; - map->pitch = ( map->width + 3 ) >> 2; - break; - case 4: - map->pixel_mode = FT_PIXEL_MODE_GRAY4; - map->pitch = ( map->width + 1 ) >> 1; - break; - case 8: - map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; - break; - default: - error = SFNT_Err_Invalid_File_Format; - goto Exit; - } - size = map->rows * map->pitch; -/* check that there is no empty image */ - if ( size == 0 ) -/* exit successfully! */ - goto Exit; - 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 SFNT_Err_Ok; - Fail: - return SFNT_Err_Invalid_Argument; - } -/* forward declaration */ - static FT_Error - tt_sbit_decoder_load_image( TT_SBitDecoder decoder, - FT_UInt glyph_index, - 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 ); - static FT_Error - tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = SFNT_Err_Ok; - FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, h; - FT_Bitmap* bitmap; - if ( !decoder->bitmap_allocated ) - { - error = tt_sbit_decoder_alloc_bitmap( decoder ); - if ( error ) - goto Exit; - } -/* 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; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) - { - error = SFNT_Err_Invalid_File_Format; - goto Exit; - } - if ( p + ( ( width + 7 ) >> 3 ) * height > limit ) - { - error = SFNT_Err_Invalid_File_Format; - goto Exit; - } -/* now do the blit */ - line += y_pos * pitch + ( x_pos >> 3 ); - x_pos &= 7; -/* the easy one */ - if ( x_pos == 0 ) - { - for ( h = height; h > 0; h--, line += pitch ) - { - FT_Byte* write = line; - FT_Int w; - for ( w = width; w >= 8; w -= 8 ) - { - write[0] = (FT_Byte)( write[0] | *p++ ); - write += 1; - } - if ( w > 0 ) - write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) ); - } - } -/* x_pos > 0 */ - else - { - for ( h = height; h > 0; h--, line += pitch ) - { - FT_Byte* write = line; - FT_Int w; - FT_UInt wval = 0; - for ( w = width; w >= 8; w -= 8 ) - { - wval = (FT_UInt)( wval | *p++ ); - write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); - write += 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 */ - write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); - if ( x_pos + w > 8 ) - { - write++; - wval <<= 8; - write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); - } - } - } - Exit: - return error; - } -/* - * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap - * (with pointer `write'). 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 | . - * | | . - * write . . - * . . - * v . - * +-------+ . - * | | - * | 7 6 5 4 3 2 1 0 | - * | | - * write+1 . - * . - * v - * +-------+ - * | | - * | 7 6 5 4 3 2 1 0 | - * | | - * write+2 - * - */ - static FT_Error - tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = SFNT_Err_Ok; - FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, h, nbits; - FT_Bitmap* bitmap; - FT_UShort rval; - if ( !decoder->bitmap_allocated ) - { - error = tt_sbit_decoder_alloc_bitmap( decoder ); - if ( error ) - goto Exit; - } -/* 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; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) - { - error = SFNT_Err_Invalid_File_Format; - goto Exit; - } - if ( p + ( ( width * height + 7 ) >> 3 ) > limit ) - { - error = SFNT_Err_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* write = line; - FT_Int w = width; -/* handle initial byte (in target bitmap) specially if necessary */ - if ( x_pos ) - { - w = ( width < 8 - x_pos ) ? width : 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; - } - *write++ |= ( ( rval >> nbits ) & 0xFF ) & - ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); - rval <<= 8; - w = width - w; - } -/* handle medial bytes */ - for ( ; w >= 8; w -= 8 ) - { - rval |= *p++; - *write++ |= ( rval >> nbits ) & 0xFF; - rval <<= 8; - } -/* handle final byte if necessary */ - if ( w > 0 ) - { - if ( nbits < w ) - { - if ( p < limit ) - rval |= *p++; - *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); - nbits += 8 - w; - rval <<= 8; - } - else - { - *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); - nbits -= w; - } - } - } - Exit: - return error; - } - static FT_Error - tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, - FT_Byte* p, - FT_Byte* limit, - FT_Int x_pos, - FT_Int y_pos ) - { - FT_Error error = SFNT_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 ) - goto Fail; - if ( !decoder->bitmap_allocated ) - { - error = tt_sbit_decoder_alloc_bitmap( decoder ); - if ( error ) - goto Exit; - } - 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, gindex, - x_pos + dx, y_pos + dy ); - if ( error ) - break; - } - 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_UInt)decoder->bitmap->width; - decoder->metrics->height = (FT_UInt)decoder->bitmap->rows; - Exit: - return error; - Fail: - error = SFNT_Err_Invalid_File_Format; - goto Exit; - } - static FT_Error - tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, - 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 = SFNT_Err_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: - error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); - break; - case 6: - case 7: - case 9: - error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); - break; - default: - error = SFNT_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; -/* skip padding */ - p += 1; -/* fall-through */ - case 9: - loader = tt_sbit_decoder_load_compound; - break; - default: - goto Fail; - } - error = loader( decoder, 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 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; -/* ignore index offset */ - p += 4; - } - goto NoBitmap; - FoundRange: - image_offset = FT_NEXT_ULONG( p ); -/* overflow check */ - if ( decoder->eblc_base + decoder->strike_index_array + image_offset < - decoder->eblc_base ) - goto Failure; - p = decoder->eblc_base + decoder->strike_index_array + 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 ) - { -/* 4-byte offsets relative to `image_offset' */ - case 1: - { - p += 4 * ( glyph_index - start ); - if ( p + 8 > p_limit ) - goto NoBitmap; - image_start = FT_NEXT_ULONG( p ); - image_end = FT_NEXT_ULONG( p ); -/* missing glyph */ - if ( image_start == image_end ) - goto NoBitmap; - } - break; -/* big metrics, constant image size */ - case 2: - { - 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; -/* 2-byte offsets relative to 'image_offset' */ - case 3: - { - p += 2 * ( glyph_index - start ); - if ( p + 4 > p_limit ) - goto NoBitmap; - image_start = FT_NEXT_USHORT( p ); - image_end = FT_NEXT_USHORT( p ); -/* missing glyph */ - if ( image_start == image_end ) - goto NoBitmap; - } - break; -/* sparse glyph array with (glyph,offset) pairs */ - case 4: - { - FT_ULong mm, num_glyphs; - if ( p + 4 > p_limit ) - goto NoBitmap; - num_glyphs = FT_NEXT_ULONG( p ); -/* overflow check */ - if ( p + ( num_glyphs + 1 ) * 4 < p ) - goto Failure; - if ( p + ( num_glyphs + 1 ) * 4 > p_limit ) - 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; -/* constant metrics with sparse glyph codes */ - case 5: - { - 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 */ - if ( p + 2 * num_glyphs < p ) - goto Failure; - if ( p + 2 * num_glyphs > p_limit ) - 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; - return tt_sbit_decoder_load_bitmap( decoder, - image_format, - image_start, - image_end, - x_pos, - y_pos ); - Failure: - return SFNT_Err_Invalid_Table; - NoBitmap: - return SFNT_Err_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, glyph_index, 0, 0 ); - tt_sbit_decoder_done( decoder ); - } - return error; - } -/* EOF */ -/* END */ -/***************************************************************************/ -/* */ -/* ttpost.c */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) - 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 = SFNT_Err_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 SFNT_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 = SFNT_Err_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 = SFNT_Err_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 SFNT_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 = SFNT_Err_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; - FT_Service_PsCMaps psnames; - if ( !face ) - return SFNT_Err_Invalid_Face_Handle; - if ( idx >= (FT_UInt)face->max_profile.numGlyphs ) - return SFNT_Err_Invalid_Glyph_Index; - psnames = (FT_Service_PsCMaps)face->psnames; - if ( !psnames ) - return SFNT_Err_Unimplemented_Feature; - names = &face->postscript_names; -/* `.notdef' by default */ - *PSname = MAC_NAME( 0 ); - format = face->postscript.FormatType; - if ( format == 0x00010000L ) - { -/* paranoid checking */ - if ( idx < 258 ) - *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; - } -/* paranoid checking */ - if ( idx < (FT_UInt)table->num_glyphs ) - { - idx += table->offsets[idx]; - *PSname = MAC_NAME( idx ); - } - } -/* nothing to do for format == 0x00030000L */ - End: - return SFNT_Err_Ok; - } -/* END */ -/***************************************************************************/ -/* */ -/* ttbdf.c */ -/* */ -/* TrueType and OpenType embedded BDF properties (body). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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 = SFNT_Err_Invalid_Table; - goto Exit; - } - bdf->table_end = bdf->table + length; - { - FT_Byte* p = bdf->table; - FT_UInt version = FT_NEXT_USHORT( p ); - FT_UInt num_strikes = FT_NEXT_USHORT( p ); - FT_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 = SFNT_Err_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 = SFNT_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 = SFNT_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 ) - { -/* string */ - case 0x00: -/* atoms */ - case 0x01: -/* 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 = SFNT_Err_Ok; - goto Exit; - } - break; - case 0x02: - aprop->type = BDF_PROPERTY_TYPE_INTEGER; - aprop->u.integer = (FT_Int32)value; - error = SFNT_Err_Ok; - goto Exit; - case 0x03: - aprop->type = BDF_PROPERTY_TYPE_CARDINAL; - aprop->u.cardinal = value; - error = SFNT_Err_Ok; - goto Exit; - default: - ; - } - } - } - p += 10; - } - Exit: - return error; - } -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* pshpic.c */ -/* */ -/* The FreeType position independent code services for pshinter module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* pshpic.h */ -/* */ -/* The FreeType position independent code services for pshinter 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. */ -/* */ -/***************************************************************************/ -#define __PSHPIC_H__ -FT_BEGIN_HEADER -#define PSHINTER_INTERFACE_GET pshinter_interface -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __PSHNTERR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PSH_Err_ -#define FT_ERR_BASE FT_Mod_Err_PShinter -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* pshrec.c */ -/* */ -/* FreeType PostScript hints recorder (body). */ -/* */ -/* Copyright 2001, 2002, 2003, 2004, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/**************************************************************************/ -#define __PSHREC_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSHGLOB_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 -/* END */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* pshalgo.h */ -/* */ -/* PostScript hinting algorithm (specification). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -#define __PSHALGO_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 - { -/* point is off the curve */ - PSH_POINT_OFF = 1, -/* point is smooth */ - PSH_POINT_SMOOTH = 2, -/* point is inflection */ - PSH_POINT_INFLEX = 4 - }; -#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 - { -/* point is strong */ - PSH_POINT_STRONG = 16, -/* point is already fitted */ - PSH_POINT_FITTED = 32, -/* point is local extremum */ - PSH_POINT_EXTREMUM = 64, -/* extremum has positive contour flow */ - PSH_POINT_POSITIVE = 128, -/* extremum has negative contour flow */ - PSH_POINT_NEGATIVE = 256, -/* point is aligned to left/bottom stem edge */ - PSH_POINT_EDGE_MIN = 512, -/* point is aligned to top/right stem edge */ - PSH_POINT_EDGE_MAX = 1024 - }; -#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; - FT_Angle angle_in; - FT_Angle angle_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; -#define PSH_POINT_EQUAL_ORG( a, b ) ( (a)->org_u == (b)->org_u && \ - (a)->org_v == (b)->org_v ) -#define PSH_POINT_ANGLE( a, b ) FT_Atan2( (b)->org_u - (a)->org_u, \ - (b)->org_v - (a)->org_v ) - 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 -/* END */ -#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 = PSH_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 = PSH_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 = PSH_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 = PSH_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 = PSH_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 = PSH_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 = PSH_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 = PSH_Err_Ok; - 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 = ( count1 <= count2 ) ? 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 = PSH_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; -/* number of masks to move */ - delta = 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 ) ); - 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 = PSH_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 = PSH_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; - PS_Mask mask; - if ( count > 0 ) - { - 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 = PSH_Err_Ok; -/* 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 = PSH_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 = PSH_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 = PSH_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 PSH_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 = PSH_Err_Ok; - hints->hint_type = hint_type; - ps_dimension_init( &hints->dimension[0] ); - ps_dimension_init( &hints->dimension[1] ); - break; - default: - hints->error = PSH_Err_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 ) - { -/* Type 1 "hstem" or "vstem" operator */ - case PS_HINT_TYPE_1: -/* Type 2 "hstem" or "vstem" operator */ - case PS_HINT_TYPE_2: - { - 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 = PSH_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 = PSH_Err_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 = PSH_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 = PSH_Err_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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#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; -/* standard width/height */ - PSH_Width stand = width; - 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; - } -/* 0 */ -#endif -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 */ -/***************************************************************************/ -/* */ -/* pshalgo.c */ -/* */ -/* PostScript hinting algorithm (body). */ -/* */ -/* Copyright 2001-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. */ -/* */ -/***************************************************************************/ -#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 -/* compute inflection points to optimize `S' */ -#define COMPUTE_INFLEXS -/* and similar glyphs */ -/* slightly increase the contrast of smooth */ -#define STRONGER -/* 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; - } -/* 0 */ -#endif -#ifdef DEBUG_HINTER - static void - ps_simple_scale( PSH_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta, - FT_Int dimension ) - { - PSH_Hint hint; - FT_UInt count; - for ( count = 0; count < table->max_hints; count++ ) - { - 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 ); - } - } -/* DEBUG_HINTER */ -#endif - 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 - } - } -/* not used for now, experimental */ -#if 0 -/* - * 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. - */ -/* len > 64 */ - else - { - 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 - } - } -/* 0 */ -#endif - 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; - } -/* DEBUG_HINTER*/ -#endif - 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 - 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 ) -/* DEBUG_ZONES */ -#endif -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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; - } -/* general case */ - else - { - 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; - } -/* !1 */ -#endif -#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: - ; - } - } -/* COMPUTE_INFLEXS */ -#endif - 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 = ( dx >= 0 ) ? dx : -dx; - ay = ( dy >= 0 ) ? dy : -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 ); -/* COMPUTE_INFLEXS */ -#endif -/* 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; - } - } -/* before->org_u > point->org_u */ - else - { - 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; - } - } - } - } -/* 1 */ -#endif - } - } -/* 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 ); -/* hint->org_len > 0 */ - else - 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++; - } -/* nothing to do here */ - if ( num_strongs == 0 ) - 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; -/* point before the first strong point */ - if ( nn == 0 ) - { - 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; -/* point is after last strong point */ - if ( nn == num_strongs ) - { - 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 ); -/* 1 */ -#endif - } -/* 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 PSH_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; -/* DEBUG_HINTER */ -#endif - 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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/* 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, -/* module-specific interface */ - &PSHINTER_INTERFACE_GET, - (FT_Module_Constructor)ps_hinter_init, - (FT_Module_Destructor) ps_hinter_done, -/* no additional interface for now */ - (FT_Module_Requester) NULL ) -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* pspic.c */ -/* */ -/* The FreeType position independent code services for psnames module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSPIC_H__ -FT_BEGIN_HEADER -#define PSCMAPS_SERVICES_GET pscmaps_services -#define PSCMAPS_INTERFACE_GET pscmaps_interface -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __PSNAMERR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PSnames_Err_ -#define FT_ERR_BASE FT_Mod_Err_PSnames -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* psmodule.c */ -/* */ -/* PSNames module implementation (body). */ -/* */ -/* Copyright 1996-2003, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSMODULE_H__ -FT_BEGIN_HEADER - FT_DECLARE_MODULE( psnames_module_class ) -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. - */ - 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; - } -/* END */ -#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 = PSnames_Err_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 = PSnames_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 ) -/* remember match but continue search for base glyph */ - result = mid; - 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 ) -/* we have a variant glyph */ - goto Exit; -/* 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; - } - 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]; - } - 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 ) - 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 */ - FT_UNUSED( module ); - return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id ); - } -#define PUT_PS_NAMES_SERVICE( a ) a - FT_DEFINE_MODULE( - psnames_module_class, -/* this is not a font driver, nor a renderer */ - 0, - sizeof ( FT_ModuleRec ), -/* driver name */ - "psnames", -/* driver version */ - 0x10000L, -/* driver requires FreeType 2 or above */ - 0x20000L, - PUT_PS_NAMES_SERVICE( -/* module specific interface */ - (void*)&PSCMAPS_INTERFACE_GET ), - (FT_Module_Constructor)NULL, - (FT_Module_Destructor) NULL, - (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* cidparse.c */ -/* */ -/* CID-keyed Type1 parser (body). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CIDPARSE_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSAUX_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. */ -/* */ -/* 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_ - { -/* current memory block */ - FT_Byte* block; -/* current cursor in memory block */ - FT_Offset cursor; -/* current size of memory block */ - FT_Offset capacity; - FT_Long init; - FT_Int max_elems; - FT_Int num_elems; -/* addresses of table elements */ - FT_Byte** elements; -/* lengths of table elements */ - FT_PtrDist* lengths; - 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, -/* aka `name' */ - T1_TOKEN_TYPE_KEY, -/* do not remove */ - T1_TOKEN_TYPE_MAX - } T1_TokenType; -/* a simple structure used to identify tokens */ - typedef struct T1_TokenRec_ - { -/* first character of token in input stream */ - FT_Byte* start; -/* first character after the token */ - FT_Byte* limit; -/* type of token */ - T1_TokenType type; - } 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_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_ - { -/* field identifier */ - const char* ident; - T1_FieldLocation location; -/* type of field */ - T1_FieldType type; - T1_Field_ParseFunc reader; -/* offset of field in object */ - FT_UInt offset; -/* size of field in bytes */ - FT_Byte size; -/* maximum number of elements for */ - FT_UInt array_max; -/* array */ -/* offset of element count for */ - FT_UInt count_offset; -/* 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 */ -/* where we expect it */ - FT_UInt dict; - } T1_FieldRec; -/* also FontInfo and FDArray */ -#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) -#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; -/* bounding box */ - FT_BBox bbox; - T1_ParseState parse_state; - FT_Bool load_points; - FT_Bool no_recurse; - FT_Bool metrics_only; -/* hinter-specific */ - void* hints_funcs; -/* hinter-specific */ - void* hints_globals; - 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 -/* 0 */ -#endif - 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; -/* for seac */ - FT_Service_PsCMaps psnames; - FT_UInt num_glyphs; - FT_Byte** glyph_names; -/* internal for sub routine calls */ - FT_Int lenIV; - FT_UInt num_subrs; - FT_Byte** subrs; -/* array of subrs length (optional) */ - FT_PtrDist* subrs_len; - FT_Matrix font_matrix; - FT_Vector font_offset; - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; -/* for multiple master support */ - PS_Blend blend; - 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 -/* END */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __CIDERRS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX CID_Err_ -#define FT_ERR_BASE FT_Mod_Err_CID -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/*************************************************************************/ -/* */ -/* 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 = CID_Err_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]; -/* same as signed FT_Stream->size */ - FT_Long read_len = 256 + 10; - FT_Byte* p = buffer; - for ( offset = FT_STREAM_POS(); ; offset += 256 ) - { -/* same as signed FT_Stream->size */ - FT_Long stream_len; - stream_len = stream->size - FT_STREAM_POS(); - if ( stream_len == 0 ) - { - FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); - error = CID_Err_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 += p - buffer + 10; - goto Found; - } - else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) - { - offset += p - buffer + 7; - goto Found; - } - } - FT_MEM_MOVE( buffer, p, 10 ); - 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 = CID_Err_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 */ -/***************************************************************************/ -/* */ -/* cidload.c */ -/* */ -/* CID-keyed Type1 font loader (body). */ -/* */ -/* Copyright 1996-2006, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CIDLOAD_H__ -FT_BEGIN_HEADER - typedef struct CID_Loader_ - { -/* parser used to read the stream */ - CID_Parser parser; -/* number of characters in encoding */ - FT_Int num_chars; - } 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 -/* END */ -/*************************************************************************/ -/* */ -/* 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_Long result; - FT_Byte* p = *start; - for ( result = 0; offsize > 0; offsize-- ) - { - result <<= 8; - result |= *p++; - } - *start = p; - return 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 = CID_Err_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; - } -/* this is a callback function; */ - return CID_Err_Ok; -/* 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 = CID_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 CID_Err_Ok; - } - static - const T1_FieldRec cid_field_records[] = - { -/***************************************************************************/ -/* */ -/* 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 */ - 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 = CID_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 = CID_Err_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 = CID_Err_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 = CID_Err_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 = CID_Err_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 = CID_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 */ -/***************************************************************************/ -/* */ -/* cidobjs.c */ -/* */ -/* CID objects manager (body). */ -/* */ -/* Copyright 1996-2006, 2008, 2010-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CIDGLOAD_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CIDOBJS_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 */ - cid_size_done( FT_Size size ); - FT_LOCAL( FT_Error ) -/* CID_Size */ - cid_size_init( FT_Size size ); - FT_LOCAL( FT_Error ) -/* CID_Size */ - cid_size_request( FT_Size size, - FT_Size_Request req ); - FT_LOCAL( FT_Error ) - cid_face_init( FT_Stream stream, -/* CID_Face */ - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - FT_LOCAL( void ) -/* CID_Face */ - cid_face_done( FT_Face face ); - FT_LOCAL( FT_Error ) - cid_driver_init( FT_Module driver ); - FT_LOCAL( void ) - cid_driver_done( FT_Module driver ); -FT_END_HEADER -/* END */ -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 ); -/* 0 */ -#endif - FT_LOCAL( FT_Error ) -/* CID_Glyph_Slot */ - cid_slot_load_glyph( FT_GlyphSlot glyph, -/* CID_Size */ - FT_Size size, - FT_UInt glyph_index, - FT_Int32 load_flags ); -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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 */ - cid_size_done( FT_Size cidsize ) - { - 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 */ - cid_size_init( FT_Size cidsize ) - { - CID_Size size = (CID_Size)cidsize; - FT_Error error = CID_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 CID_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 */ - cid_face_done( FT_Face cidface ) - { - 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, -/* CID_Face */ - FT_Face cidface, - 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 = CID_Err_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 = CID_Err_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; -/* scalable outlines */ - cidface->face_flags = FT_FACE_FLAG_SCALABLE | -/* horizontal data */ - FT_FACE_FLAG_HORIZONTAL | -/* has native hinter */ - FT_FACE_FLAG_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 CID_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 */ -/***************************************************************************/ -/* */ -/* cidriver.c */ -/* */ -/* CID driver interface (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __CIDRIVER_H__ -FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Driver_ClassRec t1cid_driver_class; -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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 CID_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 CID_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, -/* unsupported with CID fonts */ - (PS_HasGlyphNamesFunc) NULL, -/* unsupported */ - (PS_GetFontPrivateFunc)NULL, -/* not implemented */ - (PS_GetFontValueFunc) NULL - }; -/* - * 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 CID_Err_Ok; - } - static FT_Error - cid_get_is_cid( CID_Face face, - FT_Bool *is_cid ) - { - FT_Error error = CID_Err_Ok; - FT_UNUSED( face ); - if ( is_cid ) -/* cid driver is only used for CID keyed fonts */ - *is_cid = 1; - return error; - } - static FT_Error - cid_get_cid_from_glyph_index( CID_Face face, - FT_UInt glyph_index, - FT_UInt *cid ) - { - FT_Error error = CID_Err_Ok; - FT_UNUSED( face ); - if ( cid ) -/* identity mapping */ - *cid = glyph_index; - 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 ), -/* module name */ - "t1cid", -/* version 1.0 of driver */ - 0x10000L, -/* requires FreeType 2.0 */ - 0x20000L, - 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, -/* FT_Face_GetKerningFunc */ - 0, -/* FT_Face_AttachFunc */ - 0, -/* FT_Face_GetAdvancesFunc */ - 0, - cid_size_request, -/* FT_Size_SelectFunc */ - 0 - }; -/* END */ -/***************************************************************************/ -/* */ -/* cidgload.c */ -/* */ -/* CID-keyed Type1 Glyph Loader (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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 = CID_Err_Ok; - FT_Byte* charstring = 0; - FT_Memory memory = face->root.memory; - FT_ULong glyph_length = 0; - PSAux_Service psaux = (PSAux_Service)face->psaux; - FT_Incremental_InterfaceRec *inc = - face->root.internal->incremental_interface; - FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); -/* 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 -/* 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 = CID_Err_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 ); -/* 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 ); - } - 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, -/* size */ - 0, -/* glyph slot */ - 0, -/* glyph names! XXX */ - 0, -/* blend == 0 */ - 0, -/* hinting == 0 */ - 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 CID_Err_Ok; - } -/* 0 */ -#endif - FT_LOCAL_DEF( FT_Error ) -/* CID_GlyphSlot */ - cid_slot_load_glyph( FT_GlyphSlot cidglyph, -/* CID_Size */ - FT_Size cidsize, - 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 = CID_Err_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, -/* glyph names -- XXX */ - 0, -/* blend == 0 */ - 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 */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* psobjs.c */ -/* */ -/* Auxiliary functions for PostScript fonts (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSOBJS_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSCONV_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __PSAUXERR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PSaux_Err_ -#define FT_ERR_BASE FT_Mod_Err_PSaux -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/*************************************************************************/ -/* */ -/* 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_Long 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 PSaux_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 PSaux_Err_Invalid_Argument; - } - if ( length < 0 ) - { - FT_ERROR(( "ps_table_add: invalid length\n" )); - return PSaux_Err_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 PSaux_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 = PSaux_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 = PSaux_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 = PSaux_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 = PSaux_Err_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 = PSaux_Err_Ok; - FT_ASSERT( **acur == '{' ); - for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur ) - { - switch ( *cur ) - { - case '{': - ++embed; - break; - case '}': - --embed; - if ( embed == 0 ) - { - ++cur; - goto end; - } - break; - case '(': - error = skip_literal_string( &cur, limit ); - break; - case '<': - error = skip_string( &cur, limit ); - break; - case '%': - skip_comment( &cur, limit ); - break; - } - } - end: - if ( embed != 0 ) - error = PSaux_Err_Invalid_File_Format; - *acur = cur; - return error; - } -/***********************************************************************/ -/* */ -/* 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 = PSaux_Err_Ok; -/* this also skips comments */ - skip_spaces( &cur, limit ); - 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 = PSaux_Err_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 = PSaux_Err_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 ) == PSaux_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 ) == PSaux_Err_Ok ) - token->limit = cur; - break; -/************* check for table/array ********************/ -/* XXX: in theory we should also look for "<<" */ -/* since this is semantically equivalent to "["; */ -/* in practice it doesn't matter (?) */ - case '[': - token->type = T1_TOKEN_TYPE_ARRAY; - 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 == '(' ) -/* skip the opening parenthesis, if there is one */ - cur++; - *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; - } -/* 0 */ -#endif - 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; -/* 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; -/* we must detect arrays in /FontBBox */ - if ( field->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 ) - goto FieldArray; - } - else if ( token.type == T1_TOKEN_TYPE_ARRAY ) - { - FieldArray: -/* if this is an array and we have no blend, an error occurs */ - if ( max_objects == 0 ) - goto Fail; - count = max_objects; - 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 ( field->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; -/* for 64-bit systems */ - default: - *(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 = PSaux_Err_Invalid_File_Format; - goto Exit; - } -/* for this to work (FT_String**)q must have been */ -/* initialized to NULL */ - if ( *(FT_String**)q != NULL ) - { - FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", - field->ident )); - FT_FREE( *(FT_String**)q ); - *(FT_String**)q = NULL; - } - if ( FT_ALLOC( string, len + 1 ) ) - goto Exit; - 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 = PSaux_Err_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; - default: -/* an error occurred */ - goto Fail; - } - } -/* obsolete -- keep for reference */ -#if 0 - if ( pflags ) - *pflags |= 1L << field->flag_bit; -#else - FT_UNUSED( pflags ); -#endif - error = PSaux_Err_Ok; - Exit: - return error; - Fail: - error = PSaux_Err_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 = PSaux_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 = PSaux_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; - } -/* obsolete -- keep for reference */ -#if 0 - 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 = PSaux_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 = PSaux_Err_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 = PSaux_Err_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 ); - } -/* 0 */ -#endif - FT_LOCAL_DEF( void ) - ps_parser_init( PS_Parser parser, - FT_Byte* base, - FT_Byte* limit, - FT_Memory memory ) - { - parser->error = PSaux_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 PSaux_Err_Invalid_File_Format; - } - if ( !builder->load_points ) - { - outline->n_contours++; - return PSaux_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 = PSaux_Err_Invalid_File_Format; -/* test whether we are building a new contour */ - if ( builder->parse_state == T1_Parse_Have_Path ) - error = PSaux_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 */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PSAUXMOD_H__ -FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1DECODE_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1CMAP_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFMPARSE_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, -/* real number */ - AFM_VALUE_TYPE_FIXED, - AFM_VALUE_TYPE_INTEGER, - AFM_VALUE_TYPE_BOOL, -/* glyph index */ - AFM_VALUE_TYPE_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 -/* END */ - 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 - }; - FT_CALLBACK_TABLE_DEF - const AFM_Parser_FuncsRec afm_parser_funcs = - { - afm_parser_init, - afm_parser_done, - afm_parser_parse - }; - 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, - &afm_parser_funcs, - }; - FT_CALLBACK_TABLE_DEF - const FT_Module_Class psaux_module_class = - { - 0, - sizeof ( FT_ModuleRec ), - "psaux", - 0x20000L, - 0x20000L, -/* module-specific interface */ - &psaux_interface, - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }; -/* END */ -/***************************************************************************/ -/* */ -/* t1decode.c */ -/* */ -/* PostScript Type 1 decoding routines (body). */ -/* */ -/* Copyright 2000-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. */ -/* */ -/***************************************************************************/ -/* 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, -/* never remove this one */ - op_max - } T1_Operator; - static - const FT_Int t1_args_count[op_max] = - { -/* none */ - 0, -/* endchar */ - 0, -/* hsbw */ - 2, -/* seac */ - 5, -/* sbw */ - 4, -/* closepath */ - 0, -/* hlineto */ - 1, -/* hmoveto */ - 1, -/* hvcurveto */ - 4, -/* rlineto */ - 2, -/* rmoveto */ - 2, -/* rrcurveto */ - 6, -/* vhcurveto */ - 4, -/* vlineto */ - 1, -/* vmoveto */ - 1, -/* dotsection */ - 0, -/* hstem */ - 2, -/* hstem3 */ - 6, -/* vstem */ - 2, -/* vstem3 */ - 6, -/* div */ - 2, -/* callothersubr */ - -1, -/* callsubr */ - 1, -/* pop */ - 0, -/* return */ - 0, -/* setcurrentpoint */ - 2, -/* opcode 15 (undocumented and obsolete) */ - 2 - }; -/*************************************************************************/ -/* */ -/* <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; - T1_Face face = (T1_Face)decoder->builder.face; - if ( decoder->seac ) - { - FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); - return PSaux_Err_Syntax_Error; - } - if ( decoder->builder.metrics_only ) - { - FT_ERROR(( "t1operator_seac: unexpected seac\n" )); - return PSaux_Err_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? */ - if ( decoder->glyph_names == 0 && - !face->root.internal->incremental_interface ) - { - FT_ERROR(( "t1operator_seac:" - " glyph names table not available in this font\n" )); - return PSaux_Err_Syntax_Error; - } - if ( face->root.internal->incremental_interface ) - { -/* the caller must handle the font encoding also */ - bchar_index = bchar; - achar_index = achar; - } - else - { - 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 PSaux_Err_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 */ -/* prepare loader */ - FT_GlyphLoader_Prepare( decoder->builder.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; -/* 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 = PSaux_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 ); -/*********************************************************************/ -/* */ -/* 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; -/* undocumented, obsolete operator */ - case 15: - 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; -/* four bytes integer */ - case 255: - if ( ip + 4 > limit ) - { - FT_ERROR(( "t1_decoder_parse_charstrings:" - " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) | - ( (FT_Long)ip[1] << 16 ) | - ( (FT_Long)ip[2] << 8 ) | - 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 <<= 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 = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - if ( !large_int ) - 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; - } - *top++ = value; - decoder->top = top; - } -/* callothersubr */ - else if ( op == op_callothersubr ) - { - FT_Int subr_no; - FT_Int arg_cnt; - 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 ) - { -/* end flex feature */ - case 0: - 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; -/* start flex feature */ - case 1: - 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 ) ) - != PSaux_Err_Ok || - ( error = t1_builder_check_points( builder, 6 ) ) - != PSaux_Err_Ok ) - goto Fail; - break; -/* add flex vectors */ - case 2: - { - 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; -/* change hints */ - case 3: - 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: -/* multiple masters */ - case 18: - { - 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; -/* XXX (over|under)flow */ - top[0] += top[1]; - 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; -/* XXX (over|under)flow */ - top[0] -= top[1]; - 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; - } -/* general operator */ - else - { - 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 (?). */ - 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 ... */ - FT_TRACE4(( "\n" )); -/* return now! */ - return PSaux_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 PSaux_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 PSaux_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 ) ) - != PSaux_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 ) ) - != PSaux_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != PSaux_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 ) ) - != PSaux_Err_Ok ) - goto Fail; - x += top[0]; - y += top[1]; - Add_Line: - if ( ( error = t1_builder_add_point1( builder, x, y ) ) - != PSaux_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 ) ) - != PSaux_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != PSaux_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 ) ) - != PSaux_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != PSaux_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 ) ) - != PSaux_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; - } -/* save current instruction pointer */ - zone->cursor = ip; - 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--; -/* `push' the operand to callothersubr onto the stack */ - top++; - 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; -/* general operator processing */ - } -/* while ip < limit */ - } - FT_TRACE4(( "..end..\n\n" )); - Fail: - return error; - Syntax_Error: - return PSaux_Err_Syntax_Error; - Stack_Underflow: - return PSaux_Err_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 PSaux_Err_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 PSaux_Err_Ok; - } -/* finalize T1 decoder */ - FT_LOCAL_DEF( void ) - t1_decoder_done( T1_Decoder decoder ) - { - t1_builder_done( &decoder->builder ); - } -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 */ -/***************************************************************************/ -/* */ -/* afmparse.c */ -/* */ -/* AFM parser (body). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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 ) - { -/* make stupid compiler happy */ - int ch = 0; - 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; - int ch; - afm_stream_skip_spaces( stream ); - if ( AFM_STATUS_EOC( stream ) ) - return NULL; - str = AFM_STREAM_KEY_BEGIN( stream ); - while ( 1 ) - { - 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; - int ch; - afm_stream_skip_spaces( stream ); - if ( AFM_STATUS_EOL( stream ) ) - return NULL; - str = AFM_STREAM_KEY_BEGIN( stream ); -/* scan to eol */ - while ( 1 ) - { - 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; -/* make stupid compiler happy */ - char* key = 0; - 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 PSaux_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 PSaux_Err_Ok; - } - else - return PSaux_Err_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 PSaux_Err_Ok; - case AFM_TOKEN_UNKNOWN: - break; - default: - goto Fail; - } - } - Fail: - return PSaux_Err_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 PSaux_Err_Ok; - case AFM_TOKEN_UNKNOWN: - break; - default: - goto Fail; - } - } - Fail: - return PSaux_Err_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 PSaux_Err_Ok; - case AFM_TOKEN_UNKNOWN: - break; - default: - goto Fail; - } - } - Fail: - return PSaux_Err_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 PSaux_Err_Ok; - } - Fail: - return PSaux_Err_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 = PSaux_Err_Syntax_Error; - char* key; - FT_Offset len; - FT_Int metrics_sets = 0; - if ( !fi ) - return PSaux_Err_Invalid_Argument; - key = afm_parser_next_key( parser, 1, &len ); - if ( !key || len != 16 || - ft_strncmp( key, "StartFontMetrics", 16 ) != 0 ) - return PSaux_Err_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 = PSaux_Err_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 PSaux_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 */ -/***************************************************************************/ -/* */ -/* psconv.c */ -/* */ -/* Some convenience conversions (body). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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 >= -/* 'A' == 65 */ -#endif -#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 < -/* 'A' == 193 */ -#endif - 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 <<= 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; - } -/* 0 */ -#endif - 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; -/* 0 */ -#else - 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; -/* 0 */ -#endif - } - 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; -/* 0 */ -#else - 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; -/* 0 */ -#endif - return r; - } -/* END */ -/* END */ -/* 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 -/* - -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 */ -/* 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. -*/ -#define __PCFUTIL_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 -/* END */ -/* - * 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 */ -/* pcfread.c - - FreeType font driver for pcf fonts - - Copyright 2000-2010, 2012 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.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. -*/ -#define __PCF_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; -/* a single charmap per face */ - FT_CharMapRec charmap; - } 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 ) -/* I'm not sure about this */ -#define GLYPHPADOPTIONS 4 - FT_LOCAL( FT_Error ) - pcf_load_font( FT_Stream, - PCF_Face ); -FT_END_HEADER -/* END */ -/* 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. -*/ -#define __PCFREAD_H__ -FT_BEGIN_HEADER - FT_LOCAL( PCF_Property ) - pcf_find_property( PCF_Face face, - const FT_String* prop ); -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __PCFERROR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PCF_Err_ -#define FT_ERR_BASE FT_Mod_Err_PCF -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/*************************************************************************/ -/* */ -/* 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 - 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 PCF_Err_Cannot_Open_Resource; - if ( toc->version != PCF_FILE_VERSION || - toc->count > FT_ARRAY_MAX( face->toc.tables ) || - toc->count == 0 ) - return PCF_Err_Invalid_File_Format; - if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) - return PCF_Err_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 PCF_Err_Invalid_Offset; - } - if ( !have_change ) - break; - } - return PCF_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 = PCF_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, -/* same as PCF_Toc->count */ - FT_ULong ntables, - FT_ULong type, - FT_ULong *aformat, - FT_ULong *asize ) - { - FT_Error error = PCF_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 = PCF_Err_Invalid_Stream_Skip; - goto Fail; - } - if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) - { - error = PCF_Err_Invalid_Stream_Skip; - goto Fail; - } - *asize = tables[i].size; - *aformat = tables[i].format; - return PCF_Err_Ok; - } - Fail: - *asize = 0; - return error; - } - static FT_Bool - pcf_has_table_type( PCF_Table tables, -/* same as PCF_Toc->count */ - FT_ULong ntables, - 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 = PCF_Err_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 = PCF_Err_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 = PCF_Err_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 = PCF_Err_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 = PCF_Err_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 = PCF_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 = PCF_Err_Ok; - 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 PCF_Err_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 PCF_Err_Invalid_File_Format; - face->nmetrics = nmetrics; - if ( !nmetrics ) - return PCF_Err_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 PCF_Err_Invalid_Table; - } - else - { - if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) - return PCF_Err_Invalid_Table; - } - if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) - return PCF_Err_Out_Of_Memory; - 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 = PCF_Err_Ok; - 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 PCF_Err_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 PCF_Err_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 )); -/* only used for debugging */ - FT_UNUSED( sizebitmaps ); - 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 = PCF_Err_Ok; - FT_Memory memory = FT_FACE(face)->memory; - FT_ULong format, size; - int firstCol, lastCol; - int firstRow, lastRow; - int nencoding, encodingOffset; - int i, j; - PCF_Encoding tmpEncoding = NULL, encoding = 0; - 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 PCF_Err_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( tmpEncoding, nencoding ) ) - return PCF_Err_Out_Of_Memory; - error = FT_Stream_EnterFrame( stream, 2 * nencoding ); - if ( error ) - goto Bail; - for ( i = 0, j = 0 ; i < nencoding; i++ ) - { - if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - encodingOffset = FT_GET_SHORT(); - else - encodingOffset = FT_GET_SHORT_LE(); - if ( encodingOffset != -1 ) - { - tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) + - firstRow ) * 256 ) + - ( ( i % ( lastCol - firstCol + 1 ) ) + - firstCol ); - tmpEncoding[j].glyph = (FT_Short)encodingOffset; - FT_TRACE5(( " code %d (0x%04X): idx %d\n", - tmpEncoding[j].enc, tmpEncoding[j].enc, - tmpEncoding[j].glyph )); - j++; - } - } - FT_Stream_ExitFrame( stream ); - if ( FT_NEW_ARRAY( encoding, j ) ) - goto Bail; - for ( i = 0; i < j; i++ ) - { - encoding[i].enc = tmpEncoding[i].enc; - encoding[i].glyph = tmpEncoding[i].glyph; - } - face->nencodings = j; - face->encodings = encoding; - FT_FREE( tmpEncoding ); - return error; - Bail: - FT_FREE( encoding ); - FT_FREE( tmpEncoding ); - 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_Err_Ok; - 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 - { -/* I'm not sure about this */ - accel->ink_minbounds = accel->minbounds; - accel->ink_maxbounds = accel->maxbounds; - } - Bail: - return error; - } - static FT_Error - pcf_interpret_style( PCF_Face pcf ) - { - FT_Error error = PCF_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 = PCF_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 = PCF_Err_Invalid_File_Format; - } - return error; - } -/* END */ -/* pcfdrivr.c - - FreeType font driver for pcf files - - Copyright (C) 2000-2004, 2006-2011 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. -*/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTGZIP_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTLZW_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTBZIP2_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 -/* END */ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* 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. -*/ -#define __PCFDRIVR_H__ -FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; -FT_END_HEADER -/* END */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_pcfread -/*************************************************************************/ -/* */ -/* 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 */ - pcf_cmap_init( FT_CMap pcfcmap, - 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 PCF_Err_Ok; - } - FT_CALLBACK_DEF( void ) -/* PCF_CMap */ - pcf_cmap_done( FT_CMap pcfcmap ) - { - PCF_CMap cmap = (PCF_CMap)pcfcmap; - cmap->encodings = NULL; - cmap->num_encodings = 0; - } - FT_CALLBACK_DEF( FT_UInt ) -/* PCF_CMap */ - pcf_cmap_char_index( FT_CMap pcfcmap, - 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 */ - pcf_cmap_char_next( FT_CMap pcfcmap, - 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 */ - PCF_Face_Done( FT_Face pcfface ) - { - 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, -/* PCF_Face */ - FT_Face pcfface, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - PCF_Face face = (PCF_Face)pcfface; - FT_Error error = PCF_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 ) - 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; -/* !(FT_CONFIG_OPTION_USE_ZLIB || - FT_CONFIG_OPTION_USE_LZW || - FT_CONFIG_OPTION_USE_BZIP2) */ -#else - 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 */ - error = PCF_Err_Unknown_File_Format; - 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 PCF_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 = PCF_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 = PCF_Err_Ok; - break; - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - if ( height == ( face->accel.fontAscent + - face->accel.fontDescent ) ) - error = PCF_Err_Ok; - break; - default: - error = PCF_Err_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 = PCF_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 = PCF_Err_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 PCF_Err_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, 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 PCF_Err_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, -/* FT_Module_Constructor */ - 0, -/* FT_Module_Destructor */ - 0, - pcf_driver_requester - }, - sizeof ( PCF_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - PCF_Face_Init, - PCF_Face_Done, -/* FT_Size_InitFunc */ - 0, -/* FT_Size_DoneFunc */ - 0, -/* FT_Slot_InitFunc */ - 0, -/* FT_Slot_DoneFunc */ - 0, - PCF_Glyph_Load, -/* FT_Face_GetKerningFunc */ - 0, -/* FT_Face_AttachFunc */ - 0, -/* FT_Face_GetAdvancesFunc */ - 0, - PCF_Size_Request, - PCF_Size_Select - }; -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* pfrload.c */ -/* */ -/* FreeType PFR loader (body). */ -/* */ -/* Copyright 2002, 2003, 2004, 2005, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFRLOAD_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFROBJS_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFRTYPES_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; -/* optional, bbox.yMax if not present */ - FT_Int ascent; -/* optional, bbox.yMin if not present */ - FT_Int descent; -/* optional, 0 if not present */ - FT_Int leading; - 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 -/* END */ -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, -/* PFR_Face */ - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - FT_LOCAL( void ) -/* PFR_Face */ - pfr_face_done( FT_Face face ); - FT_LOCAL( FT_Error ) -/* PFR_Face */ - pfr_face_get_kerning( FT_Face face, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - FT_LOCAL( FT_Error ) -/* PFR_Slot */ - pfr_slot_init( FT_GlyphSlot slot ); - FT_LOCAL( void ) -/* PFR_Slot */ - pfr_slot_done( FT_GlyphSlot slot ); - FT_LOCAL( FT_Error ) -/* PFR_Slot */ - pfr_slot_load( FT_GlyphSlot slot, -/* PFR_Size */ - FT_Size size, - FT_UInt gindex, - FT_Int32 load_flags ); -FT_END_HEADER -/* END */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __PFRERROR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX PFR_Err_ -#define FT_ERR_BASE FT_Mod_Err_PFR -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -#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 = PFR_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 = PFR_Err_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 */ -/* "PFR0" */ - if ( header->signature != 0x50465230L || - header->version > 4 || - header->header_size < 58 || -/* CR/LF */ - header->signature2 != 0x0d0a ) - { - 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 PFR_Err_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 = PFR_Err_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 = PFR_Err_Ok; - PFR_CHECK( 5 ); -/* skip bctSize */ - p += 3; - 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 = PFR_Err_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 = PFR_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 = PFR_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 = PFR_Err_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 = PFR_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 = PFR_Err_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 = PFR_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 = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); - goto Fail; - } -/* END */ -/***************************************************************************/ -/* */ -/* pfrgload.c */ -/* */ -/* FreeType PFR glyph loader (body). */ -/* */ -/* Copyright 2002, 2003, 2005, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFRGLOAD_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFRSBIT_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 -/* END */ -/* for macro definitions */ -#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 = PFR_Err_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 = PFR_Err_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 = PFR_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 ) - { -/* end glyph */ - case 0: - FT_TRACE6(( "- end glyph" )); - args_count = 0; - break; -/* general line operation */ - case 1: - FT_TRACE6(( "- general line" )); - goto Line1; -/* move to inside contour */ - case 4: - FT_TRACE6(( "- move to inside" )); - goto Line1; -/* move to outside contour */ - case 5: - FT_TRACE6(( "- move to outside" )); - Line1: - args_format = format_low; - args_count = 1; - break; -/* horizontal line to */ - case 2: - 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; -/* vertical line to */ - case 3: - 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; -/* horizontal to vertical curve */ - case 6: - FT_TRACE6(( "- hv curve " )); - args_format = 0xB8E; - args_count = 3; - break; -/* vertical to horizontal curve */ - case 7: - FT_TRACE6(( "- vh curve" )); - args_format = 0xE2B; - args_count = 3; - break; -/* general curve to */ - default: - 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 ) - { -/* 8-bit index */ - case 0: - 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; -/* 16-bit value */ - case 1: - PFR_CHECK( 2 ); - cur->x = PFR_NEXT_SHORT( p ); - FT_TRACE7(( " x.%d", cur->x )); - break; -/* 8-bit delta */ - case 2: - 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 ) - { -/* 8-bit index */ - case 0: - 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; -/* 16-bit absolute value */ - case 1: - PFR_CHECK( 2 ); - cur->y = PFR_NEXT_SHORT( p ); - FT_TRACE7(( " y.%d", cur->y )); - break; -/* 8-bit delta */ - case 2: - 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 ) - { -/* end glyph => EXIT */ - case 0: - pfr_glyph_end( glyph ); - goto Exit; -/* line operations */ - case 1: - case 2: - case 3: - error = pfr_glyph_line_to( glyph, pos ); - goto Test_Error; -/* move to inside contour */ - case 4: -/* move to outside contour */ - case 5: - error = pfr_glyph_move_to( glyph, pos ); - goto Test_Error; -/* curve operations */ - default: - error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); -/* test error condition */ - Test_Error: - if ( error ) - goto Exit; - } -/* for (;;) */ - } - } - Exit: - return error; - Failure: - Too_Short: - error = PFR_Err_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 = PFR_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 = PFR_Err_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 = PFR_Err_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 */ -/***************************************************************************/ -/* */ -/* pfrcmap.c */ -/* */ -/* FreeType PFR cmap handling (body). */ -/* */ -/* Copyright 2002, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFRCMAP_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 -/* END */ - FT_CALLBACK_DEF( FT_Error ) - pfr_cmap_init( PFR_CMap cmap ) - { - FT_Error error = PFR_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 = PFR_Err_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 */ -/***************************************************************************/ -/* */ -/* pfrobjs.c */ -/* */ -/* FreeType PFR object methods (body). */ -/* */ -/* Copyright 2002-2008, 2010-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_COMPONENT -#define FT_COMPONENT trace_pfr -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** FACE OBJECT METHODS *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ - FT_LOCAL_DEF( void ) -/* PFR_Face */ - pfr_face_done( FT_Face pfrface ) - { - 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 = PFR_Err_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 = PFR_Err_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 ) -/* not scalable */ - pfrface->face_flags = 0; - else - { - FT_ERROR(( "pfr_face_init: font doesn't contain glyphs\n" )); - error = PFR_Err_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 */ - pfr_slot_init( FT_GlyphSlot pfrslot ) - { - 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 */ - pfr_slot_done( FT_GlyphSlot pfrslot ) - { - PFR_Slot slot = (PFR_Slot)pfrslot; - pfr_glyph_done( &slot->glyph ); - } - FT_LOCAL_DEF( FT_Error ) -/* PFR_Slot */ - pfr_slot_load( FT_GlyphSlot pfrslot, -/* PFR_Size */ - FT_Size pfrsize, - 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 = PFR_Err_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 = PFR_Err_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; -/* some fonts seem to be broken here! */ -#if 0 -/* 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 */ - pfr_face_get_kerning( FT_Face pfrface, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - PFR_Face face = (PFR_Face)pfrface; - FT_Error error = PFR_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; -/* we found an item, now parse it and find the value if any */ - FoundPair: - 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 */ -/***************************************************************************/ -/* */ -/* pfrdrivr.c */ -/* */ -/* FreeType PFR driver interface (body). */ -/* */ -/* Copyright 2002-2004, 2006, 2008, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __PFRDRIVR_H__ -FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; -FT_END_HEADER -/* END */ - FT_CALLBACK_DEF( FT_Error ) -/* PFR_Face */ - pfr_get_kerning( FT_Face pfrface, - 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 PFR_Err_Ok; - } -/* - * PFR METRICS SERVICE - * - */ - FT_CALLBACK_DEF( FT_Error ) -/* PFR_Face */ - pfr_get_advance( FT_Face pfrface, - FT_UInt gindex, - FT_Pos *anadvance ) - { - PFR_Face face = (PFR_Face)pfrface; - FT_Error error = PFR_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 = PFR_Err_Ok; - } - } - Exit: - return error; - } - FT_CALLBACK_DEF( FT_Error ) -/* PFR_Face */ - pfr_get_metrics( FT_Face pfrface, - 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 PFR_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, -/* FT_Module_Constructor */ - 0, -/* FT_Module_Destructor */ - 0, - pfr_get_service - }, - sizeof ( PFR_FaceRec ), - sizeof ( PFR_SizeRec ), - sizeof ( PFR_SlotRec ), - pfr_face_init, - pfr_face_done, -/* FT_Size_InitFunc */ - 0, -/* FT_Size_DoneFunc */ - 0, - pfr_slot_init, - pfr_slot_done, - pfr_slot_load, - pfr_get_kerning, -/* FT_Face_AttachFunc */ - 0, -/* FT_Face_GetAdvancesFunc */ - 0, -/* FT_Size_RequestFunc */ - 0, -/* FT_Size_SelectFunc */ - 0, - }; -/* END */ -/***************************************************************************/ -/* */ -/* pfrsbit.c */ -/* */ -/* FreeType PFR bitmap loader (body). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -#undef FT_COMPONENT -#define FT_COMPONENT trace_pfr -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** PFR BIT WRITER *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ - typedef struct PFR_BitWriter_ - { -/* current line start */ - FT_Byte* line; -/* line size in bytes */ - FT_Int pitch; -/* width in pixels/bits */ - FT_Int width; -/* number of remaining rows to scan */ - FT_Int rows; -/* total number of bits to draw */ - FT_Int total; - } 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 = PFR_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 = PFR_Err_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 = PFR_Err_Ok; - PFR_BitWriterRec writer; - if ( target->rows > 0 && target->width > 0 ) - { - pfr_bitwriter_init( &writer, target, decreasing ); - switch ( format ) - { -/* packed bits */ - case 0: - pfr_bitwriter_decode_bytes( &writer, p, limit ); - break; -/* RLE1 */ - case 1: - pfr_bitwriter_decode_rle1( &writer, p, limit ); - break; -/* RLE2 */ - case 2: - pfr_bitwriter_decode_rle2( &writer, p, limit ); - break; - default: - FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); - error = PFR_Err_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 PFR_Err_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 = PFR_Err_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 = PFR_Err_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 */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* ttpic.c */ -/* */ -/* The FreeType position independent code services for truetype module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* ttpic.h */ -/* */ -/* The FreeType position independent code services for truetype 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. */ -/* */ -/***************************************************************************/ -#define __TTPIC_H__ -FT_BEGIN_HEADER -#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 -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __TTERRORS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX TT_Err_ -#define FT_ERR_BASE FT_Mod_Err_TrueType -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/* driver interface */ -/***************************************************************************/ -/* */ -/* ttdriver.c */ -/* */ -/* TrueType font driver implementation (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTDRIVER_H__ -FT_BEGIN_HEADER - FT_DECLARE_DRIVER( tt_driver_class ) -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTGLOAD_H__ -/***************************************************************************/ -/* */ -/* ttobjs.h */ -/* */ -/* Objects manager (specification). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -#define __TTOBJS_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; - 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; - 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 ); -/*************************************************************************/ -/* */ -/* 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_ - { -/* in which code range is it located? */ - FT_Int range; -/* where does it start? */ - FT_Long start; -/* where does it end? */ - FT_Long end; -/* function #, or instruction code */ - FT_UInt opc; -/* is it active? */ - FT_Bool active; -/* is function that defines inline delta? */ - FT_Bool inline_delta; - } TT_DefRecord, *TT_DefArray; -/*************************************************************************/ -/* */ -/* Subglyph transformation record. */ -/* */ - typedef struct TT_Transform_ - { -/* transformation matrix coefficients */ - FT_Fixed xx, xy; - FT_Fixed yx, yy; -/* offsets */ - FT_F26Dot6 ox, oy; - } 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; -/* maximum ppem size */ - FT_UShort ppem; -/* current ratio */ - FT_Long ratio; - FT_Fixed scale; -/* device-specific compensations */ - FT_F26Dot6 compensations[4]; - FT_Bool valid; -/* `is the glyph rotated?'-flag */ - FT_Bool rotated; -/* `is the glyph stretched?'-flag */ - FT_Bool stretched; - } 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; -/* 0xFFFFFFFF to indicate invalid */ - FT_ULong strike_index; -/* number of function definitions */ - FT_UInt num_function_defs; - FT_UInt max_function_defs; -/* table of function definitions */ - TT_DefArray function_defs; -/* number of ins. definitions */ - FT_UInt num_instruction_defs; - FT_UInt max_instruction_defs; -/* table of ins. definitions */ - TT_DefArray instruction_defs; - FT_UInt max_func; - FT_UInt max_ins; - TT_CodeRangeTable codeRangeTable; - TT_GraphicsState GS; -/* the scaled control value table */ - FT_ULong cvt_size; - FT_Long* cvt; -/* The storage area is now part of */ - FT_UShort storage_size; -/* the instance */ - FT_Long* storage; -/* The instance's twilight zone */ - TT_GlyphZoneRec twilight; -/* 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; - FT_Bool ttfautohinted; - } TT_SizeRec; -/*************************************************************************/ -/* */ -/* TrueType driver class. */ -/* */ - typedef struct TT_DriverRec_ - { - FT_DriverRec root; -/* execution context */ - TT_ExecContext context; -/* glyph loader points zone */ - TT_GlyphZoneRec zone; - void* extension_component; - } 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, -/* TT_Face */ - FT_Face ttface, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - FT_LOCAL( void ) -/* TT_Face */ - tt_face_done( FT_Face ttface ); -/*************************************************************************/ -/* */ -/* Size functions */ -/* */ - FT_LOCAL( FT_Error ) -/* TT_Size */ - tt_size_init( FT_Size ttsize ); - FT_LOCAL( void ) -/* TT_Size */ - tt_size_done( FT_Size ttsize ); - 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 ); - FT_LOCAL( FT_Error ) - tt_size_reset( TT_Size size ); -/*************************************************************************/ -/* */ -/* Driver functions */ -/* */ - FT_LOCAL( FT_Error ) -/* TT_Driver */ - tt_driver_init( FT_Module ttdriver ); - FT_LOCAL( void ) -/* TT_Driver */ - tt_driver_done( FT_Module ttdriver ); -/*************************************************************************/ -/* */ -/* 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 -/* END */ -/***************************************************************************/ -/* */ -/* ttinterp.h */ -/* */ -/* TrueType bytecode interpreter (specification). */ -/* */ -/* Copyright 1996-2007, 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. */ -/* */ -/***************************************************************************/ -#define __TTINTERP_H__ -FT_BEGIN_HEADER -/* indirect implementation */ -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER -#define EXEC_OP_ TT_ExecContext exc, -#define EXEC_OP TT_ExecContext exc -#define EXEC_ARG_ exc, -#define EXEC_ARG exc -/* static implementation */ -#else -/* void */ -#define EXEC_OP_ -/* void */ -#define EXEC_OP -/* void */ -#define EXEC_ARG_ -/* void */ -#define EXEC_ARG -/* TT_CONFIG_OPTION_STATIC_INTERPRETER */ -#endif -/*************************************************************************/ -/* */ -/* 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; -/*************************************************************************/ -/* */ -/* 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 */ -/* last execution error */ - FT_Error error; -/* top of exec. stack */ - FT_Long top; -/* size of exec. stack */ - FT_UInt stackSize; -/* current exec. stack */ - FT_Long* stack; - FT_Long args; -/* new top after exec. */ - FT_UInt new_top; -/* zone records */ - TT_GlyphZoneRec zp0, - zp1, - zp2, - pts, - twilight; - FT_Size_Metrics metrics; -/* size metrics */ - TT_Size_Metrics tt_metrics; -/* current graphics state */ - TT_GraphicsState GS; -/* current code range number */ - FT_Int curRange; -/* current code range */ - FT_Byte* code; -/* current instruction pointer */ - FT_Long IP; -/* size of current range */ - FT_Long codeSize; -/* current opcode */ - FT_Byte opcode; -/* length of current opcode */ - FT_Int length; -/* true if the interpreter must */ - FT_Bool step_ins; -/* increment IP after ins. exec */ - FT_ULong cvtSize; - FT_Long* cvt; -/* glyph instructions buffer size */ - FT_UInt glyphSize; -/* glyph instructions buffer */ - FT_Byte* glyphIns; -/* number of function defs */ - FT_UInt numFDefs; -/* maximum number of function defs */ - FT_UInt maxFDefs; -/* table of FDefs entries */ - TT_DefArray FDefs; -/* number of instruction defs */ - FT_UInt numIDefs; -/* maximum number of ins defs */ - FT_UInt maxIDefs; -/* table of IDefs entries */ - TT_DefArray IDefs; -/* maximum function index */ - FT_UInt maxFunc; -/* maximum instruction index */ - FT_UInt maxIns; -/* top of call stack during execution */ - FT_Int callTop, -/* size of call stack */ - callSize; -/* call stack */ - TT_CallStack callStack; -/* capacity of this context's `pts' */ - FT_UShort maxPoints; -/* record, expressed in points and */ - FT_Short maxContours; -/* contours. */ -/* table of valid code ranges */ - TT_CodeRangeTable codeRangeTable; -/* useful for the debugger */ -/* size of current storage */ - FT_UShort storeSize; -/* storage area */ - FT_Long* storage; -/* values used for the */ - FT_F26Dot6 period; -/* `SuperRounding' */ - FT_F26Dot6 phase; - FT_F26Dot6 threshold; -#if 0 -/* this seems to be unused */ -/* ppem along the current proj vector */ - FT_Int cur_ppem; -#endif -/* If `True', the interpreter will */ - FT_Bool instruction_trap; -/* exit after each instruction */ -/* graphics state resulting from */ - TT_GraphicsState default_GS; -/* the prep program */ -/* true if the glyph is composite */ - FT_Bool is_composite; -/* true if pedantic interpretation */ - FT_Bool pedantic_hinting; -/* latest interpreter additions */ -/* dot product of freedom and projection */ - FT_Long F_dot_P; -/* vectors */ -/* current rounding function */ - TT_Round_Func func_round; -/* current projection function */ - TT_Project_Func func_project, -/* current dual proj. function */ - func_dualproj, -/* current freedom proj. func */ - func_freeProj; -/* current point move function */ - TT_Move_Func func_move; -/* move original position function */ - TT_Move_Func func_move_orig; -/* read a cvt entry */ - TT_Get_CVT_Func func_read_cvt; -/* write a cvt entry (in pixels) */ - TT_Set_CVT_Func func_write_cvt; -/* incr a cvt entry (in pixels) */ - TT_Set_CVT_Func func_move_cvt; -/* are we hinting for grayscale? */ - FT_Bool grayscale; - } TT_ExecContextRec; - extern const TT_GraphicsState tt_default_graphics_state; - 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 ); -/*************************************************************************/ -/* */ -/* <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 ); - 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 ); -/*************************************************************************/ -/* */ -/* <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 -/* END */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTPLOAD_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __TTGXVAR_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; -/* array with pairCount entries */ - GX_AVarCorrespondence correspondence; - } 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; -/* shared tuples in `gvar' */ - FT_UInt tuplecount; -/* tuplecoords[tuplecount][num_axis] */ - FT_Fixed* tuplecoords; - 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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/**** ****/ -/**** ****/ -/**** 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_Face */ - tt_get_kerning( FT_Face ttface, - 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 TT_Err_Ok; - } -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/**** ****/ -/**** ****/ -/**** S I Z E S ****/ -/**** ****/ -/**** ****/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ - 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 = TT_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; - } - static FT_Error - tt_size_request( FT_Size size, - FT_Size_Request req ) - { - TT_Size ttsize = (TT_Size)size; - FT_Error error = TT_Err_Ok; - 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 ); - } - 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_GlyphSlot */ - tt_glyph_load( FT_GlyphSlot ttslot, -/* TT_Size */ - FT_Size ttsize, - 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 TT_Err_Invalid_Slot_Handle; - if ( !size ) - return TT_Err_Invalid_Size_Handle; - if ( !face ) - return TT_Err_Invalid_Argument; - if ( glyph_index >= (FT_UInt)face->num_glyphs && - !face->internal->incremental_interface ) - return TT_Err_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 ****/ -/**** ****/ -/**** ****/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ - 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 ) - static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = - { - FT_TRUETYPE_ENGINE_TYPE_PATENTED - }; - FT_DEFINE_SERVICE_TTGLYFREC( - tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) - FT_DEFINE_SERVICEDESCREC4( - 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_CALLBACK_DEF( FT_Module_Interface ) -/* TT_Driver */ - tt_get_interface( FT_Module 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 */ - result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); - if ( result != NULL ) - return result; - if ( !driver ) - return NULL; - library = driver->library; - if ( !library ) - return NULL; -/* 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. */ -#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER -#define TT_SIZE_SELECT tt_size_select - FT_DEFINE_DRIVER( tt_driver_class, - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - TT_HINTER_FLAG, - sizeof ( TT_DriverRec ), -/* driver name */ - "truetype", -/* driver version == 1.0 */ - 0x10000L, -/* driver requires FreeType 2.0 or above */ - 0x20000L, -/* driver specific interface */ - (void*)0, - 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, -/* FT_Slot_DoneFunc */ - 0, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - ft_stub_set_char_sizes, -/* FT_CONFIG_OPTION_OLD_INTERNALS */ - ft_stub_set_pixel_sizes, - tt_glyph_load, - tt_get_kerning, -/* FT_Face_AttachFunc */ - 0, - tt_get_advances, - tt_size_request, - TT_SIZE_SELECT - ) -/* END */ -/* tables loader */ -/***************************************************************************/ -/* */ -/* ttpload.c */ -/* */ -/* TrueType-specific tables loader (body). */ -/* */ -/* Copyright 1996-2002, 2004-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 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 ( error == TT_Err_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 = TT_Err_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 = TT_Err_Invalid_Table; - goto Exit; - } - face->num_locations = table_len >> shift; - } - else - { - shift = 1; - if ( table_len >= 0x20000L ) - { - FT_TRACE2(( "table too large\n" )); - error = TT_Err_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 ) - { - 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 = TT_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" )); - if ( face->doblend ) - error = tt_face_vary_cvt( face, stream ); - Exit: - return error; - } -/*************************************************************************/ -/* */ -/* <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 ) - { - 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 = TT_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; - } -/*************************************************************************/ -/* */ -/* <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 ) - { - 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 = TT_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; - } -/*************************************************************************/ -/* */ -/* <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 TT_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 = TT_Err_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 */ -/* glyph loader */ -/***************************************************************************/ -/* */ -/* ttgload.c */ -/* */ -/* TrueType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2012 */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* ttsubpix.h */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -#define __TTSUBPIX_H__ -FT_BEGIN_HEADER -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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 ); -/* Empirically determined, at variance with what MS said */ -#if 1 - else - { - *tsb = 0; - *ah = face->root.units_per_EM; - } -/* This is what MS said to do. It isn't what they do, however. */ -#else - 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; - 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; - if ( !loader->linear_def ) - { - loader->linear_def = 1; - loader->linear = advance_width; - } - } - 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; -/* 0 */ -#endif - 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; - } -/*************************************************************************/ -/* */ -/* 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 TT_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 TT_Err_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 TT_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 = TT_Err_Too_Many_Hints; - goto Fail; - } - if ( ( limit - p ) < n_ins ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); - error = TT_Err_Too_Many_Hints; - goto Fail; - } - 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 ); - } - 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 = TT_Err_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; - { - 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 ); - } - loader->cursor = p; - Fail: - return error; - Invalid_Composite: - error = TT_Err_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 ) - { - TT_GlyphZone zone = &loader->zone; - FT_Pos origin; - FT_UInt n_ins; - 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 ); - 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 ); -/* 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; - } -/* 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 ); - 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; - } -/* 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]; - } - return TT_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 = TT_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; - 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 ); - } - 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 ); - } -/* scale the glyph */ - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - FT_Vector* vec = outline->points; - FT_Vector* limit = outline->points + n_points; - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_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 TT_Err_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 TT_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 && - ( subglyph->flags & SCALED_COMPONENT_OFFSET ) ) - { -#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 ); -/* 0 */ -#else -/*************************************************************************/ -/* */ -/* This algorithm is a guess and works much better than the above. */ -/* */ - FT_Fixed mac_xscale = FT_SqrtFixed( - (FT_Int32)FT_MulFix( subglyph->transform.xx, - subglyph->transform.xx ) + - (FT_Int32)FT_MulFix( subglyph->transform.xy, - subglyph->transform.xy ) ); - FT_Fixed mac_yscale = FT_SqrtFixed( - (FT_Int32)FT_MulFix( subglyph->transform.yy, - subglyph->transform.yy ) + - (FT_Int32)FT_MulFix( subglyph->transform.yx, - subglyph->transform.yx ) ); - x = FT_MulFix( x, mac_xscale ); - y = FT_MulFix( y, mac_yscale ); -/* 0 */ -#endif - } - 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 TT_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; - { - 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 TT_Err_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 TT_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; - } - 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 = TT_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; - FT_Vector* deltas = NULL; - FT_StreamRec inc_stream; - FT_Data glyph_data; - FT_Bool glyph_data_loaded = 0; -/* 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 = TT_Err_Invalid_Composite; - goto Exit; - } -/* check glyph index */ - if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) - { - error = TT_Err_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. */ -/* 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 - offset = tt_face_get_location( face, glyph_index, - (FT_UInt*)&loader->byte_len ); - if ( loader->byte_len > 0 ) - { -/* for the incremental interface, `glyf_offset' is always zero */ - if ( !loader->glyf_offset && - !face->root.internal->incremental_interface ) - { - FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); - error = TT_Err_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 ); - tt_get_metrics_incr_overrides( loader, glyph_index ); - 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 ); - } - 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 = TT_Err_Ok; - goto Exit; - } -/* must initialize points before (possibly) overriding */ -/* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); - tt_get_metrics_incr_overrides( loader, glyph_index ); -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ -/* 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; -/* position of composite instructions, if any */ - FT_ULong ins_pos; - 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; - 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 ); - } - 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 ) && - subglyph->flags & WE_HAVE_INSTR && - num_points > start_point ) - TT_Process_Composite_Glyph( loader, start_point, start_contour ); - } - } - else - { -/* invalid composite count (negative but not -1) */ - error = TT_Err_Invalid_Outline; - goto Exit; - } -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - Exit: - if ( opened_frame ) - face->forget_glyph_frame( loader ); - if ( glyph_data_loaded ) - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, - &glyph_data ); - return error; - } - static FT_Error - compute_glyph_metrics( TT_Loader loader, - FT_UInt glyph_index ) - { - FT_BBox bbox; - TT_Face face = (TT_Face)loader->face; - 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 ); - 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 */ - { -/* scaled vertical top side bearing */ - FT_Pos top; -/* scaled vertical advance height */ - FT_Pos advance; -/* 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; - } - { - 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? */ - 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; - } - 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; - } - 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; - FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); - face = (TT_Face)glyph->face; - stream = face->root.stream; - FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); -/* load execution context */ - if ( IS_HINTED( load_flags ) && !glyf_table_only ) - { - TT_ExecContext exec; - FT_Bool grayscale; - 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 TT_Err_Could_Not_Find_Context; - grayscale = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); - TT_Load_Context( exec, face, size ); -/* a change from mono to grayscale rendering (and vice versa) */ -/* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale ) - { - FT_UInt i; - FT_TRACE4(( "tt_loader_init: grayscale change," - " re-executing `prep' table\n" )); - exec->grayscale = grayscale; - 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; - } -/* seek to the beginning of the glyph table -- for Type 42 fonts */ -/* the table might be accessed from a Postscript stream or something */ -/* else... */ - if ( face->root.internal->incremental_interface ) - loader->glyf_offset = 0; - else - { - FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); - if ( error == TT_Err_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 TT_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 = TT_Err_Ok; -/* 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; - } - return TT_Err_Ok; - } - } -/* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ - if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) - return TT_Err_Invalid_Size_Handle; - if ( load_flags & FT_LOAD_SBITS_ONLY ) - return TT_Err_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 ); - } - 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 ) - { -/* simple drop-outs including stubs */ - case 0: - glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS; - break; -/* simple drop-outs excluding stubs */ - case 1: -/* nothing; it's the default rendering mode */ - break; -/* smart drop-outs including stubs */ - case 4: - glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS | - FT_OUTLINE_INCLUDE_STUBS; - break; -/* smart drop-outs excluding stubs */ - case 5: - glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS; - break; -/* no drop-out control */ - default: - glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; - break; - } - } - else - glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; - } - 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 */ -/* object manager */ -/***************************************************************************/ -/* */ -/* ttobjs.c */ -/* */ -/* Objects manager (body). */ -/* */ -/* Copyright 1996-2012 */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.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 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 -/*************************************************************************/ -/* */ -/* 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; - } -/* 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] = - { -/* dfkaisb.ttf */ - "DFKaiSho-SB", - "DFKaiShu", -/* kaiu.ttf */ - "DFKai-SB", -/* htkt2.ttf */ - "HuaTianKaiTi?", -/* htst3.ttf */ - "HuaTianSongTi?", -/* mingliu.ttf & mingliu.ttc */ - "MingLiU", -/* mingliu.ttc */ - "PMingLiU", -/* mingli.ttf */ - "MingLi43", - }; - 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 we believe the written value, use following part. */ -#if 0 - 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 */ - { -/* cvt */ - { 0x05bcf058, 0x000002e4 }, -/* fpgm */ - { 0x28233bf1, 0x000087c4 }, -/* prep */ - { 0xa344a1ea, 0x000001e1 } - }, -/* MingLiU 1996- */ - { -/* cvt */ - { 0x05bcf058, 0x000002e4 }, -/* fpgm */ - { 0x28233bf1, 0x000087c4 }, -/* prep */ - { 0xa344a1eb, 0x000001e1 } - }, -/* DFKaiShu */ - { -/* cvt */ - { 0x11e5ead4, 0x00000350 }, -/* fpgm */ - { 0x5a30ca3b, 0x00009063 }, -/* prep */ - { 0x13a42602, 0x0000007e } - }, -/* HuaTianKaiTi */ - { -/* cvt */ - { 0xfffbfffc, 0x00000008 }, -/* fpgm */ - { 0x9c9e48b8, 0x0000bea2 }, -/* prep */ - { 0x70020112, 0x00000008 } - }, -/* HuaTianSongTi */ - { -/* cvt */ - { 0xfffbfffc, 0x00000008 }, -/* fpgm */ - { 0x0a5a0483, 0x00017c39 }, -/* prep */ - { 0x70020112, 0x00000008 } - }, -/* NEC fadpop7.ttf */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x40c92555, 0x000000e5 }, -/* prep */ - { 0xa39b58e3, 0x0000117c } - }, -/* NEC fadrei5.ttf */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x33c41652, 0x000000e5 }, -/* prep */ - { 0x26d6c52a, 0x00000f6a } - }, -/* NEC fangot7.ttf */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x6db1651d, 0x0000019d }, -/* prep */ - { 0x6c6e4b03, 0x00002492 } - }, -/* NEC fangyo5.ttf */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x40c92555, 0x000000e5 }, -/* prep */ - { 0xde51fad0, 0x0000117c } - }, -/* NEC fankyo5.ttf */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x85e47664, 0x000000e5 }, -/* prep */ - { 0xa6c62831, 0x00001caa } - }, -/* NEC fanrgo5.ttf */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x2d891cfd, 0x0000019d }, -/* prep */ - { 0xa0604633, 0x00001de8 } - }, -/* NEC fangot5.ttc */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x40aa774c, 0x000001cb }, -/* prep */ - { 0x9b5caa96, 0x00001f9a } - }, -/* NEC fanmin3.ttc */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x0d3de9cb, 0x00000141 }, -/* prep */ - { 0xd4127766, 0x00002280 } - }, -/* NEC FA-Gothic, 1996 */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x4a692698, 0x000001f0 }, -/* prep */ - { 0x340d4346, 0x00001fca } - }, -/* NEC FA-Minchou, 1996 */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0xcd34c604, 0x00000166 }, -/* prep */ - { 0x6cf31046, 0x000022b0 } - }, -/* NEC FA-RoundGothicB, 1996 */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0x5da75315, 0x0000019d }, -/* prep */ - { 0x40745a5f, 0x000022e0 } - }, -/* NEC FA-RoundGothicM, 1996 */ - { -/* cvt */ - { 0x00000000, 0x00000000 }, -/* fpgm */ - { 0xf055fc48, 0x000001c2 }, -/* prep */ - { 0x3900ded3, 0x00001e18 } - } - }; - 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, -/* TT_Face */ - FT_Face ttface, - 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 = TT_Err_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. */ -/* MS fonts */ - if ( face->format_tag != 0x00010000L && -/* CJK fonts for Win 3.1 */ - face->format_tag != 0x00020000L && -/* Mac fonts */ - face->format_tag != TTAG_true ) - { - FT_TRACE2(( " not a TTF font\n" )); - goto Bad_Format; - } - ttface->face_flags |= FT_FACE_FLAG_HINTER; -/* If we are performing a simple font format check, exit immediately. */ - if ( face_index < 0 ) - return TT_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 ) ) - { - 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; - } - } -#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; - } -/* TT_CONFIG_OPTION_UNPATENTED_HINTING && - !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ -#endif -/* initialize standard glyph loading routines */ - TT_Init_Glyph_Loading( face ); - Exit: - return error; - Bad_Format: - error = TT_Err_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 */ - tt_face_done( FT_Face ttface ) - { - 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; - tt_done_blend( memory, face->blend ); - face->blend = NULL; - } -/*************************************************************************/ -/* */ -/* SIZE FUNCTIONS */ -/* */ -/*************************************************************************/ -/*************************************************************************/ -/* */ -/* <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 TT_Err_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 = TT_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 TT_Err_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 = TT_Err_Ok; -/* save as default graphics state */ - size->GS = exec->GS; - TT_Save_Context( exec, size ); - return error; - } - 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 = TT_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; - } -/*************************************************************************/ -/* */ -/* <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 */ - tt_size_init( FT_Size ttsize ) - { - TT_Size size = (TT_Size)ttsize; - FT_Error error = TT_Err_Ok; - size->bytecode_ready = 0; - size->cvt_ready = 0; - 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 */ - tt_size_done( FT_Size ttsize ) - { - TT_Size size = (TT_Size)ttsize; - if ( size->bytecode_ready ) - tt_size_done_bytecode( ttsize ); - 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 = TT_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 TT_Err_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; - } - size->cvt_ready = 0; - 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 */ - tt_driver_init( FT_Module ttdriver ) - { - TT_Driver driver = (TT_Driver)ttdriver; - if ( !TT_New_Context( driver ) ) - return TT_Err_Could_Not_Find_Context; - return TT_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 */ - tt_driver_done( FT_Module ttdriver ) - { - TT_Driver driver = (TT_Driver)ttdriver; -/* destroy the execution context */ - if ( driver->context ) - { - TT_Done_Context( driver->context ); - driver->context = NULL; - } - } -/*************************************************************************/ -/* */ -/* <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 */ -/***************************************************************************/ -/* */ -/* ttinterp.c */ -/* */ -/* TrueType bytecode interpreter (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ -/* issues; many thanks! */ -#define xxxSPH_DEBUG -#define xxxSPH_DEBUG_MORE_VERBOSE -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/* indirect implementation */ -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER -/* see ttobjs.h */ -#define CUR (*exc) -/*************************************************************************/ -/* */ -/* 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 ) -/* static implementation */ -#else -#define CUR cur -#define FT_UNUSED_EXEC int __dummy = __dummy - static -/* static exec. context variable */ - TT_ExecContextRec cur; -/* 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). */ -/* TT_CONFIG_OPTION_STATIC_INTERPRETER */ -#endif -/*************************************************************************/ -/* */ -/* The instruction argument stack. */ -/* */ -/* see ttobjs.h for EXEC_OP_ */ -#define INS_ARG EXEC_OP_ FT_Long* args -/*************************************************************************/ -/* */ -/* 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 ) -/*************************************************************************/ -/* */ -/* 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 -#define GUESS_VECTOR( V ) -/*************************************************************************/ -/* */ -/* 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 TT_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 TT_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 TT_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 TT_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 TT_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 TT_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 TT_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 TT_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 ) ) - != TT_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; - 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 TT_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 }, - 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 ) - }; - 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; -/* rounding */ - mid = ( mid << 16 ) + ( 1 << 13 ); - 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 ( 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 ( hi << 18 ) | ( l >> 14 ); - } -/* return length of given vector */ -#if 0 - static FT_Int32 - TT_VecLen( FT_Int32 x, - FT_Int32 y ) - { - FT_Int32 m, hi1, hi2, hi; - FT_UInt32 l, lo1, lo2, lo; -/* compute x*x as 64-bit value */ - lo = (FT_UInt32)( x & 0xFFFFU ); - hi = x >> 16; - l = lo * lo; - m = hi * lo; - hi = hi * hi; - lo1 = l + (FT_UInt32)( m << 17 ); - hi1 = hi + ( m >> 15 ) + ( lo1 < l ); -/* compute y*y as 64-bit value */ - lo = (FT_UInt32)( y & 0xFFFFU ); - hi = y >> 16; - l = lo * lo; - m = hi * lo; - hi = hi * hi; - lo2 = l + (FT_UInt32)( m << 17 ); - hi2 = hi + ( m >> 15 ) + ( lo2 < l ); -/* add them to get 'x*x+y*y' as 64-bit value */ - lo = lo1 + lo2; - hi = hi1 + hi2 + ( lo < lo1 ); -/* compute the square root of this value */ - { - FT_UInt32 root, rem, test_div; - FT_Int count; - root = 0; - { - rem = 0; - count = 32; - do - { - rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 ); - hi = ( hi << 2 ) | ( lo >> 30 ); - lo <<= 2; - root <<= 1; - test_div = ( root << 1 ) + 1; - if ( rem >= test_div ) - { - rem -= test_div; - root += 1; - } - } while ( --count ); - } - return (FT_Int32)root; - } - } -#else -/* this version uses FT_Vector_Length which computes the same value */ -/* much, much faster.. */ -/* */ - static FT_F26Dot6 - TT_VecLen( FT_F26Dot6 X, - FT_F26Dot6 Y ) - { - FT_Vector v; - v.x = X; - v.y = Y; - return FT_Vector_Length( &v ); - } -#endif -/*************************************************************************/ -/* */ -/* <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 ) - { - { - 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 = TT_VecLen( 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 = TT_Err_Bad_Argument; - return FAILURE; - } - range = &CUR.codeRangeTable[aRange - 1]; -/* invalid coderange */ - if ( range->base == NULL ) - { - CUR.error = TT_Err_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 = TT_Err_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; - v = CUR.GS.freeVector.x; - if ( v != 0 ) - { - 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; - 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; - 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 ) - { - 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 ) - { - 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_Bool S1, S2; - FT_UNUSED_EXEC; - if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L ) - { - Vx *= 0x100; - Vy *= 0x100; - W = TT_VecLen( Vx, Vy ); - if ( W == 0 ) - { -/* XXX: UNDOCUMENTED! It seems that it is possible to try */ -/* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); - R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); - return SUCCESS; - } - W = TT_VecLen( Vx, Vy ); - Vx = TT_DivFix14( Vx, W ); - Vy = TT_DivFix14( Vy, W ); - W = Vx * Vx + Vy * Vy; -/* Now, we want that Sqrt( W ) = 0x4000 */ -/* Or 0x10000000 <= W < 0x10004000 */ - if ( Vx < 0 ) - { - Vx = -Vx; - S1 = TRUE; - } - else - S1 = FALSE; - if ( Vy < 0 ) - { - Vy = -Vy; - S2 = TRUE; - } - else - S2 = FALSE; - while ( W < 0x10000000L ) - { -/* We need to increase W by a minimal amount */ - if ( Vx < Vy ) - Vx++; - else - Vy++; - W = Vx * Vx + Vy * Vy; - } - while ( W >= 0x10004000L ) - { -/* We need to decrease W by a minimal amount */ - if ( Vx < Vy ) - Vx--; - else - Vy--; - W = Vx * Vx + Vy * Vy; - } -/* Note that in various cases, we can only */ -/* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ - if ( S1 ) - Vx = -Vx; - if ( S2 ) - Vy = -Vy; -/* Type conversion */ - R->x = (FT_F2Dot14)Vx; -/* Type conversion */ - R->y = (FT_F2Dot14)Vy; - 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 = TT_Err_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 ) - { -/* counter clockwise rotation */ - C = B; - 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(); \ - } -#define DO_GPV \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; -#define DO_GFV \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; -#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 = TT_Err_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]; -/* nothing */ -#define DO_MD -#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(); -/* 0 */ -#endif -#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 = TT_Err_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 = TT_Err_Bad_Argument; \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = TT_Err_Bad_Argument; \ - CUR.step_ins = FALSE; \ - } -#define DO_JMPR \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = TT_Err_Bad_Argument; \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = TT_Err_Bad_Argument; \ - CUR.step_ins = FALSE; -#define DO_JROF \ - if ( args[1] == 0 ) \ - { \ - if ( args[0] == 0 && CUR.args == 0 ) \ - CUR.error = TT_Err_Bad_Argument; \ - CUR.IP += args[0]; \ - if ( CUR.IP < 0 || \ - ( CUR.callTop > 0 && \ - CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ - CUR.error = TT_Err_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 = TT_Err_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] ); -#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]; \ - } -#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 = TT_Err_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]; -/*************************************************************************/ -/* */ -/* 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 = TT_Err_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 = TT_Err_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 ) - { -/* IF */ - case 0x58: - nIfs++; - break; -/* ELSE */ - case 0x1B: - Out = FT_BOOL( nIfs == 1 ); - break; -/* EIF */ - case 0x59: - 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 ) - { -/* IF */ - case 0x58: - nIfs++; - break; -/* EIF */ - case 0x59: - 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; -/* 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 = TT_Err_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 = TT_Err_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; - if ( n > CUR.maxFunc ) - CUR.maxFunc = (FT_UInt16)n; -/* Now skip the whole function definition. */ -/* We don't allow nested IDEFS & FDEFs. */ - while ( SKIP_Code() == SUCCESS ) - { - switch ( CUR.opcode ) - { -/* IDEF */ - case 0x89: -/* FDEF */ - case 0x2C: - CUR.error = TT_Err_Nested_DEFS; - return; -/* ENDF */ - case 0x2D: - 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; -/* We encountered an ENDF without a call */ - if ( CUR.callTop <= 0 ) - { - CUR.error = TT_Err_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; -/* check the call stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_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 = TT_Err_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; -/* check stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_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 = TT_Err_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 = TT_Err_Too_Many_Instruction_Defs; - return; - } - CUR.numIDefs++; - } -/* opcode must be unsigned 8-bit integer */ - if ( 0 > args[0] || args[0] > 0x00FF ) - { - CUR.error = TT_Err_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 ) - { -/* IDEF */ - case 0x89: -/* FDEF */ - case 0x2C: - CUR.error = TT_Err_Nested_DEFS; - return; -/* ENDF */ - case 0x2D: - 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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 ); - } - } - } - } - 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; -/* was FT_Int in pas type ERROR */ - FT_UShort p1, p2; - 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 = TT_Err_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 ) - { -/* counter clockwise rotation */ - C = B; - 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 ( ( aOpc & 1 ) != 0 ) - { -/* counter clockwise rotation */ - C = B; - 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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_Invalid_Reference; - *refp = 0; - return FAILURE; - } - *zone = zp; - *refp = p; - d = CUR_Func_project( zp.cur + p, zp.org + p ); - { - *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 ) - { - 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 = TT_Err_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 = TT_Err_Invalid_Reference; - return; - } - } - else - 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 = TT_Err_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 = TT_Err_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; - if ( CUR.top < CUR.GS.loop + 1 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - goto Fail; - } - { - 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 = TT_Err_Invalid_Reference; - return; - } - } - else - MOVE_Zp2_Point( point, dx, dy, TRUE ); - 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; - 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 = TT_Err_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 ); - 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 = TT_Err_Invalid_Reference; - return; - } - if ( ( CUR.opcode & 1 ) != 0 ) - { - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); - 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]; - if ( BOUNDS( point, CUR.zp0.n_points ) || - BOUNDSL( cvtEntry, CUR.cvtSize ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_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 in twilight zone */ - if ( CUR.GS.gep0 == 0 ) - { - 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]; - } - org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); -/* rounding and control cut-in flag */ - if ( ( CUR.opcode & 1 ) != 0 ) - { - if ( FT_ABS( distance - org_dist ) > control_value_cutin ) - distance = org_dist; - 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; - 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 = TT_Err_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 ) - { - 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; - 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 ); -/* 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 = TT_Err_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; - } -/* 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 - 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; - } - } - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); - 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; - if ( CUR.top < CUR.GS.loop || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_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 ) - new_dist = ( old_range != 0 ) - ? FT_MulDiv( org_dist, cur_range, old_range ) - : cur_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 = TT_Err_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_ - { -/* original and current coordinate */ - FT_Vector* orgs; -/* arrays */ - FT_Vector* curs; - 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; -/* first point of contour */ - FT_UInt first_point; -/* end point (last+1) of contour */ - FT_UInt end_point; -/* first touched point in contour */ - FT_UInt first_touched; -/* current touched point in contour */ - FT_UInt cur_touched; -/* current point */ - FT_UInt point; -/* current contour */ - FT_Short 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; - 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; -/* some points theoretically may occur more - than once, thus UShort isn't enough */ - nump = (FT_ULong)args[0]; - for ( k = 1; k <= nump; k++ ) - { - if ( CUR.args < 2 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_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 ); - CUR_Func_move( &CUR.zp0, A, B ); - } - } - else - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_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; - nump = (FT_ULong)args[0]; - for ( k = 1; k <= nump; k++ ) - { - if ( CUR.args < 2 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_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 = TT_Err_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; - if ( ( args[0] & 1 ) != 0 ) - K = 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; - 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 = TT_Err_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 = TT_Err_Invalid_Opcode; - } -/*************************************************************************/ -/* */ -/* 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 ) - { -/* executed instructions counter */ - FT_Long ins_counter = 0; -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - cur = *exc; -#endif -/* 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 ) - { - FT_UShort i; - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_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 = TT_Err_Stack_Overflow; - goto LErrorLabel_; - } - CUR.step_ins = TRUE; - CUR.error = TT_Err_Ok; - { - 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 ) - { -/* SVTCA y */ - case 0x00: -/* SVTCA x */ - case 0x01: -/* SPvTCA y */ - case 0x02: -/* SPvTCA x */ - case 0x03: -/* SFvTCA y */ - case 0x04: -/* SFvTCA x */ - case 0x05: - { - 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; -/* SPvTL // */ - case 0x06: -/* SPvTL + */ - case 0x07: - DO_SPVTL - break; -/* SFvTL // */ - case 0x08: -/* SFvTL + */ - case 0x09: - DO_SFVTL - break; -/* SPvFS */ - case 0x0A: - DO_SPVFS - break; -/* SFvFS */ - case 0x0B: - DO_SFVFS - break; -/* GPV */ - case 0x0C: - DO_GPV - break; -/* GFV */ - case 0x0D: - DO_GFV - break; -/* SFvTPv */ - case 0x0E: - DO_SFVTPV - break; -/* ISECT */ - case 0x0F: - Ins_ISECT( EXEC_ARG_ args ); - break; -/* SRP0 */ - case 0x10: - DO_SRP0 - break; -/* SRP1 */ - case 0x11: - DO_SRP1 - break; -/* SRP2 */ - case 0x12: - DO_SRP2 - break; -/* SZP0 */ - case 0x13: - Ins_SZP0( EXEC_ARG_ args ); - break; -/* SZP1 */ - case 0x14: - Ins_SZP1( EXEC_ARG_ args ); - break; -/* SZP2 */ - case 0x15: - Ins_SZP2( EXEC_ARG_ args ); - break; -/* SZPS */ - case 0x16: - Ins_SZPS( EXEC_ARG_ args ); - break; -/* SLOOP */ - case 0x17: - DO_SLOOP - break; -/* RTG */ - case 0x18: - DO_RTG - break; -/* RTHG */ - case 0x19: - DO_RTHG - break; -/* SMD */ - case 0x1A: - DO_SMD - break; -/* ELSE */ - case 0x1B: - Ins_ELSE( EXEC_ARG_ args ); - break; -/* JMPR */ - case 0x1C: - DO_JMPR - break; -/* SCVTCI */ - case 0x1D: - DO_SCVTCI - break; -/* SSWCI */ - case 0x1E: - DO_SSWCI - break; -/* SSW */ - case 0x1F: - DO_SSW - break; -/* DUP */ - case 0x20: - DO_DUP - break; -/* POP */ - case 0x21: -/* nothing :-) */ - break; -/* CLEAR */ - case 0x22: - DO_CLEAR - break; -/* SWAP */ - case 0x23: - DO_SWAP - break; -/* DEPTH */ - case 0x24: - DO_DEPTH - break; -/* CINDEX */ - case 0x25: - DO_CINDEX - break; -/* MINDEX */ - case 0x26: - Ins_MINDEX( EXEC_ARG_ args ); - break; -/* ALIGNPTS */ - case 0x27: - Ins_ALIGNPTS( EXEC_ARG_ args ); - break; -/* ???? */ - case 0x28: - Ins_UNKNOWN( EXEC_ARG_ args ); - break; -/* UTP */ - case 0x29: - Ins_UTP( EXEC_ARG_ args ); - break; -/* LOOPCALL */ - case 0x2A: - Ins_LOOPCALL( EXEC_ARG_ args ); - break; -/* CALL */ - case 0x2B: - Ins_CALL( EXEC_ARG_ args ); - break; -/* FDEF */ - case 0x2C: - Ins_FDEF( EXEC_ARG_ args ); - break; -/* ENDF */ - case 0x2D: - Ins_ENDF( EXEC_ARG_ args ); - break; -/* MDAP */ - case 0x2E: -/* MDAP */ - case 0x2F: - Ins_MDAP( EXEC_ARG_ args ); - break; -/* IUP */ - case 0x30: -/* IUP */ - case 0x31: - Ins_IUP( EXEC_ARG_ args ); - break; -/* SHP */ - case 0x32: -/* SHP */ - case 0x33: - Ins_SHP( EXEC_ARG_ args ); - break; -/* SHC */ - case 0x34: -/* SHC */ - case 0x35: - Ins_SHC( EXEC_ARG_ args ); - break; -/* SHZ */ - case 0x36: -/* SHZ */ - case 0x37: - Ins_SHZ( EXEC_ARG_ args ); - break; -/* SHPIX */ - case 0x38: - Ins_SHPIX( EXEC_ARG_ args ); - break; -/* IP */ - case 0x39: - Ins_IP( EXEC_ARG_ args ); - break; -/* MSIRP */ - case 0x3A: -/* MSIRP */ - case 0x3B: - Ins_MSIRP( EXEC_ARG_ args ); - break; -/* AlignRP */ - case 0x3C: - Ins_ALIGNRP( EXEC_ARG_ args ); - break; -/* RTDG */ - case 0x3D: - DO_RTDG - break; -/* MIAP */ - case 0x3E: -/* MIAP */ - case 0x3F: - Ins_MIAP( EXEC_ARG_ args ); - break; -/* NPUSHB */ - case 0x40: - Ins_NPUSHB( EXEC_ARG_ args ); - break; -/* NPUSHW */ - case 0x41: - Ins_NPUSHW( EXEC_ARG_ args ); - break; -/* WS */ - case 0x42: - DO_WS - break; - Set_Invalid_Ref: - CUR.error = TT_Err_Invalid_Reference; - break; -/* RS */ - case 0x43: - DO_RS - break; -/* WCVTP */ - case 0x44: - DO_WCVTP - break; -/* RCVT */ - case 0x45: - DO_RCVT - break; -/* GC */ - case 0x46: -/* GC */ - case 0x47: - Ins_GC( EXEC_ARG_ args ); - break; -/* SCFS */ - case 0x48: - Ins_SCFS( EXEC_ARG_ args ); - break; -/* MD */ - case 0x49: -/* MD */ - case 0x4A: - Ins_MD( EXEC_ARG_ args ); - break; -/* MPPEM */ - case 0x4B: - DO_MPPEM - break; -/* MPS */ - case 0x4C: - DO_MPS - break; -/* FLIPON */ - case 0x4D: - DO_FLIPON - break; -/* FLIPOFF */ - case 0x4E: - DO_FLIPOFF - break; -/* DEBUG */ - case 0x4F: - DO_DEBUG - break; -/* LT */ - case 0x50: - DO_LT - break; -/* LTEQ */ - case 0x51: - DO_LTEQ - break; -/* GT */ - case 0x52: - DO_GT - break; -/* GTEQ */ - case 0x53: - DO_GTEQ - break; -/* EQ */ - case 0x54: - DO_EQ - break; -/* NEQ */ - case 0x55: - DO_NEQ - break; -/* ODD */ - case 0x56: - DO_ODD - break; -/* EVEN */ - case 0x57: - DO_EVEN - break; -/* IF */ - case 0x58: - Ins_IF( EXEC_ARG_ args ); - break; -/* EIF */ - case 0x59: -/* do nothing */ - break; -/* AND */ - case 0x5A: - DO_AND - break; -/* OR */ - case 0x5B: - DO_OR - break; -/* NOT */ - case 0x5C: - DO_NOT - break; -/* DELTAP1 */ - case 0x5D: - Ins_DELTAP( EXEC_ARG_ args ); - break; -/* SDB */ - case 0x5E: - DO_SDB - break; -/* SDS */ - case 0x5F: - DO_SDS - break; -/* ADD */ - case 0x60: - DO_ADD - break; -/* SUB */ - case 0x61: - DO_SUB - break; -/* DIV */ - case 0x62: - DO_DIV - break; -/* MUL */ - case 0x63: - DO_MUL - break; -/* ABS */ - case 0x64: - DO_ABS - break; -/* NEG */ - case 0x65: - DO_NEG - break; -/* FLOOR */ - case 0x66: - DO_FLOOR - break; -/* CEILING */ - case 0x67: - DO_CEILING - break; -/* ROUND */ - case 0x68: -/* ROUND */ - case 0x69: -/* ROUND */ - case 0x6A: -/* ROUND */ - case 0x6B: - DO_ROUND - break; -/* NROUND */ - case 0x6C: -/* NROUND */ - case 0x6D: -/* NRRUND */ - case 0x6E: -/* NROUND */ - case 0x6F: - DO_NROUND - break; -/* WCVTF */ - case 0x70: - DO_WCVTF - break; -/* DELTAP2 */ - case 0x71: -/* DELTAP3 */ - case 0x72: - Ins_DELTAP( EXEC_ARG_ args ); - break; -/* DELTAC0 */ - case 0x73: -/* DELTAC1 */ - case 0x74: -/* DELTAC2 */ - case 0x75: - Ins_DELTAC( EXEC_ARG_ args ); - break; -/* SROUND */ - case 0x76: - DO_SROUND - break; -/* S45Round */ - case 0x77: - DO_S45ROUND - break; -/* JROT */ - case 0x78: - DO_JROT - break; -/* JROF */ - case 0x79: - DO_JROF - break; -/* ROFF */ - case 0x7A: - DO_ROFF - break; -/* ???? */ - case 0x7B: - Ins_UNKNOWN( EXEC_ARG_ args ); - break; -/* RUTG */ - case 0x7C: - DO_RUTG - break; -/* RDTG */ - case 0x7D: - DO_RDTG - break; -/* SANGW */ - case 0x7E: -/* AA */ - case 0x7F: -/* nothing - obsolete */ - break; -/* FLIPPT */ - case 0x80: - Ins_FLIPPT( EXEC_ARG_ args ); - break; -/* FLIPRGON */ - case 0x81: - Ins_FLIPRGON( EXEC_ARG_ args ); - break; -/* FLIPRGOFF */ - case 0x82: - Ins_FLIPRGOFF( EXEC_ARG_ args ); - break; -/* UNKNOWN */ - case 0x83: -/* UNKNOWN */ - case 0x84: - Ins_UNKNOWN( EXEC_ARG_ args ); - break; -/* SCANCTRL */ - case 0x85: - Ins_SCANCTRL( EXEC_ARG_ args ); - break; -/* SDPVTL */ - case 0x86: -/* SDPVTL */ - case 0x87: - Ins_SDPVTL( EXEC_ARG_ args ); - break; -/* GETINFO */ - case 0x88: - Ins_GETINFO( EXEC_ARG_ args ); - break; -/* IDEF */ - case 0x89: - Ins_IDEF( EXEC_ARG_ args ); - break; -/* ROLL */ - case 0x8A: - Ins_ROLL( EXEC_ARG_ args ); - break; -/* MAX */ - case 0x8B: - DO_MAX - break; -/* MIN */ - case 0x8C: - DO_MIN - break; -/* SCANTYPE */ - case 0x8D: - Ins_SCANTYPE( EXEC_ARG_ args ); - break; -/* INSTCTRL */ - case 0x8E: - 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 ); - } - } - if ( CUR.error != TT_Err_Ok ) - { - switch ( CUR.error ) - { -/* looking for redefined instructions */ - case TT_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 = TT_Err_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 = TT_Err_Invalid_Opcode; - goto LErrorLabel_; -#if 0 -/* Unreachable code warning suppression. */ - break; -/* 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 TT_Err_Execution_Too_Long; - LSuiteLabel_: - if ( CUR.IP >= CUR.codeSize ) - { - if ( CUR.callTop > 0 ) - { - CUR.error = TT_Err_Code_Overflow; - goto LErrorLabel_; - } - else - goto LNo_Error_; - } - } while ( !CUR.instruction_trap ); - LNo_Error_: -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - return TT_Err_Ok; - LErrorCodeOverflow_: - CUR.error = TT_Err_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; - } -/* END */ -/***************************************************************************/ -/* */ -/* ttsubpix.c */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ -/* END */ -/* gx distortable font */ -/***************************************************************************/ -/* */ -/* ttgxvar.c */ -/* */ -/* TrueType GX Font Variation loader */ -/* */ -/* Copyright 2004-2012 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. */ -/* */ -/*************************************************************************/ -#define FT_Stream_FTell( stream ) \ - ( (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. */ -/* */ -#define ALL_POINTS (FT_UShort*)( ~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 = TT_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 = TT_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 = TT_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 = -/* convert to Fixed */ - FT_GET_SHORT() << 2; - segment->correspondence[j].toCoord = -/* convert to Fixed */ - FT_GET_SHORT()<<2; - } - } - 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 = TT_Err_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] = -/* convert to FT_Fixed */ - FT_GET_SHORT() << 2; - 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 = TT_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 = TT_Err_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 = -/* meaningless in this context; each glyph */ - ~0; -/* 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 Fixed */ - a->minimum = axis_rec.minValue; -/* A Fixed */ - a->def = axis_rec.defaultValue; -/* A Fixed */ - 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; - } - 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(); -/* flags = */ (void) FT_GET_USHORT(); - for ( j = 0; j < fvar_head.axisCount; ++j ) -/* A Fixed */ - ns->coords[j] = FT_GET_ULONG(); - 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 = TT_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 = TT_Err_Invalid_Argument; - goto Exit; - } - for ( i = 0; i < num_coords; ++i ) - if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) - { - error = TT_Err_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 = TT_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 = TT_Err_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 = TT_Err_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 = TT_Err_Ok; - goto Exit; - } - if ( face->cvt == NULL ) - { - FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); - error = TT_Err_Ok; - goto Exit; - } - error = face->goto_table( face, TTAG_cvar, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing\n" )); - error = TT_Err_Ok; - goto Exit; - } - if ( FT_FRAME_ENTER( table_len ) ) - { - error = TT_Err_Ok; - goto Exit; - } - table_start = FT_Stream_FTell( stream ); - if ( FT_GET_LONG() != 0x00010000L ) - { - FT_TRACE2(( "bad table version\n" )); - error = TT_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 ) -/* convert from */ - tuple_coords[j] = FT_GET_SHORT() << 2; -/* 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 ); -/* tuple isn't active for our blend */ - if ( - 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 TT_Err_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] ) -/* no variation data for this glyph */ - return TT_Err_Ok; - 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 ) -/* convert from */ - tuple_coords[j] = FT_GET_SHORT() << 2; -/* short frac to fixed */ - } - else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) - { - error = TT_Err_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 ); -/* tuple isn't active for our blend */ - if ( apply == 0 ) - { - 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 ); - } - } -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* Copyright 1996-2005, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1PARSE_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __T1ERRORS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX T1_Err_ -#define FT_ERR_BASE FT_Mod_Err_Type1 -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/*************************************************************************/ -/* */ -/* 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 = T1_Err_Ok; - if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) - error = T1_Err_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 ( error != T1_Err_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 = T1_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 = T1_Err_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 = T1_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]; -/* 9 = 5 letters for `eexec' + */ - if ( c == 'e' && cur + 9 < limit ) -/* 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 = T1_Err_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 = T1_Err_Invalid_File_Format; - goto Exit; - } - size = 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 = T1_Err_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 */ -/***************************************************************************/ -/* */ -/* t1load.c */ -/* */ -/* Type 1 font loader (body). */ -/* */ -/* Copyright 1996-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 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'. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1LOAD_H__ -FT_BEGIN_HEADER - typedef struct T1_Loader_ - { -/* parser used to read the stream */ - T1_ParserRec parser; -/* number of characters in encoding */ - FT_Int num_chars; -/* PS_Table used to store the */ - PS_TableRec encoding_table; -/* encoding character names */ - FT_Int num_glyphs; - PS_TableRec glyph_names; - PS_TableRec charstrings; -/* For moving .notdef glyph to index 0. */ - PS_TableRec swap_table; - FT_Int num_subrs; - PS_TableRec subrs; - FT_Bool fontdata; -/* T1_LOADER_ENCOUNTERED_XXX */ - FT_UInt keywords_encountered; - } 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 ); - 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 ); -FT_END_HEADER -/* END */ -#define IS_INCREMENTAL ( face->root.internal->incremental_interface != 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_t1load -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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 = T1_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->privates[nn] = blend->privates [nn - 1] + 1; - blend->font_infos[nn] = blend->font_infos[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 = T1_Err_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 = T1_Err_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 = T1_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; -/* Does not apply */ - mmvar->num_namedstyles = ~0; - 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 */ -/* Does not apply */ - mmvar->axis[i].strid = ~0; -/* Does not apply */ - mmvar->axis[i].tag = ~0; - 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 = T1_Err_Invalid_Argument; - if ( blend && blend->num_axis == num_coords ) - { -/* recompute the weight vector from the blend coordinates */ - error = T1_Err_Ok; - for ( n = 0; n < blend->num_designs; n++ ) - { -/* 1.0 fixed */ - FT_Fixed result = 0x10000L; - 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 = T1_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 = T1_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 ) - { -/* maximum axis count is 4 */ - FT_Long lcoords[4]; - FT_UInt i; - FT_Error error; - error = T1_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] = 0; -/* 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] = 0; - blend->font_infos[n] = 0; - blend->bboxes [n] = 0; - } -/* release weight vectors */ - FT_FREE( blend->weight_vector ); - blend->default_weight_vector = 0; -/* 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 = T1_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 = T1_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 = T1_Err_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 = T1_Err_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 = T1_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 = T1_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 = T1_Err_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; -/* make compiler happy */ - num_axis = 0; - 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 = T1_Err_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 = T1_Err_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 = T1_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 = T1_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 = T1_Err_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 = T1_Err_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 = T1_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 = T1_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 = T1_Err_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 = T1_Err_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; - } -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** 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; - case T1_FIELD_LOCATION_BLEND: - dummy_object = face->blend; - objects = &dummy_object; - max_objects = 0; - break; - 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 = T1_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 ); -/* `RD' or `-|' or something else */ - T1_Skip_PS_Token( parser ); -/* 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 = T1_Err_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 = T1_Err_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 = T1_Err_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 = T1_Err_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_Err_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 = T1_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 = T1_Err_Invalid_File_Format; - return; - } - num_subrs = (FT_Int)T1_ToInt( parser ); -/* position the parser right before the `dup' of the first subr */ -/* `array' */ - T1_Skip_PS_Token( parser ); - 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; -/* `dup' */ - T1_Skip_PS_Token( parser ); - 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. */ -/* `NP' or `|' or `noaccess' */ - T1_Skip_PS_Token( parser ); - 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 ) - { -/* skip `put' */ - T1_Skip_PS_Token( parser ); - 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 = T1_Err_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 = T1_Err_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 = T1_Err_Invalid_File_Format; - goto Fail; - } -/* skip `/' */ - cur++; - 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 = NULL; - if ( size <= face->type1.private_dict.lenIV ) - { - error = T1_Err_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[] = - { -/***************************************************************************/ -/* */ -/* 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 ) -#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 ) -/* END */ -/* 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 ) - 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 ) - { 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 = T1_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 T1_Err_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 T1_Err_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 != T1_Err_Ok ) - { - if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore ) - parser->root.error = T1_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; - 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; -/* 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 = T1_Err_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 */ -/***************************************************************************/ -/* */ -/* t1objs.c */ -/* */ -/* Type 1 objects manager (body). */ -/* */ -/* Copyright 1996-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1GLOAD_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1OBJS_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 -/* END */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1AFM_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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 */ - T1_Size_Done( FT_Size t1size ) - { - 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 */ - T1_Size_Init( FT_Size t1size ) - { - T1_Size size = (T1_Size)t1size; - FT_Error error = T1_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 */ - T1_Size_Request( FT_Size t1size, - 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 T1_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 */ - T1_Face_Done( FT_Face t1face ) - { - T1_Face face = (T1_Face)t1face; - FT_Memory memory; - T1_Font type1; - if ( !face ) - return; - memory = face->root.memory; - type1 = &face->type1; -/* 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; -/* 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 ); -/* release afm data if present */ - if ( face->afm_data ) - T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); -/* 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, -/* T1_Face */ - FT_Face t1face, - 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 = T1_Err_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 = T1_Err_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 -/* clear error */ - error = T1_Err_Ok; - } - 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_No_Unicode_Glyph_Name != error ) - 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 T1_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 */ -/***************************************************************************/ -/* */ -/* t1driver.c */ -/* */ -/* Type 1 driver interface (body). */ -/* */ -/* Copyright 1996-2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T1DRIVER_H__ -FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; -FT_END_HEADER -/* END */ -/*************************************************************************/ -/* */ -/* 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 T1_Err_Ok; - } - static FT_UInt - t1_get_name_index( T1_Face face, - FT_String* glyph_name ) - { - FT_Int i; - FT_String* gname; - for ( i = 0; i < face->type1.num_glyphs; i++ ) - { - 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 - * - */ - 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 - }; -/* - * 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 T1_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 T1_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 T1_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_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_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 = 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_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 = 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_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_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_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_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_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, - }; - static const FT_Service_KerningRec t1_service_kerning = - { - T1_Get_Track_Kerning, - }; -/* - * 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 }, - { FT_SERVICE_ID_KERNING, &t1_service_kerning }, - { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, - { 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 ); - } -/*************************************************************************/ -/* */ -/* <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 -/* T1_Face */ - Get_Kerning( FT_Face t1face, - 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 T1_Err_Ok; - } - 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, -/* format interface */ - 0, - 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, - Get_Kerning, - T1_Read_Metrics, - T1_Get_Advances, - T1_Size_Request, -/* FT_Size_SelectFunc */ - 0 - }; -/* END */ -/***************************************************************************/ -/* */ -/* t1gload.c */ -/* */ -/* Type 1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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 = T1_Err_Ok; - FT_Incremental_InterfaceRec *inc = - face->root.internal->incremental_interface; - decoder->font_matrix = type1->font_matrix; - decoder->font_offset = type1->font_offset; -/* 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 -/* 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 ); -/* 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 ); - } - 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 ); - 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 ); - } - 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, -/* size */ - 0, -/* glyph slot */ - 0, - (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 T1_Err_Ok; - } - FT_LOCAL_DEF( FT_Error ) -/* T1_Face */ - T1_Get_Advances( FT_Face t1face, - 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 T1_Err_Ok; - } - error = psaux->t1_decoder_funcs->init( &decoder, - (FT_Face)face, -/* size */ - 0, -/* glyph slot */ - 0, - (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 T1_Err_Ok; - } - FT_LOCAL_DEF( FT_Error ) -/* T1_GlyphSlot */ - T1_Load_Glyph( FT_GlyphSlot t1glyph, -/* T1_Size */ - FT_Size t1size, - 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; - FT_Bool glyph_data_loaded = 0; - if ( glyph_index >= (FT_UInt)face->root.num_glyphs && - !face->root.internal->incremental_interface ) - { - error = T1_Err_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; - glyph_data_loaded = 1; - 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: - 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; - } - if ( must_finish_decoder ) - decoder_funcs->done( &decoder ); - return error; - } -/* END */ -/***************************************************************************/ -/* */ -/* t1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* Copyright 1996-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 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 = T1_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; - p = start; -/* 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 = T1_Err_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 = T1_Err_Unknown_File_Format; - goto Exit; - } - fi->NumKernPair = FT_PEEK_USHORT_LE( p ); - p += 2; - if ( p + 4 * fi->NumKernPair > limit ) - { - error = T1_Err_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 = T1_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 ( error == T1_Err_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 T1_Err_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 T1_Err_Ok; - } -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* t42objs.c */ -/* */ -/* Type 42 objects manager (body). */ -/* */ -/* Copyright 2002-2009, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T42OBJS_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T42TYPES_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 -/* END */ -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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T42PARSE_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_ - { -/* parser used to read the stream */ - T42_ParserRec parser; -/* number of characters in encoding */ - FT_UInt num_chars; -/* PS_Table used to store the */ - PS_TableRec encoding_table; -/* encoding character names */ - FT_UInt num_glyphs; - PS_TableRec glyph_names; - PS_TableRec charstrings; -/* For moving .notdef glyph to index 0. */ - PS_TableRec swap_table; - } 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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __T42ERROR_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX T42_Err_ -#define FT_ERR_BASE FT_Mod_Err_Type42 -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -#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 = T42_Err_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 = T42_Err_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 */ -/* 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++ ) - { - 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, -/* T42_Face */ - FT_Face t42face, - 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 = T42_Err_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 = T42_Err_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. */ - root->face_flags |= FT_FACE_FLAG_HINTER; -/* 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_No_Unicode_Glyph_Name != error ) - 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 */ - T42_Driver_Init( FT_Module module ) - { - 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 T42_Err_Missing_Module; - } - driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; - return T42_Err_Ok; - } - FT_LOCAL_DEF( void ) - T42_Driver_Done( FT_Module module ) - { - FT_UNUSED( module ); - } - FT_LOCAL_DEF( FT_Error ) -/* T42_Size */ - T42_Size_Init( FT_Size size ) - { - T42_Size t42size = (T42_Size)size; - FT_Face face = size->face; - T42_Face t42face = (T42_Face)face; - FT_Size ttsize; - FT_Error error = T42_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 */ - T42_Size_Request( FT_Size t42size, - 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 */ - T42_Size_Select( FT_Size t42size, - 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 */ - T42_Size_Done( FT_Size t42size ) - { - 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 */ - T42_GlyphSlot_Init( FT_GlyphSlot t42slot ) - { - T42_GlyphSlot slot = (T42_GlyphSlot)t42slot; - FT_Face face = t42slot->face; - T42_Face t42face = (T42_Face)face; - FT_GlyphSlot ttslot; - FT_Error error = T42_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 */ - T42_GlyphSlot_Done( FT_GlyphSlot t42slot ) - { - 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 */ -/***************************************************************************/ -/* */ -/* t42parse.c */ -/* */ -/* Type 42 font parser (body). */ -/* */ -/* Copyright 2002-2012 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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 = T42_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 = T42_Err_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 = T42_Err_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 = T42_Err_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 = T42_Err_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 = T42_Err_Invalid_File_Format; - goto Fail; - } - string_size = T1_ToInt( parser ); - if ( string_size < 0 ) - { - FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } -/* `RD' */ - T1_Skip_PS_Token( parser ); - if ( parser->root.error ) - return; -/* one space after `RD' */ - string_buf = parser->root.cursor + 1; - if ( limit - parser->root.cursor < string_size ) - { - FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); - error = T42_Err_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 = T42_Err_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 = T42_Err_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 = T42_Err_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 = T42_Err_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 = T42_Err_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; -/* rewind */ - parser->root.cursor = cur; - 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 = T42_Err_Invalid_File_Format; - goto Fail; - } - if ( parser->root.cursor >= limit ) - { - FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); - error = T42_Err_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 = T42_Err_Invalid_File_Format; - goto Fail; - } -/* skip `/' */ - cur++; - 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 = T42_Err_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 = T42_Err_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 = T42_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 */ -/***************************************************************************/ -/* */ -/* t42drivr.c */ -/* */ -/* High-level Type 42 driver interface (body). */ -/* */ -/* Copyright 2002-2004, 2006, 2007, 2009, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __T42DRIVR_H__ -FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; -FT_END_HEADER -/* END */ -#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 T42_Err_Ok; - } - static FT_UInt - t42_get_name_index( T42_Face face, - FT_String* glyph_name ) - { - FT_Int i; - FT_String* gname; - for ( i = 0; i < face->type1.num_glyphs; i++ ) - { - 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 T42_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 T42_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 T42_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, -/* not implemented */ - (PS_GetFontValueFunc) NULL - }; -/* - * - * 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 | - FT_MODULE_DRIVER_HAS_HINTER, - sizeof ( T42_DriverRec ), - "type42", - 0x10000L, - 0x20000L, -/* format interface */ - 0, - 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, -/* FT_Face_GetKerningFunc */ - 0, -/* FT_Face_AttachFunc */ - 0, -/* FT_Face_GetAdvancesFunc */ - 0, - T42_Size_Request, - T42_Size_Select - }; -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* winfnt.c */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2004, 2006-2012 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __WINFNT_H__ -FT_BEGIN_HEADER - 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; -/* a single charmap per face */ - FT_CharMapRec charmap; - } FNT_FaceRec, *FNT_Face; - FT_EXPORT_VAR( const FT_Driver_ClassRec ) winfnt_driver_class; -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __FNTERRS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX FNT_Err_ -#define FT_ERR_BASE FT_Mod_Err_Winfonts -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/*************************************************************************/ -/* */ -/* 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 ), -/* PE00 */ - FT_FRAME_ULONG_LE ( magic ), -/* 0x014c - i386 */ - FT_FRAME_USHORT_LE ( machine ), - 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 ), -/* 0x10b */ - FT_FRAME_USHORT_LE ( magic32 ), - 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 = FNT_Err_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 = FNT_Err_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 = FNT_Err_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 = FNT_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 = FNT_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 = FNT_Err_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 = FNT_Err_Invalid_File_Format; - goto Exit; - } - face->root.num_faces = font_count; - if ( face_index >= font_count ) - { - error = FNT_Err_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 )); -/* check full signature */ if ( pe32_header.magic != WINFNT_PE_MAGIC || -/* i386 */ pe32_header.machine != 0x014c || -/* FIXME */ pe32_header.size_of_optional_header != 0xe0 || - pe32_header.magic32 != 0x10b ) - { - FT_TRACE2(( "this file has an invalid PE header\n" )); - error = FNT_Err_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 = FNT_Err_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; -/* DataIsDirectory */ if ( !(dir_entry1.offset & 0x80000000UL ) ) - { - error = FNT_Err_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; -/* DataIsDirectory */ if ( !(dir_entry2.offset & 0x80000000UL ) ) - { - error = FNT_Err_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; -/* DataIsDirectory */ if ( dir_entry2.offset & 0x80000000UL ) - { - error = FNT_Err_Invalid_File_Format; - goto Exit; - } -/* RT_FONT */ if ( dir_entry1.name == 8 ) - { - 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 = FNT_Err_Invalid_File_Format; - goto Exit; - } - if ( face_index >= face->root.num_faces ) - { - error = FNT_Err_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 */ - FNT_Face_Done( FT_Face fntface ) - { - 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, -/* FNT_Face */ - FT_Face fntface, - 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 ( error == FNT_Err_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 = FNT_Err_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 = FNT_Err_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 = FNT_Err_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 FNT_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 = FNT_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 = FNT_Err_Ok; - break; - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - if ( height == header->pixel_height ) - error = FNT_Err_Ok; - break; - default: - error = FNT_Err_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 = FNT_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 = FNT_Err_Invalid_Argument; - goto Exit; - } - font = face->font; - if ( !font || - glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) - { - error = FNT_Err_Invalid_Argument; - goto Exit; - } - if ( glyph_index > 0 ) -/* revert to real index */ - glyph_index--; - else -/* the .notdef glyph */ - glyph_index = font->header.default_char; - 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 = FNT_Err_Invalid_File_Format; - goto Exit; - } -/* jump to glyph data */ -/* font->header.bits_offset */ p = font->fnt_frame + + 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 = FNT_Err_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, -/* FT_Module_Constructor */ - 0, -/* FT_Module_Destructor */ - 0, - winfnt_get_service - }, - sizeof ( FNT_FaceRec ), - sizeof ( FT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - FNT_Face_Init, - FNT_Face_Done, -/* FT_Size_InitFunc */ - 0, -/* FT_Size_DoneFunc */ - 0, -/* FT_Slot_InitFunc */ - 0, -/* FT_Slot_DoneFunc */ - 0, - FNT_Load_Glyph, -/* FT_Face_GetKerningFunc */ - 0, -/* FT_Face_AttachFunc */ - 0, -/* FT_Face_GetAdvancesFunc */ - 0, - FNT_Size_Request, - FNT_Size_Select - }; -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* rastpic.c */ -/* */ -/* The FreeType position independent code services for raster module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __RASTPIC_H__ -FT_BEGIN_HEADER -#define FT_STANDARD_RASTER_GET ft_standard_raster -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __RASTERRS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX Raster_Err_ -#define FT_ERR_BASE FT_Mod_Err_Raster -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* ftraster.c */ -/* */ -/* The FreeType glyph rasterizer (body). */ -/* */ -/* Copyright 1996-2003, 2005, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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> -/* for memset */ -#include <string.h> -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************/ -#define __FTMISC_H__ -/* memset */ -#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; - } -/* END */ -#include "ftimage.h" -/* !_STANDALONE_ */ -#else -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTRASTER_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 -/* END */ -/* for FT_MulDiv and FT_MulDiv_No_Round */ -/* !_STANDALONE_ */ -#endif -/*************************************************************************/ -/* */ -/* 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_ -/* 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 two macros. */ -#ifndef FT_ERROR -/* nothing */ -#define FT_ERROR( x ) do { } while ( 0 ) -#endif -#ifndef FT_TRACE -/* nothing */ -#define FT_TRACE( x ) do { } while ( 0 ) -/* nothing */ -#define FT_TRACE1( x ) do { } while ( 0 ) -/* nothing */ -#define FT_TRACE6( x ) do { } while ( 0 ) -#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_ \ - }; -/* !_STANDALONE_ */ -#else -/* for FT_TRACE() and FT_ERROR() */ -#define Raster_Err_None Raster_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 -/* !_STANDALONE_ */ -#endif -#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 -/* The maximum number of stacked Bezier curves. */ -#define MaxBezier 32 -/* Setting this constant to more than 32 is a */ -/* pure waste of space. */ -/* fractional bits of *input* coordinates */ -#define Pixel_Bits 6 -/*************************************************************************/ -/*************************************************************************/ -/** **/ -/** SIMPLE TYPE DECLARATIONS **/ -/** **/ -/*************************************************************************/ -/*************************************************************************/ - typedef int Int; - typedef unsigned int UInt; - typedef short Short; - typedef unsigned short UShort, *PUShort; - typedef long Long, *PLong; - 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_ - { -/* current coordinate during sweep */ - FT_F26Dot6 X; -/* link to next profile (various purposes) */ - PProfile link; -/* start of profile's data in render pool */ - PLong offset; -/* Bit 0-2: drop-out mode */ - unsigned flags; -/* Bit 3: profile orientation (up/down) */ -/* Bit 4: is top profile? */ -/* Bit 5: is bottom profile? */ -/* profile's height in scanlines */ - long height; -/* profile's starting scanline */ - long start; -/* number of lines to step before this */ - unsigned countL; -/* profile becomes drawable */ -/* next profile in same contour, used */ - PProfile next; -/* 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_ - { -/* band's minimum */ - Short y_min; -/* band's maximum */ - Short y_max; - } 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 -/* void */ -#define RAS_ARGS -/* void */ -#define RAS_ARG -/* void */ -#define RAS_VARS -/* void */ -#define RAS_VAR -#define FT_UNUSED_RASTER do { } while ( 0 ) -/* !FT_STATIC_RASTER */ -#else -#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 ) -/* !FT_STATIC_RASTER */ -#endif - 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 ) ( (signed long)(x) >> ras.precision_bits ) -#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) -#define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) -#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half ) -#define IS_TOP_OVERSHOOT( x ) ( 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_ - { -/* precision related variables */ - Int precision_bits; - Int precision; - Int precision_half; - Int precision_shift; - Int precision_step; - Int precision_jitter; -/* == precision_shift for bitmaps */ - Int scale_shift; -/* == precision_shift+1 for pixmaps */ -/* The profiles buffer */ - PLong buff; -/* Render pool size */ - PLong sizeBuff; -/* Profiles buffer size */ - PLong maxBuff; -/* Current cursor in buffer */ - PLong top; - FT_Error error; -/* number of Y-turns in outline */ - Int numTurns; -/* current Bezier arc pointer */ - TPoint* arc; -/* target bitmap width */ - UShort bWidth; -/* target bitmap buffer */ - PByte bTarget; -/* target pixmap buffer */ - PByte gTarget; - Long lastX, lastY; - Long minY, maxY; -/* current number of profiles */ - UShort num_Profs; -/* signals a fresh new profile which */ - Bool fresh; -/* `start' field must be completed */ -/* signals that the last arc ended */ - Bool joint; -/* exactly on a scanline. Allows */ -/* removal of doublets */ -/* current profile */ - PProfile cProfile; -/* head of linked list of profiles */ - PProfile fProfile; -/* contour's first profile in case */ - PProfile gProfile; -/* of impact */ -/* rendering state */ - TStates state; -/* description of target bit/pixmap */ - FT_Bitmap target; - FT_Outline outline; -/* current offset in target bitmap */ - Long traceOfs; -/* current offset in target pixmap */ - Long traceG; -/* sweep's increment in target bitmap */ - Short traceIncr; -/* current min x during gray rendering */ - Short gray_min_x; -/* current max x during gray rendering */ - Short gray_max_x; -/* 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; -/* current drop_out control method */ - Byte dropOutControl; -/* indicates whether a horizontal pass */ - Bool second_pass; -/* should be performed to control */ -/* drop-out accurately when calling */ -/* Render_Glyph. Note that there is */ -/* no horizontal pass during gray */ -/* rendering. */ -/* The Bezier stack */ - TPoint arcs[3 * MaxBezier + 1]; -/* band stack used for sub-banding */ - black_TBand band_stack[16]; -/* band stack top */ - Int band_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 */ -/* width in bytes of one monochrome */ - Short gray_width; -/* 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'. */ -/* FT_RASTER_ANTI_ALIASING */ -#endif - }; - 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 -/* !FT_STATIC_RASTER */ -#else -#define ras (*worker) -/* !FT_STATIC_RASTER */ -#endif -#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 - }; -/* FT_RASTER_OPTION_ANTI_ALIASING */ -#endif -/*************************************************************************/ -/*************************************************************************/ -/** **/ -/** 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 < 18), */ -/* 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 = Raster_Err_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 = Raster_Err_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; - PProfile oldProfile; - h = (Long)( ras.top - ras.cProfile->offset ); - if ( h < 0 ) - { - FT_ERROR(( "End_Profile: negative height encountered\n" )); - ras.error = Raster_Err_Neg_Height; - return FAILURE; - } - if ( h > 0 ) - { - 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 = Raster_Err_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 y2, 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 ) - { - y2 = (Int)y_turns[n]; - y_turns[n] = y; - y = y2; - n--; - } - if ( n < 0 ) - { - ras.maxBuff--; - if ( ras.maxBuff <= ras.top ) - { - ras.error = Raster_Err_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 ) - { - Int bottom, top; - UShort n; - PProfile p; - n = ras.num_Profs; - p = ras.fProfile; - if ( n > 1 && p ) - { - while ( n > 0 ) - { - 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; -/* XXX: is `Short' sufficient? */ - Int e1, e2, f1, f2, size; - 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 = Raster_Err_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 = Raster_Err_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; -/* current point's state */ - unsigned tag; - 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 ) - { -/* emit a single line_to */ - case FT_CURVE_TAG_ON: - { - 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; - } -/* consume conic arcs */ - case FT_CURVE_TAG_CONIC: - 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; -/* FT_CURVE_TAG_CUBIC */ - default: - { - 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 = Raster_Err_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; - PProfile lastProfile; - 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++ ) - { - 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; - int c1, c2; - Byte f1, f2; - 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 ) - { - 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 ) - { -/* simple drop-outs including stubs */ - case 0: - pxl = e2; - break; -/* smart drop-outs including stubs */ - case 4: - pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; -/* simple drop-outs excluding stubs */ - case 1: -/* smart drop-outs excluding stubs */ - case 5: -/* 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; -/* modes 2, 3, 6, 7 */ - default: -/* no drop-out control */ - return; - } -/* 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 ) - { - Long e1, e2; - PByte bits; - Byte f1; - FT_UNUSED( left ); - FT_UNUSED( right ); - if ( x2 - x1 < ras.precision ) - { - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - if ( e1 == e2 ) - { - 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 ) - { -/* simple drop-outs including stubs */ - case 0: - pxl = e2; - break; -/* smart drop-outs including stubs */ - case 4: - pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; -/* simple drop-outs excluding stubs */ - case 1: -/* smart drop-outs excluding stubs */ - case 5: -/* 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; -/* modes 2, 3, 6, 7 */ - default: -/* no drop-out control */ - return; - } -/* 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 ) - { - Int c1, c2; - PByte pix, bit, bit2; - short* count = (short*)count_table; - Byte* grays; - ras.traceOfs += ras.gray_width; - if ( ras.traceOfs > ras.gray_width ) - { - 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; - 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; - Byte color; -/* 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 ) - { -/* simple drop-outs including stubs */ - case 0: - e1 = e2; - break; -/* smart drop-outs including stubs */ - case 4: - e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); - break; -/* simple drop-outs excluding stubs */ - case 1: -/* smart drop-outs excluding stubs */ - case 5: -/* 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; -/* modes 2, 3, 6, 7 */ - default: -/* no drop-out control */ - return; - } - } - else - return; - } - if ( e1 >= 0 ) - { - 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; - } - } - } -/* FT_RASTER_OPTION_ANTI_ALIASING */ -#endif -/*************************************************************************/ -/* */ -/* 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 = Raster_Err_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 -/* -- this is useful when debugging only */ - dropouts--; -#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 = Raster_Err_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; - } -/* !FT_RASTER_OPTION_ANTI_ALIASING */ -#else - FT_LOCAL_DEF( FT_Error ) - Render_Gray_Glyph( RAS_ARG ) - { - FT_UNUSED_RASTER; - return Raster_Err_Unsupported; - } -/* !FT_RASTER_OPTION_ANTI_ALIASING */ -#endif - 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 ); - } -/* !_STANDALONE_ */ -#else - 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 ); - } -/* !_STANDALONE_ */ -#endif - 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 = 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 Raster_Err_Not_Ini; - if ( !outline ) - return Raster_Err_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 Raster_Err_Invalid; - if ( outline->n_points != - outline->contours[outline->n_contours - 1] + 1 ) - return Raster_Err_Invalid; - worker = raster->worker; -/* this version of the raster does not support direct rendering, sorry */ - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - return Raster_Err_Unsupported; - if ( !target_map ) - return Raster_Err_Invalid; -/* nothing to do */ - if ( !target_map->width || !target_map->rows ) - return Raster_Err_None; - if ( !target_map->buffer ) - return Raster_Err_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 */ -/***************************************************************************/ -/* */ -/* ftrend1.c */ -/* */ -/* The FreeType glyph rasterizer interface (body). */ -/* */ -/* Copyright 1996-2003, 2005, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTREND1_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 -/* END */ -/* 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 Raster_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 = Raster_Err_Ok; - if ( slot->format != render->glyph_format ) - { - error = Raster_Err_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 = Raster_Err_Invalid_Argument; - goto Exit; - } -/* check rendering mode */ - if ( mode != FT_RENDER_MODE_MONO ) - { -/* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz == &ft_raster1_renderer_class ) - return Raster_Err_Cannot_Render_Glyph; - } - else - { -/* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz == &ft_raster5_renderer_class ) - return Raster_Err_Cannot_Render_Glyph; - } - 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 = Raster_Err_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, -/* module specific interface */ - 0, - (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, -/* module specific interface */ - 0, - (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 */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* ftspic.c */ -/* */ -/* The FreeType position independent code services for smooth module. */ -/* */ -/* Copyright 2009, 2010, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTSPIC_H__ -FT_BEGIN_HEADER -#define FT_GRAYS_RASTER_GET ft_grays_raster -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __FTSMERRS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX Smooth_Err_ -#define FT_ERR_BASE FT_Mod_Err_Smooth -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* ftgrays.c */ -/* */ -/* A new `perfect' anti-aliasing renderer (body). */ -/* */ -/* Copyright 2000-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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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_ -/* define this to dump debugging information */ -/* #define FT_DEBUG_LEVEL_TRACE */ -#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" -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTGRAYS_H__ -#ifdef __cplusplus - extern "C" { -#endif -#ifdef _STANDALONE_ -#include "ftimage.h" -#else -/* for FT_CONFIG_OPTION_PIC */ -#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 -/* END */ -/* 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 */ -/* nothing */ -#define FT_TRACE5( x ) do { } while ( 0 ) -/* nothing */ -#define FT_TRACE7( x ) do { } while ( 0 ) -/* nothing */ -#define FT_ERROR( x ) do { } while ( 0 ) -#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_ \ - }; -/* !_STANDALONE_ */ -#else -#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph -#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline -#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument -/* !_STANDALONE_ */ -#endif -#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, -/* FT_STATIC_RASTER */ -#else -/* empty */ -#define RAS_ARG -/* empty */ -#define RAS_ARG_ -/* empty */ -#define RAS_VAR -/* empty */ -#define RAS_VAR_ -/* FT_STATIC_RASTER */ -#endif -/* 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 */ -/* integer scanline/pixel coordinate */ - typedef long TCoord; -/* sub-pixel coordinate */ - typedef long TPos; -/* 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; -/* PIXEL_BITS >= 8 */ -#else -/* approximately determine the size of integers using an ANSI-C header */ -#if FT_UINT_MAX == 0xFFFFU - typedef long TArea; -#else - typedef int TArea; -#endif -/* PIXEL_BITS >= 8 */ -#endif -/* 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_ - { -/* same with gray_TWorker.ex */ - TPos x; -/* same with gray_TWorker.cover */ - TCoord cover; - TArea area; - PCell next; - } TCell; - 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; -#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, lift, rem; - 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 ) - { - 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 ); -/* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - ey2 = TRUNC( to_y ); - 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 ) - { - FT_Span* span; - int count; - 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 ) - { -/* 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 ); - 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++; - } - } - 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 _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; -/* index of contour in outline */ - int n; -/* index of first point in contour */ - int first; -/* current point's state */ - char tag; - int shift; - TPos delta; - if ( !outline || !func_interface ) - return ErrRaster_Invalid_Argument; - shift = func_interface->shift; - delta = func_interface->delta; - first = 0; - for ( n = 0; n < outline->n_contours; n++ ) - { -/* index of last point in contour */ - int last; - 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 ) - { -/* emit a single line_to */ - case FT_CURVE_TAG_ON: - { - 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; - } -/* consume conic arcs */ - case FT_CURVE_TAG_CONIC: - 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; -/* FT_CURVE_TAG_CUBIC */ - default: - { - 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 ErrRaster_Invalid_Outline; - } -/* _STANDALONE_ */ -#endif - 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; - if ( ft_setjmp( ras.jump_buffer ) == 0 ) - { - error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); - gray_record_cell( RAS_VAR ); - } - else - error = ErrRaster_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 ) - { - 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 ErrRaster_Invalid_Argument; - if ( !outline ) - return ErrRaster_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 ErrRaster_Invalid_Outline; - if ( outline->n_points != - outline->contours[outline->n_contours - 1] + 1 ) - return ErrRaster_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 ErrRaster_Invalid_Argument; -/* nothing to do */ - if ( !target_map->width || !target_map->rows ) - return 0; - if ( !target_map->buffer ) - return ErrRaster_Invalid_Argument; - } -/* this version does not support monochrome rendering */ - if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return ErrRaster_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 ); - } -/* !_STANDALONE_ */ -#else - 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 ); - } -/* !_STANDALONE_ */ -#endif - 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: */ -/***************************************************************************/ -/* */ -/* ftsmooth.c */ -/* */ -/* Anti-aliasing renderer interface (body). */ -/* */ -/* Copyright 2000-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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTSMOOTH_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 -/* END */ -/* 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 = Smooth_Err_Ok; - if ( slot->format != render->glyph_format ) - { - error = Smooth_Err_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; - FT_Bitmap* bitmap = NULL; - FT_Memory memory = NULL; - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; - FT_Pos x_shift, y_shift, 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 = Smooth_Err_Invalid_Argument; - goto Exit; - } -/* check mode */ - if ( mode != required_mode ) - { - error = Smooth_Err_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 = Smooth_Err_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 = Smooth_Err_Raster_Overflow; - goto Exit; - } - else - height = ( cbox.yMax - cbox.yMin ) >> 6; - 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 */ - 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 ); - 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; - } - } -#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 = Smooth_Err_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; -/* 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 ); -/* - * 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 = Smooth_Err_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 = Smooth_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, -/* module specific interface */ - 0, - (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, -/* module specific interface */ - 0, - (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, -/* module specific interface */ - 0, - (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 */ -/* END */ -/***************************************************************************/ -/* */ -/* 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 -/***************************************************************************/ -/* */ -/* afpic.c */ -/* */ -/* The FreeType position independent code services for autofit 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFPIC_H__ -FT_BEGIN_HEADER -#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 -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/*************************************************************************/ -#define __AFERRORS_H__ -#undef __FTERRORS_H__ -#undef FT_ERR_PREFIX -#define FT_ERR_PREFIX AF_Err_ -#define FT_ERR_BASE FT_Mod_Err_Autofit -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error code handling (specification). */ -/* */ -/* Copyright 1996-2001, 2002, 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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). You can then use the macro */ -/* FT_ERROR_BASE macro to extract the generic error code from an */ -/* FT_Error value. */ -/* */ -/* */ -/* 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 */ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** SETUP MACROS *****/ -/***** *****/ -/*******************************************************************/ -/*******************************************************************/ -#undef FT_NEED_EXTERN_C -#undef FT_ERR_XCAT -#undef FT_ERR_CAT -#define FT_ERR_XCAT( x, y ) x ## y -#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -/* 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. */ -/* */ -#undef FT_ERR_BASE -#define FT_ERR_BASE 0 -/* 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 -/* !FT_ERRORDEF */ -#endif -/* 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 */ -/***************************************************************************/ -/* */ -/* fterrdef.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 2002, 2004, 2006, 2007, 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. */ -/* */ -/***************************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/***** *****/ -/***** 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" ) -/* 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 */ -#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_KEEP_ERR_PREFIX is needed for ftvalid.h */ -#ifndef FT_KEEP_ERR_PREFIX -#undef FT_ERR_PREFIX -#else -#undef FT_KEEP_ERR_PREFIX -#endif -/* __FTERRORS_H__ */ -#endif -/* END */ -/* END */ -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. - * - *************************************************************************/ -#define __AFTYPES_H__ -FT_BEGIN_HEADER -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** D E B U G G I N G *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** U T I L I T Y S T U F F *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ - typedef struct AF_WidthRec_ - { -/* original position/width in font units */ - FT_Pos org; -/* current/scaled position/width in device sub-pixels */ - FT_Pos cur; -/* current/fitted position/width in device sub-pixels */ - FT_Pos fit; - } 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 ); -/* 0 */ -#endif -#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_ - { -/* disable horizontal hinting */ - AF_SCALER_FLAG_NO_HORIZONTAL = 1, -/* disable vertical hinting */ - AF_SCALER_FLAG_NO_VERTICAL = 2, -/* disable advance hinting */ - AF_SCALER_FLAG_NO_ADVANCE = 4 - } AF_ScalerFlags; - typedef struct AF_ScalerRec_ - { -/* source font face */ - FT_Face face; -/* from font units to 1/64th device pixels */ - FT_Fixed x_scale; -/* from font units to 1/64th device pixels */ - FT_Fixed y_scale; -/* in 1/64th device pixels */ - FT_Pos x_delta; -/* in 1/64th device pixels */ - FT_Pos y_delta; -/* monochrome, anti-aliased, LCD, etc. */ - FT_Render_Mode render_mode; -/* additional control flags, see above */ - FT_UInt32 flags; - } 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'. */ -/* do not remove */ - AF_SCRIPT_MAX - } 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; -/* to access properties */ - AF_FaceGlobals globals; - } 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; -/* last must be { 0, 0 } */ - AF_Script_UniRange script_uni_ranges; -/* for default width and height */ - FT_UInt32 standard_char; - 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 */ -#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 \ - }; -/* */ -FT_END_HEADER -/* END */ -#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 ); - } -/* 0 */ -#endif -/* - * We are not using `af_angle_atan' anymore, but we keep the source - * code below just in case... - */ -#if 0 -/* - * The trick here is to realize that we don't need a very accurate angle - * approximation. We are going to use the result of `af_angle_atan' to - * only compare the sign of angle differences, or check whether its - * magnitude is very small. - * - * The approximation - * - * dy * PI / (|dx|+|dy|) - * - * should be enough, and much faster to compute. - */ - FT_LOCAL_DEF( AF_Angle ) - af_angle_atan( FT_Fixed dx, - FT_Fixed dy ) - { - AF_Angle angle; - FT_Fixed ax = dx; - FT_Fixed ay = dy; - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - ax += ay; - if ( ax == 0 ) - angle = 0; - else - { - angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay ); - if ( dx < 0 ) - { - if ( angle >= 0 ) - angle = AF_ANGLE_PI - angle; - else - angle = -AF_ANGLE_PI - angle; - } - } - return angle; - } -#elif 0 -/* the following table has been automatically generated with */ -/* the `mather.py' Python script */ -#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; - } -/* 0 */ -#endif - 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 */ -/***************************************************************************/ -/* */ -/* afglobal.c */ -/* */ -/* Auto-fitter routines to compute global hinting values (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFGLOBAL_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFMODULE_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFLOADER_H__ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFHINTS_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_ - { -/* x coordinates, */ - AF_DIMENSION_HORZ = 0, -/* i.e., vertical segments & edges */ -/* y coordinates, */ - AF_DIMENSION_VERT = 1, -/* i.e., horizontal segments & edges */ -/* do not remove */ - AF_DIMENSION_MAX - } 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_ - { -/* point flags used by hinter */ - FT_UShort flags; -/* direction of inwards vector */ - FT_Char in_dir; -/* direction of outwards vector */ - FT_Char out_dir; -/* original, scaled position */ - FT_Pos ox, oy; -/* original, unscaled position (in font units) */ - FT_Short fx, fy; -/* current position */ - FT_Pos x, y; -/* current (x,y) or (y,x) depending on context */ - FT_Pos u, v; -/* next point in contour */ - AF_Point next; -/* previous point in contour */ - AF_Point prev; - } AF_PointRec; - typedef struct AF_SegmentRec_ - { -/* edge/segment flags for this segment */ - FT_Byte flags; -/* segment direction */ - FT_Char dir; -/* position of segment */ - FT_Short pos; -/* minimum coordinate of segment */ - FT_Short min_coord; -/* maximum coordinate of segment */ - FT_Short max_coord; -/* the hinted segment height */ - FT_Short height; -/* the segment's parent edge */ - AF_Edge edge; -/* link to next segment in parent edge */ - AF_Segment edge_next; -/* (stem) link segment */ - AF_Segment link; -/* primary segment for serifs */ - AF_Segment serif; -/* number of linked segments */ - FT_Pos num_linked; -/* used during stem matching */ - FT_Pos score; -/* used during stem matching */ - FT_Pos len; -/* first point in edge segment */ - AF_Point first; -/* last point in edge segment */ - AF_Point last; - } AF_SegmentRec; - typedef struct AF_EdgeRec_ - { -/* original, unscaled position (in font units) */ - FT_Short fpos; -/* original, scaled position */ - FT_Pos opos; -/* current position */ - FT_Pos pos; -/* edge flags */ - FT_Byte flags; -/* edge direction */ - FT_Char dir; -/* used to speed up interpolation between edges */ - FT_Fixed scale; -/* non-NULL if this is a blue edge */ - AF_Width blue_edge; -/* link edge */ - AF_Edge link; -/* primary edge for serifs */ - AF_Edge serif; -/* number of linked edges */ - FT_Short num_linked; -/* used during stem matching */ - FT_Int score; -/* first segment in edge */ - AF_Segment first; -/* last segment in edge */ - AF_Segment last; - } AF_EdgeRec; - typedef struct AF_AxisHintsRec_ - { -/* number of used segments */ - FT_Int num_segments; -/* number of allocated segments */ - FT_Int max_segments; -/* segments array */ - AF_Segment segments; -#ifdef AF_SORT_SEGMENTS - FT_Int mid_segments; -#endif -/* number of used edges */ - FT_Int num_edges; -/* number of allocated edges */ - FT_Int max_edges; -/* edges array */ - AF_Edge edges; -/* either vertical or horizontal */ - AF_Direction major_dir; - } 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; -/* number of allocated points */ - FT_Int max_points; -/* number of used points */ - FT_Int num_points; -/* points array */ - AF_Point points; -/* number of allocated contours */ - FT_Int max_contours; -/* number of used contours */ - FT_Int num_contours; -/* contours array */ - AF_Point* contours; - AF_AxisHintsRec axis[AF_DIMENSION_MAX]; -/* copy of scaler flags */ - FT_UInt32 scaler_flags; -/* free for script-specific */ - FT_UInt32 other_flags; -/* implementations */ - AF_ScriptMetrics metrics; -/* used for warping */ - FT_Pos xmin_delta; - 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) ) -#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 - 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 ); - 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 -/* END */ -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 -/* END */ -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 -/* END */ -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; -/* same as face->num_glyphs */ - FT_Long glyph_count; - FT_Byte* glyph_scripts; -/* per-face auto-hinter properties */ - FT_UInt increase_x_height; - AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; -/* to access global properties */ - AF_Module module; - } 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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFDUMMY_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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFLATIN_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 - { -/* set if zone height is <= 3/4px */ - AF_LATIN_BLUE_ACTIVE = 1 << 0, -/* result of AF_LATIN_IS_TOP_BLUE */ - AF_LATIN_BLUE_TOP = 1 << 1, -/* used for scale adjustment */ - AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, -/* 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; -/* number of used widths */ - FT_UInt width_count; -/* widths array */ - AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; -/* used for creating edges */ - FT_Pos edge_distance_threshold; -/* the default stem thickness */ - FT_Pos standard_width; -/* is standard width very light? */ - FT_Bool extra_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 - { -/* enable stem width snapping */ - AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, -/* enable stem height snapping */ - AF_LATIN_HINTS_VERT_SNAP = 1 << 1, -/* enable stem width/height */ - AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, -/* adjustment */ -/* indicate monochrome */ - AF_LATIN_HINTS_MONO = 1 << 3 -/* 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 -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFCJK_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, -/* used for scale adjustment */ - AF_CJK_BLUE_ADJUSTMENT = 1 << 3, -/* optimization */ - AF_CJK_BLUE_FLAG_MAX - }; - typedef struct AF_CJKBlueRec_ - { - AF_WidthRec ref; -/* undershoot */ - AF_WidthRec shoot; - 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; - 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 ); -/* */ -FT_END_HEADER -/* END */ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFINDIC_H__ -FT_BEGIN_HEADER -/* the Indic-specific script class */ - AF_DECLARE_SCRIPT_CLASS( af_indic_script_class ) -/* */ -FT_END_HEADER -/* END */ -#ifdef FT_OPTION_AUTOFIT2 -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __AFLATIN2_H__ -FT_BEGIN_HEADER -/* the latin-specific script class */ - AF_DECLARE_SCRIPT_CLASS( af_latin2_script_class ) -/* */ -FT_END_HEADER -/* END */ -#endif -/* 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, -/* do not remove */ - NULL - }; -/* 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 = AF_Err_Ok; - 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 = AF_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; -/* no need to free this one! */ - globals->glyph_scripts = NULL; - 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 = AF_Err_Ok; - if ( gindex >= (FT_ULong)globals->glyph_count ) - { - error = AF_Err_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 */ -/***************************************************************************/ -/* */ -/* afhints.c */ -/* */ -/* Auto-fitter hinting routines (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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 = AF_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 = AF_Err_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 = AF_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 = AF_Err_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; - } -/* 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 -/* Compute the direction value of a given vector. */ - FT_LOCAL_DEF( AF_Direction ) - af_direction_compute( FT_Pos dx, - FT_Pos dy ) - { -/* long and short arm lengths */ - FT_Pos ll, ss; -/* candidate direction */ - AF_Direction dir; - if ( dy >= dx ) - { - if ( dy >= -dx ) - { - dir = AF_DIR_UP; - ll = dy; - ss = dx; - } - else - { - dir = AF_DIR_LEFT; - ll = -dx; - ss = dy; - } - } -/* dy < dx */ - else - { - 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 = AF_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 ) - { -/* round up to a multiple of 4 */ - new_max = ( new_max + 3 ) & ~3; - 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 ) - { -/* round up to a multiple of 8 */ - new_max = ( new_max + 2 + 7 ) & ~7; - 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++ ) - { -/* point position */ - FT_Pos u, ou, fu; - 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 (;;) - { -/* no touched point in contour */ - if ( point > end_point ) - 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 ); -/* interpolate the last part */ - else - { - 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; - } - } -/* END */ -/***************************************************************************/ -/* */ -/* afdummy.c */ -/* */ -/* Auto-fitter dummy routines to be used if no hinting should be */ -/* performed (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - static FT_Error - af_dummy_hints_init( AF_GlyphHints hints, - AF_ScriptMetrics metrics ) - { - af_glyph_hints_rescale( hints, - metrics ); - return AF_Err_Ok; - } - static FT_Error - af_dummy_hints_apply( AF_GlyphHints hints, - FT_Outline* outline ) - { - FT_UNUSED( hints ); - FT_UNUSED( outline ); - return AF_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 */ -/***************************************************************************/ -/* */ -/* aflatin.c */ -/* */ -/* Auto-fitter hinting routines for latin script (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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; - } - } - 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; -/* same as points.y */ - FT_Pos best_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; -/* make compiler happy */ - best_y = 0; -/* ditto */ - best_contour_first = 0; -/* ditto */ - best_contour_last = 0; - { - 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 AF_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 *= 0.98 */ - scale -= scale / 50; - } - 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 ( delta < 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 = AF_Err_Ok; - AF_Segment segment = NULL; - AF_SegmentRec seg0; - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - AF_Direction major_dir, segment_dir; - 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; -/* minimum segment pos != min_coord */ - FT_Pos min_pos = 32000; -/* maximum segment pos != max_coord */ - FT_Pos max_pos = -32000; - FT_Bool passed; -/* skip singletons -- just in case */ - if ( point == last ) - 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 = AF_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++ ) - { -/* does it contain round segments? */ - FT_Int is_round = 0; -/* does it contain straight segments? */ - FT_Int is_straight = 0; -#if 0 -/* number of upwards segments */ - FT_Pos ups = 0; -/* number of downwards segments */ - FT_Pos downs = 0; -#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 ) -/* both up and down! */ - edge->dir = 0; -#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; -/* initial threshold */ - FT_Pos best_dist; -/* 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; -/* #ifdef AF_CONFIG_OPTION_USE_WARPER */ -#if 0 - 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 AF_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; - 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; -/* these edges form the stem to check */ - AF_Edge edge1, edge2; - 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; - 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; - } - 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; - 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 ); - } - 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 )); - } - edge->flags |= AF_EDGE_DONE; - edge2->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) - { - 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 )); - } - } - 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; - } - } - } - } -/* 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 */ - if ( AF_HINTS_DO_HORIZONTAL( hints ) ) - { - 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++ ) - { - 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[] = - { -/* Basic Latin (no control chars) */ - AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), -/* Latin-1 Supplement (no control chars) */ - AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), -/* Latin Extended-A */ - AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), -/* Latin Extended-B */ - AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), -/* IPA Extensions */ - AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), -/* Spacing Modifier Letters */ - AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), -/* Combining Diacritical Marks */ - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), -/* Greek and Coptic */ - AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), -/* Cyrillic */ - AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), -/* Cyrillic Supplement */ - AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), -/* Phonetic Extensions */ - AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), -/* Phonetic Extensions Supplement */ - AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), -/* Combining Diacritical Marks Supplement */ - AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), -/* Latin Extended Additional */ - AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), -/* Greek Extended */ - AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), -/* General Punctuation */ - AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), -/* Superscripts and Subscripts */ - AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), -/* Currency Symbols */ - AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), -/* Number Forms */ - AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), -/* Enclosed Alphanumerics */ - AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), -/* Latin Extended-C */ - AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), -/* Cyrillic Extended-A */ - AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), -/* Supplemental Punctuation */ - AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), -/* Cyrillic Extended-B */ - AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), -/* Latin Extended-D */ - AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), -/* Alphab. Present. Forms (Latin Ligs) */ - AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), -/* Mathematical Alphanumeric Symbols */ - AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), -/* Enclosed Alphanumeric Supplement */ - AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), - 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 */ -#ifdef FT_OPTION_AUTOFIT2 -/***************************************************************************/ -/* */ -/* aflatin2.c */ -/* */ -/* Auto-fitter hinting routines for latin script (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/*************************************************************************/ -/* */ -/* 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; -/* make compiler happy */ - best_y = 0; -/* ditto */ - best_first = 0; -/* ditto */ - best_last = 0; - { - 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 = AF_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, -/* end of list */ - FT_ENCODING_NONE - }; - 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 AF_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 = AF_Err_Ok; - AF_Segment segment = NULL; - AF_SegmentRec seg0; - AF_Point* contour = hints->contours; - AF_Point* contour_limit = contour + hints->num_contours; - AF_Direction major_dir, segment_dir; - 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; -/* skip singletons -- just in case */ - if ( point == last ) - 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; - } -/* otherwise, find first segment start, if any */ - else - { - 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 = AF_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++ ) - { -/* does it contain round segments? */ - FT_Int is_round = 0; -/* does it contain straight segments? */ - FT_Int is_straight = 0; -#if 0 -/* number of upwards segments */ - FT_Pos ups = 0; -/* number of downwards segments */ - FT_Pos downs = 0; -#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 ) -/* both up and down! */ - edge->dir = 0; -#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; -/* initial threshold */ - FT_Pos best_dist0; -/* 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; -/* #ifdef AF_CONFIG_OPTION_USE_WARPER */ -#if 0 - 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 */ - if ( AF_HINTS_DO_HORIZONTAL( hints ) ) - { - 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++ ) - { - 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[] = - { -/* TODO: Add new Unicode ranges here! */ - AF_UNIRANGE_REC( 32UL, 127UL ), - 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 */ -#endif -/***************************************************************************/ -/* */ -/* afcjk.c */ -/* */ -/* Auto-fitter hinting routines for CJK script (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/* - * The algorithm is based on akito's autohint patch, available here: - * - * http://www.kde.gr.jp/~akito/patch/freetype2/ - * - */ -#undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT -/*************************************************************************/ -/* */ -/* 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, -/* top fill */ - 0x9F4A - }, - { - 0x519B, 0x540C, 0x5DF2, 0x613F, 0x65E2, 0x661F, 0x662F, 0x666F, - 0x6C11, 0x7167, 0x73B0, 0x73FE, 0x7406, 0x7528, 0x7F6E, 0x8981, - 0x8ECD, 0x90A3, 0x914D, 0x91CC, 0x958B, 0x96F7, 0x9732, 0x9762, -/* top unfill */ - 0x987E - } - }, - { - { - 0x4E2A, 0x4E3A, 0x4EBA, 0x4ED6, 0x4EE5, 0x4EEC, 0x4F60, 0x4F86, - 0x500B, 0x5011, 0x5230, 0x548C, 0x5927, 0x5BF9, 0x5C0D, 0x5C31, - 0x6211, 0x65F6, 0x6642, 0x6709, 0x6765, 0x70BA, 0x8981, 0x8AAA, -/* bottom fill */ - 0x8BF4 - }, - { - 0x4E3B, 0x4E9B, 0x56E0, 0x5B83, 0x60F3, 0x610F, 0x7406, 0x751F, - 0x7576, 0x770B, 0x7740, 0x7F6E, 0x8005, 0x81EA, 0x8457, 0x88E1, - 0x8FC7, 0x8FD8, 0x8FDB, 0x9032, 0x904E, 0x9053, 0x9084, 0x91CC, -/* bottom unfill */ - 0x9762 - } - }, -#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, -/* left fill */ - 0x901A - }, - { - 0x5373, 0x5417, 0x5427, 0x542C, 0x5462, 0x54C1, 0x54CD, 0x55CE, - 0x5E08, 0x5E2B, 0x6536, 0x65AD, 0x65B7, 0x660E, 0x773C, 0x9593, - 0x95F4, 0x9645, 0x9648, 0x9650, 0x9664, 0x9673, 0x968F, 0x969B, -/* left unfill */ - 0x96A8 - } - }, - { - { - 0x4E8B, 0x524D, 0x5B78, 0x5C06, 0x5C07, 0x60C5, 0x60F3, 0x6216, - 0x653F, 0x65AF, 0x65B0, 0x6837, 0x6A23, 0x6C11, 0x6C92, 0x6CA1, - 0x7136, 0x7279, 0x73B0, 0x73FE, 0x7403, 0x7B2C, 0x7D93, 0x8C01, -/* right fill */ - 0x8D77 - }, - { - 0x4F8B, 0x5225, 0x522B, 0x5236, 0x52A8, 0x52D5, 0x5417, 0x55CE, - 0x589E, 0x6307, 0x660E, 0x671D, 0x671F, 0x6784, 0x7269, 0x786E, - 0x79CD, 0x8ABF, 0x8C03, 0x8CBB, 0x8D39, 0x90A3, 0x90FD, 0x9593, -/* right unfill */ - 0x95F4 - } - } -/* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ -#endif - }; -/* 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; -/* 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; -/* same as points.y */ - FT_Pos best_pos; - 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; -/* make compiler happy */ - best_pos = 0; - { - 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 AF_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 AF_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 = AF_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; - AF_Segment link1; - FT_Pos dist2 = 0; - do - { - 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++ ) - { -/* does it contain round segments? */ - FT_Int is_round = 0; -/* does it contain straight segments? */ - FT_Int is_straight = 0; - 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; -/* initial threshold */ - FT_Pos best_dist0; -/* compute the initial threshold as a fraction of the EM size */ - best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); -/* maximum 1/2 pixel */ - if ( best_dist0 > 64 / 2 ) - 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; - 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 -/* 0 */ -#endif - 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 ) ) ) - { - 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[] = - { -/* Hangul Jamo */ - AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), -/* CJK Radicals Supplement */ - AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), -/* Kangxi Radicals */ - AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), -/* Ideographic Description Characters */ - AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), -/* CJK Symbols and Punctuation */ - AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), -/* Hiragana */ - AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), -/* Katakana */ - AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), -/* Bopomofo */ - AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), -/* Hangul Compatibility Jamo */ - AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), -/* Kanbun */ - AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), -/* Bopomofo Extended */ - AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), -/* CJK Strokes */ - AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), -/* Katakana Phonetic Extensions */ - AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), -/* Enclosed CJK Letters and Months */ - AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), -/* CJK Compatibility */ - AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), -/* CJK Unified Ideographs Extension A */ - AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), -/* Yijing Hexagram Symbols */ - AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), -/* CJK Unified Ideographs */ - AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), -/* Hangul Jamo Extended-A */ - AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), -/* Hangul Syllables */ - AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), -/* Hangul Jamo Extended-B */ - AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), -/* CJK Compatibility Ideographs */ - AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), -/* Vertical forms */ - AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), -/* CJK Compatibility Forms */ - AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), -/* Halfwidth and Fullwidth Forms */ - AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), -/* Kana Supplement */ - AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), -/* Tai Xuan Hing Symbols */ - AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), -/* Enclosed Ideographic Supplement */ - AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ), -/* CJK Unified Ideographs Extension B */ - AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), -/* CJK Unified Ideographs Extension C */ - AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), -/* CJK Unified Ideographs Extension D */ - AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), -/* CJK Compatibility Ideographs Supplement */ - AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), - 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 - ) -/* END */ -/***************************************************************************/ -/* */ -/* afindic.c */ -/* */ -/* Auto-fitter hinting routines for Indic scripts (body). */ -/* */ -/* Copyright 2007, 2011, 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. */ -/* */ -/***************************************************************************/ - 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 AF_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 -/* why this? */ - AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), -#endif -/* Indic Range */ - AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), -/* Tibetan */ - AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL), -/* Limbu */ - AF_UNIRANGE_REC( 0x1900UL, 0x194FUL), -/* Sundanese */ - AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL), -/* Meetei Mayak */ - AF_UNIRANGE_REC( 0x1C80UL, 0x1CDFUL), -/* Syloti Nagri */ - AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL), -/* Sharada */ - AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL), - AF_UNIRANGE_REC( 0UL, 0UL) - }; - AF_DEFINE_SCRIPT_CLASS( af_indic_script_class, - AF_SCRIPT_INDIC, - af_indic_uniranges, -/* XXX */ - 'o', - 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 - ) -/* END */ -/***************************************************************************/ -/* */ -/* afloader.c */ -/* */ -/* Auto-fitter glyph loading routines (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -/* 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 ); - 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 = AF_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; - 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]; -/* leftmost edge */ - AF_Edge edge1 = axis->edges; - AF_Edge edge2 = edge1 + -/* rightmost edge */ - axis->num_edges - 1; - 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 = AF_Err_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 = AF_Err_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 AF_Err_Invalid_Argument; - FT_ZERO( &scaler ); - scaler.face = face; - scaler.x_scale = size->metrics.x_scale; -/* XXX: TODO: add support for sub-pixel hinting */ - scaler.x_delta = 0; - scaler.y_scale = size->metrics.y_scale; -/* XXX: TODO: add support for sub-pixel hinting */ - scaler.y_delta = 0; - scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); -/* XXX: fix this */ - scaler.flags = 0; - 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 */ -/***************************************************************************/ -/* */ -/* afmodule.c */ -/* */ -/* Auto-fitter module implementation (body). */ -/* */ -/* Copyright 2003-2006, 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. */ -/* */ -/***************************************************************************/ -/***************************************************************************/ -/* */ -/* ftautoh.h */ -/* */ -/* FreeType API for controlling the auto-hinter (specification only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ -#define __FTAUTOH_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: - * 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: - * 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: - * 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: - * 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 -/* END */ -/*************************************************************************/ -/* */ -/* 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 = AF_Err_Ok; - AF_FaceGlobals globals; - if ( !face ) - return AF_Err_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 = AF_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_get: missing property `%s'\n", - property_name )); - return AF_Err_Missing_Property; - } - FT_Error - af_property_get( FT_Module ft_module, - const char* property_name, - void* value ) - { - FT_Error error = AF_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 AF_Err_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 */ - FT_UNUSED( module ); - return ft_service_list_lookup( AF_SERVICES_GET, module_interface ); - } - FT_CALLBACK_DEF( FT_Error ) - af_autofitter_init( AF_Module module ) - { - module->fallback_script = AF_SCRIPT_FALLBACK; - return af_loader_init( module ); - } - FT_CALLBACK_DEF( void ) - af_autofitter_done( AF_Module 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, -/* reset_face */ - NULL, -/* get_global_hints */ - NULL, -/* done_global_hints */ - NULL, -/* load_glyph */ - (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph ) - FT_DEFINE_MODULE( - autofit_module_class, - FT_MODULE_HINTER, - sizeof ( AF_ModuleRec ), - "autofitter", -/* version 1.0 of the autofitter */ - 0x10000L, -/* requires FreeType 2.0 or above */ - 0x20000L, - (const void*)&AF_INTERFACE_GET, - (FT_Module_Constructor)af_autofitter_init, - (FT_Module_Destructor) af_autofitter_done, - (FT_Module_Requester) af_get_interface ) -/* END */ -/* END */ - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif // defined(_MSC_VER) diff --git a/examples/10-font/font.cpp b/examples/10-font/font.cpp index 7947c2cc1..720135130 100644 --- a/examples/10-font/font.cpp +++ b/examples/10-font/font.cpp @@ -87,6 +87,10 @@ public: , 0 ); + // Initialize Imgui + // This initializes the same allocator used by stb_truetype, so must do that before creating the font manager + imguiCreate(); + // Init the text rendering system. m_fontManager = new FontManager(512); m_textBufferManager = new TextBufferManager(m_fontManager); @@ -186,8 +190,6 @@ public: // Create a transient buffer for real-time data. m_transientText = m_textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Transient); - - imguiCreate(); } virtual int shutdown() override diff --git a/examples/11-fontsdf/fontsdf.cpp b/examples/11-fontsdf/fontsdf.cpp index 6cbe71d82..d9cbd5f0a 100644 --- a/examples/11-fontsdf/fontsdf.cpp +++ b/examples/11-fontsdf/fontsdf.cpp @@ -70,7 +70,8 @@ public: , 0 ); - // Imgui. + // Initialize Imgui + // This initializes the same allocator used by stb_truetype, so must do that before creating the font manager imguiCreate(); uint32_t size; diff --git a/examples/common/font/font_manager.cpp b/examples/common/font/font_manager.cpp index 13c92ce2e..ba7cad434 100644 --- a/examples/common/font/font_manager.cpp +++ b/examples/common/font/font_manager.cpp @@ -5,22 +5,7 @@ #include <bx/bx.h> -#if BX_COMPILER_MSVC -# define generic GenericFromFreeType // WinRT language extensions see "generic" as a keyword... this is stupid -#endif // BX_COMPILER_MSVC - -BX_PRAGMA_DIAGNOSTIC_PUSH(); -BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4245) // error C4245: '=' : conversion from 'int' to 'FT_UInt', signed/unsigned mismatch -BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4611) // warning C4611 : interaction between '_setjmp' and C++ object destruction is non - portable -#if BX_COMPILER_MSVC || BX_COMPILER_GCC >= 40300 -#pragma push_macro("interface") -#endif -#undef interface -#include <freetype/freetype.h> -#if BX_COMPILER_MSVC || BX_COMPILER_GCC >= 40300 -#pragma pop_macro("interface") -#endif -BX_PRAGMA_DIAGNOSTIC_POP(); +#include <stb/stb_truetype.h> #include "../common.h" @@ -38,11 +23,6 @@ namespace stl = tinystl; #include "font_manager.h" #include "../cube_atlas.h" -struct FTHolder -{ - FT_Library library; - FT_Face face; -}; class TrueTypeFont { @@ -63,33 +43,22 @@ public: /// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char) bool bakeGlyphAlpha(CodePoint _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer); - /// raster a glyph as 32bit subpixel rgba to a memory buffer - /// update the GlyphInfo according to the raster strategy - /// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(uint32_t) - bool bakeGlyphSubpixel(CodePoint _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer); - /// raster a glyph as 8bit signed distance to a memory buffer /// update the GlyphInfo according to the raster strategy /// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char) bool bakeGlyphDistance(CodePoint _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer); private: - FTHolder* m_font; + stbtt_fontinfo m_font; + float m_scale; }; -TrueTypeFont::TrueTypeFont() : m_font(NULL) +TrueTypeFont::TrueTypeFont() : m_font() { } TrueTypeFont::~TrueTypeFont() { - if (NULL != m_font) - { - FT_Done_Face(m_font->face); - FT_Done_FreeType(m_font->library); - delete m_font; - m_font = NULL; - } } bool TrueTypeFont::init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _fontIndex, uint32_t _pixelHeight) @@ -97,171 +66,74 @@ bool TrueTypeFont::init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _f BX_CHECK(m_font == NULL, "TrueTypeFont already initialized"); BX_CHECK( (_bufferSize > 256 && _bufferSize < 100000000), "TrueType buffer size is suspicious"); BX_CHECK( (_pixelHeight > 4 && _pixelHeight < 128), "TrueType buffer size is suspicious"); + BX_UNUSED(_bufferSize); - FTHolder* holder = new FTHolder; + int offset = stbtt_GetFontOffsetForIndex(_buffer, _fontIndex); - FT_Error error = FT_Init_FreeType(&holder->library); - BX_WARN(!error, "FT_Init_FreeType failed."); + stbtt_InitFont(&m_font, _buffer, offset); - if (error) - { - goto err0; - } + m_scale = stbtt_ScaleForMappingEmToPixels(&m_font, (float)_pixelHeight); - error = FT_New_Memory_Face(holder->library, _buffer, _bufferSize, _fontIndex, &holder->face); - BX_WARN(!error, "FT_Init_FreeType failed."); - - if (error) - { - if (FT_Err_Unknown_File_Format == error) - { - goto err0; - } - - goto err1; - } - - error = FT_Select_Charmap(holder->face, FT_ENCODING_UNICODE); - BX_WARN(!error, "FT_Init_FreeType failed."); - - if (error) - { - goto err2; - } - - error = FT_Set_Pixel_Sizes(holder->face, 0, _pixelHeight); - BX_WARN(!error, "FT_Init_FreeType failed."); - - if (error) - { - goto err2; - } - - m_font = holder; return true; - -err2: - FT_Done_Face(holder->face); - -err1: - FT_Done_FreeType(holder->library); - -err0: - delete holder; - return false; } FontInfo TrueTypeFont::getFontInfo() { BX_CHECK(m_font != NULL, "TrueTypeFont not initialized"); - BX_CHECK(FT_IS_SCALABLE(m_font->face), "Font is unscalable"); - FT_Size_Metrics metrics = m_font->face->size->metrics; + int ascent; + int descent; + int lineGap; + stbtt_GetFontVMetrics(&m_font, &ascent, &descent, &lineGap); + + float scale = m_scale; + + int x0, y0, x1, y1; + stbtt_GetFontBoundingBox(&m_font, &x0, &y0, &x1, &y1); FontInfo outFontInfo; outFontInfo.scale = 1.0f; - outFontInfo.ascender = metrics.ascender / 64.0f; - outFontInfo.descender = metrics.descender / 64.0f; - outFontInfo.lineGap = (metrics.height - metrics.ascender + metrics.descender) / 64.0f; - outFontInfo.maxAdvanceWidth = metrics.max_advance/ 64.0f; + outFontInfo.ascender = bx::round(ascent * scale); + outFontInfo.descender = bx::round(descent * scale); + outFontInfo.lineGap = bx::round(lineGap * scale); + outFontInfo.maxAdvanceWidth = bx::round((y1 - y0) * scale); - outFontInfo.underlinePosition = FT_MulFix(m_font->face->underline_position, metrics.y_scale) / 64.0f; - outFontInfo.underlineThickness = FT_MulFix(m_font->face->underline_thickness, metrics.y_scale) / 64.0f; + outFontInfo.underlinePosition = (x1 - x0) * scale - ascent; + outFontInfo.underlineThickness = (x1 - x0) * scale / 24.f; return outFontInfo; } -static void glyphInfoInit(GlyphInfo& _glyphInfo, FT_BitmapGlyph _bitmap, FT_GlyphSlot _slot, uint8_t* _dst, uint32_t _bpp) -{ - int32_t xx = _bitmap->left; - int32_t yy = -_bitmap->top; - int32_t ww = _bitmap->bitmap.width; - int32_t hh = _bitmap->bitmap.rows; - - _glyphInfo.offset_x = (float)xx; - _glyphInfo.offset_y = (float)yy; - _glyphInfo.width = (float)ww; - _glyphInfo.height = (float)hh; - _glyphInfo.advance_x = (float)_slot->advance.x / 64.0f; - _glyphInfo.advance_y = (float)_slot->advance.y / 64.0f; - - uint32_t dstPitch = ww * _bpp; - - uint8_t* src = _bitmap->bitmap.buffer; - uint32_t srcPitch = _bitmap->bitmap.pitch; - - for (int32_t ii = 0; ii < hh; ++ii) - { - bx::memCopy(_dst, src, dstPitch); - - _dst += dstPitch; - src += srcPitch; - } -} - bool TrueTypeFont::bakeGlyphAlpha(CodePoint _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer) { BX_CHECK(m_font != NULL, "TrueTypeFont not initialized"); - _glyphInfo.glyphIndex = FT_Get_Char_Index(m_font->face, _codePoint); + int xx; + int yy; + int ww; + int hh; + int advance; + int ascent; + int descent; + int lineGap; + int lsb; - FT_GlyphSlot slot = m_font->face->glyph; - FT_Error error = FT_Load_Glyph(m_font->face, _glyphInfo.glyphIndex, FT_LOAD_DEFAULT); - if (error) - { - return false; - } + float scale = m_scale; - FT_Glyph glyph; - error = FT_Get_Glyph(slot, &glyph); - if (error) - { - return false; - } + stbtt_GetFontVMetrics(&m_font, &ascent, &descent, &lineGap); + stbtt_GetCodepointHMetrics(&m_font, _codePoint, &advance, &lsb); + stbtt_GetCodepointBitmap(&m_font, scale, scale, _codePoint, &ww, &hh, &xx, &yy); - error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); - if (error) - { - return false; - } + _glyphInfo.offset_x = (float)xx; + _glyphInfo.offset_y = (float)yy; + _glyphInfo.width = (float)ww; + _glyphInfo.height = (float)hh; + _glyphInfo.advance_x = bx::round(((float)advance) * scale); + _glyphInfo.advance_y = bx::round(((float)(ascent + descent + lineGap)) * scale); - FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph; + uint32_t bpp = 1; + uint32_t dstPitch = ww * bpp; - glyphInfoInit(_glyphInfo, bitmap, slot, _outBuffer, 1); - - FT_Done_Glyph(glyph); - return true; -} - -bool TrueTypeFont::bakeGlyphSubpixel(CodePoint _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer) -{ - BX_CHECK(m_font != NULL, "TrueTypeFont not initialized"); - - _glyphInfo.glyphIndex = FT_Get_Char_Index(m_font->face, _codePoint); - - FT_GlyphSlot slot = m_font->face->glyph; - FT_Error error = FT_Load_Glyph(m_font->face, _glyphInfo.glyphIndex, FT_LOAD_DEFAULT); - if (error) - { - return false; - } - - FT_Glyph glyph; - error = FT_Get_Glyph(slot, &glyph); - if (error) - { - return false; - } - - error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_LCD, 0, 1); - if (error) - { - return false; - } - - FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph; - - glyphInfoInit(_glyphInfo, bitmap, slot, _outBuffer, 3); - FT_Done_Glyph(glyph); + stbtt_MakeCodepointBitmap(&m_font, _outBuffer, ww, hh, dstPitch, scale, scale, _codePoint); return true; } @@ -270,39 +142,33 @@ bool TrueTypeFont::bakeGlyphDistance(CodePoint _codePoint, GlyphInfo& _glyphInfo { BX_CHECK(m_font != NULL, "TrueTypeFont not initialized"); - _glyphInfo.glyphIndex = FT_Get_Char_Index(m_font->face, _codePoint); + int32_t xx; + int32_t yy; + int32_t ww; + int32_t hh; + int advance; + int ascent; + int descent; + int lineGap; + int lsb; - FT_Int32 loadMode = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - FT_Render_Mode renderMode = FT_RENDER_MODE_NORMAL; + float scale = m_scale; - FT_GlyphSlot slot = m_font->face->glyph; - FT_Error error = FT_Load_Glyph(m_font->face, _glyphInfo.glyphIndex, loadMode); - if (error) - { - return false; - } + stbtt_GetFontVMetrics(&m_font, &ascent, &descent, &lineGap); + stbtt_GetCodepointHMetrics(&m_font, _codePoint, &advance, &lsb); + stbtt_GetCodepointBitmap(&m_font, scale, scale, _codePoint, &ww, &hh, &xx, &yy); - FT_Glyph glyph; - error = FT_Get_Glyph(slot, &glyph); - if (error) - { - return false; - } + _glyphInfo.offset_x = (float)xx; + _glyphInfo.offset_y = (float)yy; + _glyphInfo.width = (float)ww; + _glyphInfo.height = (float)hh; + _glyphInfo.advance_x = bx::round(((float)advance) * scale); + _glyphInfo.advance_y = bx::round(((float)(ascent + descent + lineGap)) * scale); - error = FT_Glyph_To_Bitmap(&glyph, renderMode, 0, 1); - if (error) - { - return false; - } + uint32_t bpp = 1; + uint32_t dstPitch = ww * bpp; - FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph; - - int32_t ww = bitmap->bitmap.width; - int32_t hh = bitmap->bitmap.rows; - - glyphInfoInit(_glyphInfo, bitmap, slot, _outBuffer, 1); - - FT_Done_Glyph(glyph); + stbtt_MakeCodepointBitmap(&m_font, _outBuffer, ww, hh, dstPitch, scale, scale, _codePoint); if (ww * hh > 0) { @@ -324,6 +190,7 @@ bool TrueTypeFont::bakeGlyphDistance(CodePoint _codePoint, GlyphInfo& _glyphInfo bx::memCopy(alphaImg + ii * nw + dw, _outBuffer + (ii - dh) * ww, ww); } + // stb_truetype has some builtin sdf functionality, we can investigate using that too sdfBuild(_outBuffer, nw, 8.0f, alphaImg, nw, nh, nw); free(alphaImg);