summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/3rdparty/freetype/freetype.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/3rdparty/freetype/freetype.h')
-rw-r--r--3rdparty/bgfx/3rdparty/freetype/freetype.h117440
1 files changed, 0 insertions, 117440 deletions
diff --git a/3rdparty/bgfx/3rdparty/freetype/freetype.h b/3rdparty/bgfx/3rdparty/freetype/freetype.h
deleted file mode 100644
index fb67c097b21..00000000000
--- a/3rdparty/bgfx/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__
-/*@***********************************************************************/
-/* */
-/* <Macro> */
-/* FT_BEGIN_HEADER */
-/* */
-/* <Description> */
-/* This macro is used in association with @FT_END_HEADER in header */
-/* files to ensure that the declarations within are properly */
-/* encapsulated in an `extern "C" { .. }' block when included from a */
-/* C++ compiler. */
-/* */
-#ifdef __cplusplus
-#define FT_BEGIN_HEADER extern "C" {
-#else
-/* nothing */
-#define FT_BEGIN_HEADER
-#endif
-/*@***********************************************************************/
-/* */
-/* <Macro> */
-/* FT_END_HEADER */
-/* */
-/* <Description> */
-/* This macro is used in association with @FT_BEGIN_HEADER in header */
-/* files to ensure that the declarations within are properly */
-/* encapsulated in an `extern "C" { .. }' block when included from a */
-/* C++ compiler. */
-/* */
-#ifdef __cplusplus
-#define FT_END_HEADER }
-#else
-/* nothing */
-#define FT_END_HEADER
-#endif
-/*************************************************************************/
-/* */
-/* Aliases for the FreeType 2 public and configuration files. */
-/* */
-/*************************************************************************/
-/*************************************************************************/
-/* */
-/* <Section> */
-/* header_file_macros */
-/* */
-/* <Title> */
-/* Header File Macros */
-/* */
-/* <Abstract> */
-/* Macro definitions used to #include specific header files. */
-/* */
-/* <Description> */
-/* The following macros are defined to the name of specific */
-/* FreeType~2 header files. They can be used directly in #include */
-/* statements as in: */
-/* */
-/* { */
-/* #include FT_FREETYPE_H */
-/* #include FT_MULTIPLE_MASTERS_H */
-/* #include FT_GLYPH_H */
-/* } */
-/* */
-/* There are several reasons why we are now using macros to name */
-/* public header files. The first one is that such macros are not */
-/* limited to the infamous 8.3~naming rule required by DOS (and */
-/* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */
-/* */
-/* The second reason is that it allows for more flexibility in the */
-/* way FreeType~2 is installed on a given system. */
-/* */
-/*************************************************************************/
-/* configuration files */
-/*************************************************************************
- *
- * @macro:
- * FT_CONFIG_CONFIG_H
- *
- * @description:
- * A macro used in #include statements to name the file containing
- * FreeType~2 configuration data.
- *
- */
-#ifndef FT_CONFIG_CONFIG_H
-#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h>
-#endif
-/*************************************************************************
- *
- * @macro:
- * FT_CONFIG_STANDARD_LIBRARY_H
- *
- * @description:
- * A macro used in #include statements to name the file containing
- * FreeType~2 interface to the standard C library functions.
- *
- */
-#ifndef FT_CONFIG_STANDARD_LIBRARY_H
-#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h>
-#endif
-/*************************************************************************
- *
- * @macro:
- * FT_CONFIG_OPTIONS_H
- *
- * @description:
- * A macro used in #include statements to name the file containing
- * FreeType~2 project-specific configuration options.
- *
- */
-#ifndef FT_CONFIG_OPTIONS_H
-#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h>
-#endif
-/*************************************************************************
- *
- * @macro:
- * FT_CONFIG_MODULES_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * list of FreeType~2 modules that are statically linked to new library
- * instances in @FT_Init_FreeType.
- *
- */
-#ifndef FT_CONFIG_MODULES_H
-#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h>
-#endif
-/* */
-/* public headers */
-/*************************************************************************
- *
- * @macro:
- * FT_FREETYPE_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * base FreeType~2 API.
- *
- */
-#define FT_FREETYPE_H <freetype/freetype.h>
-/*************************************************************************
- *
- * @macro:
- * FT_ERRORS_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * list of FreeType~2 error codes (and messages).
- *
- * It is included by @FT_FREETYPE_H.
- *
- */
-#define FT_ERRORS_H <freetype/fterrors.h>
-/*************************************************************************
- *
- * @macro:
- * FT_MODULE_ERRORS_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * list of FreeType~2 module error offsets (and messages).
- *
- */
-#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h>
-/*************************************************************************
- *
- * @macro:
- * FT_SYSTEM_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * FreeType~2 interface to low-level operations (i.e., memory management
- * and stream i/o).
- *
- * It is included by @FT_FREETYPE_H.
- *
- */
-#define FT_SYSTEM_H <freetype/ftsystem.h>
-/*************************************************************************
- *
- * @macro:
- * FT_IMAGE_H
- *
- * @description:
- * A macro used in #include statements to name the file containing type
- * definitions related to glyph images (i.e., bitmaps, outlines,
- * scan-converter parameters).
- *
- * It is included by @FT_FREETYPE_H.
- *
- */
-#define FT_IMAGE_H <freetype/ftimage.h>
-/*************************************************************************
- *
- * @macro:
- * FT_TYPES_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * basic data types defined by FreeType~2.
- *
- * It is included by @FT_FREETYPE_H.
- *
- */
-#define FT_TYPES_H <freetype/fttypes.h>
-/*************************************************************************
- *
- * @macro:
- * FT_LIST_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * list management API of FreeType~2.
- *
- * (Most applications will never need to include this file.)
- *
- */
-#define FT_LIST_H <freetype/ftlist.h>
-/*************************************************************************
- *
- * @macro:
- * FT_OUTLINE_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * scalable outline management API of FreeType~2.
- *
- */
-#define FT_OUTLINE_H <freetype/ftoutln.h>
-/*************************************************************************
- *
- * @macro:
- * FT_SIZES_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * API which manages multiple @FT_Size objects per face.
- *
- */
-#define FT_SIZES_H <freetype/ftsizes.h>
-/*************************************************************************
- *
- * @macro:
- * FT_MODULE_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * module management API of FreeType~2.
- *
- */
-#define FT_MODULE_H <freetype/ftmodapi.h>
-/*************************************************************************
- *
- * @macro:
- * FT_RENDER_H
- *
- * @description:
- * A macro used in #include statements to name the file containing the
- * renderer module management API of FreeType~2.
- *
- */
-#define FT_RENDER_H <freetype/ftrender.h>
-/*************************************************************************
- *
- * @macro:
- * FT_AUTOHINTER_H
- *
- * @description:
- * A macro used in #include statements to name the file containing
- * structures and macros related to the auto-hinting module.
- *
- */
-#define FT_AUTOHINTER_H <freetype/ftautoh.h>
-/*************************************************************************
- *
- * @macro:
- * FT_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 = &parameter; */
-/* */
-/* 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 = &parameter; // 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, &params );
- }
-/* 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, &copy );
- 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, &registry );
- }
- 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, &copy );
- 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, &copy );
- 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", &registry );
- if ( !error )
- {
- error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
- if ( !error )
- {
- if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
- encoding.type == BDF_PROPERTY_TYPE_ATOM )
- {
- *acharset_encoding = encoding.u.atom;
- *acharset_registry = registry.u.atom;
- }
- else
- error = 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 = &current->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 = &current->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 = &current->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, &params );
- 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, &params );
-/* 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)