android-native: real-server login by default, readable CJK text, 16 KB pages

- FreeType: add the cff/psaux/pshinter modules (from the pinned 2.13.3
  tarball, same sha256). Android's only CJK font is the CFF2
  NotoSansCJK-Regular.ttc, which the TrueType-only build could not open,
  so every Chinese glyph drew as a box.
- Font oversample rounds the UI density up: Android's 1760x800 UI on a
  2376x1080 screen is 1.35, which rounded to 1x bilevel glyphs stretched
  1.35x. Now 2x anti-aliased glyphs are scaled down. macOS 2.0 unchanged.
- MainActivity: a launcher start (no intent args) opens the login screen
  against 192.168.21.203 instead of auto-logging into the in-process fake
  server; explicit args still select the fake-server smoke flow.
- build-android-native.sh: ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON for SDL3
  and libmain (LOAD alignment 0x1000 -> 0x4000), with a stamp that
  rebuilds a cached pre-flag SDL3. Clears Android's 16 KB compat warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-29 12:16:38 +09:00
co-authored by Claude Opus 5.5
parent 3c52ced02e
commit 53d06c3c26
73 changed files with 33280 additions and 10 deletions
@@ -15,9 +15,13 @@ import org.libsdl.app.SDLActivity;
* Runs native_render's main() (libmain.so). Command-line arguments come from the launch intent, * Runs native_render's main() (libmain.so). Command-line arguments come from the launch intent,
* e.g. adb shell am start -n org.metin2port.client/.MainActivity \ * e.g. adb shell am start -n org.metin2port.client/.MainActivity \
* --es args "--live-server 192.168.21.203:11000:13000 --login-screen" * --es args "--live-server 192.168.21.203:11000:13000 --login-screen"
* Without arguments the client runs against the in-process fake server once Client/ is in files/. * A launcher start (no arguments) opens the login screen against DEFAULT_ARGS' server, so the
* installed app is played by hand on the real server. Any explicit args replace DEFAULT_ARGS; args
* without --live-server (e.g. --es args "--fake-mobs 64") run the in-process fake-server smoke flow.
*/ */
public class MainActivity extends SDLActivity { public class MainActivity extends SDLActivity {
private static final String DEFAULT_ARGS = "--live-server 192.168.21.203:11000:13000 --login-screen";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -70,7 +74,7 @@ public class MainActivity extends SDLActivity {
String args = intent != null ? intent.getStringExtra("args") : null; String args = intent != null ? intent.getStringExtra("args") : null;
Log.i("Metin2Args", "native args: " + args); Log.i("Metin2Args", "native args: " + args);
if (args == null || args.trim().isEmpty()) if (args == null || args.trim().isEmpty())
return new String[0]; args = DEFAULT_ARGS;
return args.trim().split("\\s+"); return args.trim().split("\\s+");
} }
+8 -3
View File
@@ -45,18 +45,23 @@ if [ ! -f "$SDL_SRC/CMakeLists.txt" ]; then
echo "$SDL_SHA256 $tarball" | shasum -a 256 -c - echo "$SDL_SHA256 $tarball" | shasum -a 256 -c -
tar xzf "$tarball" -C "$OUT/_deps" tar xzf "$tarball" -C "$OUT/_deps"
fi fi
if [ ! -f "$OUT/sdl3/lib/libSDL3.so" ]; then # 16 KB page alignment (Android 15+ devices check it): NDK r27 links with max-page-size=16384 when
# ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES is on. The stamp rebuilds an SDL3 cached from before the flag.
PAGE_SIZES=-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON
if [ ! -f "$OUT/sdl3/lib/libSDL3.so" ] || [ ! -f "$OUT/sdl3/.page16k" ]; then
rm -rf "$OUT/sdl3-build" "$OUT/sdl3"
cmake -S "$SDL_SRC" -B "$OUT/sdl3-build" -G "Unix Makefiles" \ cmake -S "$SDL_SRC" -B "$OUT/sdl3-build" -G "Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM="android-$API" \ -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM="android-$API" "$PAGE_SIZES" \
-DCMAKE_BUILD_TYPE=Release -DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_TEST_LIBRARY=OFF \ -DCMAKE_BUILD_TYPE=Release -DSDL_SHARED=ON -DSDL_STATIC=OFF -DSDL_TEST_LIBRARY=OFF \
-DSDL_TESTS=OFF -DSDL_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX="$OUT/sdl3" -DSDL_TESTS=OFF -DSDL_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX="$OUT/sdl3"
cmake --build "$OUT/sdl3-build" -j "$JOBS" cmake --build "$OUT/sdl3-build" -j "$JOBS"
cmake --install "$OUT/sdl3-build" cmake --install "$OUT/sdl3-build"
touch "$OUT/sdl3/.page16k"
fi fi
# --- libmain.so (native_render + port_platform + embedded Python) and its assets --- # --- libmain.so (native_render + port_platform + embedded Python) and its assets ---
cmake -S . -B "$OUT/app-build" -G "Unix Makefiles" -Wno-deprecated \ cmake -S . -B "$OUT/app-build" -G "Unix Makefiles" -Wno-deprecated \
-DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM="android-$API" \ -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM="android-$API" "$PAGE_SIZES" \
-DCMAKE_BUILD_TYPE="$CONFIG" -DMT_BUILD_TOOLS=OFF -DBUILD_TESTING=OFF \ -DCMAKE_BUILD_TYPE="$CONFIG" -DMT_BUILD_TOOLS=OFF -DBUILD_TESTING=OFF \
-DMT_BUILD_NATIVE_RENDER=ON -DSDL3_DIR="$OUT/sdl3/lib/cmake/SDL3" \ -DMT_BUILD_NATIVE_RENDER=ON -DSDL3_DIR="$OUT/sdl3/lib/cmake/SDL3" \
-DCMAKE_FIND_ROOT_PATH="$OUT/sdl3" -DGLSLC="$GLSLC" >/dev/null -DCMAKE_FIND_ROOT_PATH="$OUT/sdl3" -DGLSLC="$GLSLC" >/dev/null
+6 -2
View File
@@ -1,8 +1,9 @@
# FreeType 2.13.3, trimmed to the modules the platform font adapter needs # FreeType 2.13.3, trimmed to the modules the platform font adapter needs
# (EterLib/GrpFontTexture: TrueType faces, bytecode hinting, mono + gray rasterizers). # (EterLib/GrpFontTexture: TrueType and CFF/CFF2 faces, hinting, mono + gray rasterizers).
# CFF is needed on Android, whose only CJK fallback is the CFF2 NotoSansCJK-Regular.ttc.
# Source: https://download.savannah.gnu.org/releases/freetype/freetype-2.13.3.tar.xz # Source: https://download.savannah.gnu.org/releases/freetype/freetype-2.13.3.tar.xz
# sha256 0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 # sha256 0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289
# Kept: include/, src/{base,sfnt,truetype,smooth,raster,psnames,gzip}, LICENSE.TXT, docs/FTL.TXT. # Kept: include/, src/{base,sfnt,truetype,cff,psaux,pshinter,smooth,raster,psnames,gzip}, LICENSE.TXT, docs/FTL.TXT.
# mt-config/freetype/config/ftmodule.h replaces the stock module list. # mt-config/freetype/config/ftmodule.h replaces the stock module list.
set(dir "${CMAKE_CURRENT_SOURCE_DIR}") set(dir "${CMAKE_CURRENT_SOURCE_DIR}")
add_library(freetype STATIC add_library(freetype STATIC
@@ -17,6 +18,9 @@ add_library(freetype STATIC
${dir}/src/base/ftmm.c ${dir}/src/base/ftmm.c
${dir}/src/sfnt/sfnt.c ${dir}/src/sfnt/sfnt.c
${dir}/src/truetype/truetype.c ${dir}/src/truetype/truetype.c
${dir}/src/cff/cff.c
${dir}/src/psaux/psaux.c
${dir}/src/pshinter/pshinter.c
${dir}/src/smooth/smooth.c ${dir}/src/smooth/smooth.c
${dir}/src/raster/raster.c ${dir}/src/raster/raster.c
${dir}/src/psnames/psnames.c ${dir}/src/psnames/psnames.c
@@ -1,8 +1,11 @@
/* Modules linked into the mtgodot FreeType build (see extension/third_party/freetype-2.13.3/CMakeLists.txt): /* Modules linked into the mtgodot FreeType build (see extension/third_party/freetype-2.13.3/CMakeLists.txt):
TrueType fonts only, the bytecode hinter, and the mono/gray rasterizers. */ TrueType and CFF/CFF2 fonts (Android's CJK fallback is CFF2), their hinters, and the mono/gray rasterizers. */
FT_USE_MODULE( FT_Module_Class, psnames_module_class ) FT_USE_MODULE( FT_Module_Class, psnames_module_class )
FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
FT_USE_MODULE( FT_Module_Class, psaux_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_Renderer_Class, ft_raster1_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
/* EOF */ /* EOF */
+28
View File
@@ -0,0 +1,28 @@
/****************************************************************************
*
* cff.c
*
* FreeType OpenType driver component (body only).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "cffcmap.c"
#include "cffdrivr.c"
#include "cffgload.c"
#include "cffparse.c"
#include "cffload.c"
#include "cffobjs.c"
/* END */
+230
View File
@@ -0,0 +1,230 @@
/****************************************************************************
*
* cffcmap.c
*
* CFF character mapping table (cmap) support (body).
*
* Copyright (C) 2002-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include <freetype/internal/ftdebug.h>
#include "cffcmap.h"
#include "cffload.h"
#include "cfferrs.h"
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
cff_cmap_encoding_init( FT_CMap cmap,
FT_Pointer pointer )
{
CFF_CMapStd cffcmap = (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;
FT_UNUSED( pointer );
cffcmap->gids = encoding->codes;
return 0;
}
FT_CALLBACK_DEF( void )
cff_cmap_encoding_done( FT_CMap cmap )
{
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
cffcmap->gids = NULL;
}
FT_CALLBACK_DEF( FT_UInt )
cff_cmap_encoding_char_index( FT_CMap cmap,
FT_UInt32 char_code )
{
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
FT_UInt result = 0;
if ( char_code < 256 )
result = cffcmap->gids[char_code];
return result;
}
FT_CALLBACK_DEF( FT_UInt )
cff_cmap_encoding_char_next( FT_CMap cmap,
FT_UInt32 *pchar_code )
{
CFF_CMapStd cffcmap = (CFF_CMapStd)cmap;
FT_UInt result = 0;
FT_UInt32 char_code = *pchar_code;
while ( char_code < 255 )
{
result = cffcmap->gids[++char_code];
if ( result )
{
*pchar_code = char_code;
break;
}
}
return result;
}
FT_DEFINE_CMAP_CLASS(
cff_cmap_encoding_class_rec,
sizeof ( CFF_CMapStdRec ),
(FT_CMap_InitFunc) cff_cmap_encoding_init, /* init */
(FT_CMap_DoneFunc) cff_cmap_encoding_done, /* done */
(FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, /* char_index */
(FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
)
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( const char* )
cff_sid_to_glyph_name( void* face_, /* TT_Face */
FT_UInt idx )
{
TT_Face face = (TT_Face)face_;
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( FT_CMap cmap, /* PS_Unicodes */
FT_Pointer pointer )
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
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;
FT_UNUSED( pointer );
/* can't build Unicode map for CID-keyed font */
/* because we don't know glyph names. */
if ( !charset->sids )
return FT_THROW( No_Unicode_Glyph_Name );
if ( !psnames->unicodes_init )
return FT_THROW( Unimplemented_Feature );
return psnames->unicodes_init( memory,
unicodes,
cff->num_glyphs,
&cff_sid_to_glyph_name,
(PS_FreeGlyphNameFunc)NULL,
(FT_Pointer)face );
}
FT_CALLBACK_DEF( void )
cff_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
FT_Face face = FT_CMAP_FACE( cmap );
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( FT_CMap cmap, /* PS_Unicodes */
FT_UInt32 char_code )
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
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_UInt )
cff_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */
FT_UInt32 *pchar_code )
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
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, /* init */
(FT_CMap_DoneFunc) cff_cmap_unicode_done, /* done */
(FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, /* char_index */
(FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
)
/* END */
+67
View File
@@ -0,0 +1,67 @@
/****************************************************************************
*
* cffcmap.h
*
* CFF character mapping table (cmap) support (specification).
*
* Copyright (C) 2002-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFCMAP_H_
#define CFFCMAP_H_
#include <freetype/internal/cffotypes.h>
FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* standard (and expert) encoding cmaps */
typedef struct CFF_CMapStdRec_* CFF_CMapStd;
typedef struct CFF_CMapStdRec_
{
FT_CMapRec cmap;
FT_UShort* gids; /* up to 256 elements */
} CFF_CMapStdRec;
FT_DECLARE_CMAP_CLASS( cff_cmap_encoding_class_rec )
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* unicode (synthetic) cmaps */
FT_DECLARE_CMAP_CLASS( cff_cmap_unicode_class_rec )
FT_END_HEADER
#endif /* CFFCMAP_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
/****************************************************************************
*
* cffdrivr.h
*
* High-level OpenType driver interface (specification).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFDRIVER_H_
#define CFFDRIVER_H_
#include <freetype/internal/ftdrv.h>
FT_BEGIN_HEADER
FT_DECLARE_DRIVER( cff_driver_class )
FT_END_HEADER
#endif /* CFFDRIVER_H_ */
/* END */
+42
View File
@@ -0,0 +1,42 @@
/****************************************************************************
*
* cfferrs.h
*
* CFF error codes (specification only).
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file is used to define the CFF error enumeration constants.
*
*/
#ifndef CFFERRS_H_
#define CFFERRS_H_
#include <freetype/ftmoderr.h>
#undef FTERRORS_H_
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX CFF_Err_
#define FT_ERR_BASE FT_Mod_Err_CFF
#include <freetype/fterrors.h>
#endif /* CFFERRS_H_ */
/* END */
+762
View File
@@ -0,0 +1,762 @@
/****************************************************************************
*
* cffgload.c
*
* OpenType Glyph Loader (body).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/internal/sfnt.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/psaux.h>
#include <freetype/ftoutln.h>
#include <freetype/ftdriver.h>
#include "cffload.h"
#include "cffgload.h"
#include "cfferrs.h"
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#define IS_DEFAULT_INSTANCE( _face ) \
( !( FT_IS_NAMED_INSTANCE( _face ) || \
FT_IS_VARIATION( _face ) ) )
#else
#define IS_DEFAULT_INSTANCE( _face ) 1
#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 cffgload
FT_LOCAL_DEF( FT_Error )
cff_get_glyph_data( TT_Face face,
FT_UInt glyph_index,
FT_Byte** pointer,
FT_ULong* length )
{
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* For incremental fonts get the character data using the */
/* callback function. */
if ( face->root.internal->incremental_interface )
{
FT_Data data;
FT_Error error =
face->root.internal->incremental_interface->funcs->get_glyph_data(
face->root.internal->incremental_interface->object,
glyph_index, &data );
*pointer = (FT_Byte*)data.pointer;
*length = data.length;
return error;
}
else
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
{
CFF_Font cff = (CFF_Font)( face->extra.data );
return cff_index_access_element( &cff->charstrings_index, glyph_index,
pointer, length );
}
}
FT_LOCAL_DEF( void )
cff_free_glyph_data( TT_Face face,
FT_Byte** pointer,
FT_ULong length )
{
#ifndef FT_CONFIG_OPTION_INCREMENTAL
FT_UNUSED( length );
#endif
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* For incremental fonts get the character data using the */
/* callback function. */
if ( face->root.internal->incremental_interface )
{
FT_Data data;
data.pointer = *pointer;
data.length = (FT_UInt)length;
face->root.internal->incremental_interface->funcs->free_glyph_data(
face->root.internal->incremental_interface->object, &data );
}
else
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
{
CFF_Font cff = (CFF_Font)( face->extra.data );
cff_index_forget_element( &cff->charstrings_index, pointer );
}
}
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/********** *********/
/********** *********/
/********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
/********** *********/
/********** The following code is in charge of computing *********/
/********** the maximum advance width of the font. It *********/
/********** quickly processes each glyph charstring to *********/
/********** extract the value from either a `sbw' or `seac' *********/
/********** operator. *********/
/********** *********/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
#if 0 /* unused until we support pure CFF fonts */
FT_LOCAL_DEF( FT_Error )
cff_compute_max_advance( TT_Face face,
FT_Int* max_advance )
{
FT_Error error = FT_Err_Ok;
CFF_Decoder decoder;
FT_Int glyph_index;
CFF_Font cff = (CFF_Font)face->other;
PSAux_Service psaux = (PSAux_Service)face->psaux;
const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs;
*max_advance = 0;
/* Initialize load decoder */
decoder_funcs->init( &decoder, face, 0, 0, 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 = decoder_funcs->prepare( &decoder, size, glyph_index );
if ( !error )
error = decoder_funcs->parse_charstrings_old( &decoder,
charstring,
charstring_len,
0 );
cff_free_glyph_data( face, &charstring, &charstring_len );
}
/* ignore the error if one has occurred -- skip to next glyph */
error = FT_Err_Ok;
}
*max_advance = decoder.builder.advance.x;
return FT_Err_Ok;
}
#endif /* 0 */
FT_LOCAL_DEF( FT_Error )
cff_slot_load( CFF_GlyphSlot glyph,
CFF_Size size,
FT_UInt glyph_index,
FT_Int32 load_flags )
{
FT_Error error;
CFF_Decoder decoder;
PS_Decoder psdecoder;
TT_Face face = (TT_Face)glyph->root.face;
FT_Bool hinting, scaled, force_scaling;
CFF_Font cff = (CFF_Font)face->extra.data;
PSAux_Service psaux = (PSAux_Service)face->psaux;
const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs;
FT_Matrix font_matrix;
FT_Vector font_offset;
force_scaling = FALSE;
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
/* it immediately to the real glyph_index -- if it isn't a */
/* subsetted font, glyph_indices and CIDs are identical, though */
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
cff->charset.cids )
{
/* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
if ( glyph_index != 0 )
{
glyph_index = cff_charset_cid_to_gindex( &cff->charset,
glyph_index );
if ( glyph_index == 0 )
return FT_THROW( Invalid_Argument );
}
}
else if ( glyph_index >= cff->num_glyphs )
return FT_THROW( Invalid_Argument );
if ( load_flags & FT_LOAD_NO_RECURSE )
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
glyph->x_scale = 0x10000L;
glyph->y_scale = 0x10000L;
if ( size )
{
glyph->x_scale = size->root.metrics.x_scale;
glyph->y_scale = size->root.metrics.y_scale;
}
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* try to load embedded bitmap if any */
/* */
/* XXX: The convention should be emphasized in */
/* the documents because it can be confusing. */
if ( size )
{
CFF_Face cff_face = (CFF_Face)size->root.face;
SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt;
FT_Stream stream = cff_face->root.stream;
if ( size->strike_index != 0xFFFFFFFFUL &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
IS_DEFAULT_INSTANCE( size->root.face ) )
{
TT_SBit_MetricsRec metrics;
error = sfnt->load_sbit_image( face,
size->strike_index,
glyph_index,
(FT_UInt)load_flags,
stream,
&glyph->root.bitmap,
&metrics );
if ( !error )
{
FT_Bool has_vertical_info;
FT_UShort advance;
FT_Short dummy;
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
glyph->root.metrics.width = (FT_Pos)metrics.width * 64;
glyph->root.metrics.height = (FT_Pos)metrics.height * 64;
glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64;
glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64;
glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64;
glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64;
glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64;
glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64;
glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
{
glyph->root.bitmap_left = metrics.vertBearingX;
glyph->root.bitmap_top = metrics.vertBearingY;
}
else
{
glyph->root.bitmap_left = metrics.horiBearingX;
glyph->root.bitmap_top = metrics.horiBearingY;
}
/* compute linear advance widths */
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
glyph_index,
&dummy,
&advance );
glyph->root.linearHoriAdvance = advance;
has_vertical_info = FT_BOOL(
face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 );
/* get the vertical metrics from the vmtx table if we have one */
if ( has_vertical_info )
{
(void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
glyph_index,
&dummy,
&advance );
glyph->root.linearVertAdvance = advance;
}
else
{
/* make up vertical ones */
if ( face->os2.version != 0xFFFFU )
glyph->root.linearVertAdvance = (FT_Pos)
( face->os2.sTypoAscender - face->os2.sTypoDescender );
else
glyph->root.linearVertAdvance = (FT_Pos)
( face->horizontal.Ascender - face->horizontal.Descender );
}
return error;
}
}
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
/* return immediately if we only want the embedded bitmaps */
if ( load_flags & FT_LOAD_SBITS_ONLY )
return FT_THROW( Invalid_Argument );
#ifdef FT_CONFIG_OPTION_SVG
/* check for OT-SVG */
if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
( load_flags & FT_LOAD_COLOR ) &&
face->svg )
{
/*
* We load the SVG document and try to grab the advances from the
* table. For the bearings we rely on the presetting hook to do that.
*/
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
if ( size && (size->root.metrics.x_ppem < 1 ||
size->root.metrics.y_ppem < 1 ) )
{
error = FT_THROW( Invalid_Size_Handle );
return error;
}
FT_TRACE3(( "Trying to load SVG glyph\n" ));
error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
if ( !error )
{
FT_Fixed x_scale = size->root.metrics.x_scale;
FT_Fixed y_scale = size->root.metrics.y_scale;
FT_Short dummy;
FT_UShort advanceX;
FT_UShort advanceY;
FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
glyph->root.format = FT_GLYPH_FORMAT_SVG;
/*
* If horizontal or vertical advances are not present in the table,
* this is a problem with the font since the standard requires them.
* However, we are graceful and calculate the values by ourselves
* for the vertical case.
*/
sfnt->get_metrics( face,
FALSE,
glyph_index,
&dummy,
&advanceX );
sfnt->get_metrics( face,
TRUE,
glyph_index,
&dummy,
&advanceY );
glyph->root.linearHoriAdvance = advanceX;
glyph->root.linearVertAdvance = advanceY;
glyph->root.metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
glyph->root.metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
return error;
}
FT_TRACE3(( "Failed to load SVG glyph\n" ));
}
#endif /* FT_CONFIG_OPTION_SVG */
/* 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_Long top_upm, sub_upm;
FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
glyph_index );
if ( fd_index >= cff->num_subfonts )
fd_index = (FT_Byte)( cff->num_subfonts - 1 );
top_upm = (FT_Long)cff->top_font.font_dict.units_per_em;
sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em;
font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
if ( top_upm != sub_upm )
{
glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
force_scaling = TRUE;
}
}
else
{
font_matrix = cff->top_font.font_dict.font_matrix;
font_offset = cff->top_font.font_dict.font_offset;
}
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
/* top-level code ensures that FT_LOAD_NO_HINTING is set */
/* if FT_LOAD_NO_SCALE is active */
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
glyph->hint = hinting;
glyph->scaled = scaled;
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
{
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
#endif
FT_Byte* charstring;
FT_ULong charstring_len;
decoder_funcs->init( &decoder, face, size, glyph, hinting,
FT_LOAD_TARGET_MODE( load_flags ),
cff_get_glyph_data,
cff_free_glyph_data );
/* this is for pure CFFs */
if ( load_flags & FT_LOAD_ADVANCE_ONLY )
decoder.width_only = TRUE;
decoder.builder.no_recurse =
FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
/* this function also checks for a valid subfont index */
error = decoder_funcs->prepare( &decoder, size, glyph_index );
if ( error )
goto Glyph_Build_Finished;
/* now load the unscaled outline */
error = cff_get_glyph_data( face, glyph_index,
&charstring, &charstring_len );
if ( error )
goto Glyph_Build_Finished;
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
/* choose which CFF renderer to use */
if ( driver->hinting_engine == FT_HINTING_FREETYPE )
error = decoder_funcs->parse_charstrings_old( &decoder,
charstring,
charstring_len,
0 );
else
#endif
{
psaux->ps_decoder_init( &psdecoder, &decoder, FALSE );
error = decoder_funcs->parse_charstrings( &psdecoder,
charstring,
charstring_len );
/* Adobe's engine uses 16.16 numbers everywhere; */
/* as a consequence, glyphs larger than 2000ppem get rejected */
if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
{
/* this time, we retry unhinted and scale up the glyph later on */
/* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
/* 0x400 for both `x_scale' and `y_scale' in this case) */
hinting = FALSE;
force_scaling = TRUE;
glyph->hint = hinting;
error = decoder_funcs->parse_charstrings( &psdecoder,
charstring,
charstring_len );
}
}
cff_free_glyph_data( face, &charstring, charstring_len );
if ( error )
goto Glyph_Build_Finished;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Control data and length may not be available for incremental */
/* fonts. */
if ( face->root.internal->incremental_interface )
{
glyph->root.control_data = NULL;
glyph->root.control_len = 0;
}
else
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
/* We set control_data and control_len if charstrings is loaded. */
/* See how charstring loads at cff_index_access_element() in */
/* cffload.c. */
{
CFF_Index csindex = &cff->charstrings_index;
if ( csindex->offsets )
{
glyph->root.control_data = csindex->bytes +
csindex->offsets[glyph_index] - 1;
glyph->root.control_len = (FT_Long)charstring_len;
}
}
Glyph_Build_Finished:
/* save new glyph tables, if no error */
if ( !error )
decoder.builder.funcs.done( &decoder.builder );
/* XXX: anything to do for broken glyph entry? */
}
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Incremental fonts can optionally override the metrics. */
if ( !error &&
face->root.internal->incremental_interface &&
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
{
FT_Incremental_MetricsRec metrics;
metrics.bearing_x = decoder.builder.left_bearing.x;
metrics.bearing_y = 0;
metrics.advance = decoder.builder.advance.x;
metrics.advance_v = decoder.builder.advance.y;
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
face->root.internal->incremental_interface->object,
glyph_index, FALSE, &metrics );
decoder.builder.left_bearing.x = metrics.bearing_x;
decoder.builder.advance.x = metrics.advance;
decoder.builder.advance.y = metrics.advance_v;
}
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
if ( !error )
{
/* Now, set the metrics -- this is rather simple, as */
/* the left side bearing is the xMin, and the top side */
/* bearing the yMax. */
/* For composite glyphs, return only left side bearing and */
/* advance width. */
if ( load_flags & FT_LOAD_NO_RECURSE )
{
FT_Slot_Internal internal = glyph->root.internal;
glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
glyph->root.metrics.horiAdvance = decoder.glyph_width;
internal->glyph_matrix = font_matrix;
internal->glyph_delta = font_offset;
internal->glyph_transformed = 1;
}
else
{
FT_BBox cbox;
FT_Glyph_Metrics* metrics = &glyph->root.metrics;
FT_Bool has_vertical_info;
if ( face->horizontal.number_Of_HMetrics )
{
FT_Short horiBearingX = 0;
FT_UShort horiAdvance = 0;
( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
glyph_index,
&horiBearingX,
&horiAdvance );
metrics->horiAdvance = horiAdvance;
metrics->horiBearingX = horiBearingX;
glyph->root.linearHoriAdvance = horiAdvance;
}
else
{
/* copy the _unscaled_ advance width */
metrics->horiAdvance = decoder.glyph_width;
glyph->root.linearHoriAdvance = decoder.glyph_width;
}
glyph->root.internal->glyph_transformed = 0;
has_vertical_info = FT_BOOL( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 );
/* get the vertical metrics from the vmtx 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;
/* apply the font matrix, if any */
if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
font_matrix.xy != 0 || font_matrix.yx != 0 )
{
FT_Outline_Transform( &glyph->root.outline, &font_matrix );
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
font_matrix.xx );
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
font_matrix.yy );
}
if ( font_offset.x || font_offset.y )
{
FT_Outline_Translate( &glyph->root.outline,
font_offset.x,
font_offset.y );
metrics->horiAdvance += font_offset.x;
metrics->vertAdvance += 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;
metrics->vertBearingY = FT_MulFix( metrics->vertBearingY,
glyph->y_scale );
}
else
{
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
ft_synthesize_vertical_metrics( metrics,
metrics->vertAdvance );
}
}
}
return error;
}
/* END */
@@ -0,0 +1,62 @@
/****************************************************************************
*
* cffgload.h
*
* OpenType Glyph Loader (specification).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFGLOAD_H_
#define CFFGLOAD_H_
#include <freetype/freetype.h>
#include <freetype/internal/cffotypes.h>
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cff_get_glyph_data( TT_Face face,
FT_UInt glyph_index,
FT_Byte** pointer,
FT_ULong* length );
FT_LOCAL( void )
cff_free_glyph_data( TT_Face face,
FT_Byte** pointer,
FT_ULong length );
#if 0 /* unused until we support pure CFF fonts */
/* Compute the maximum advance width of a font through quick parsing */
FT_LOCAL( FT_Error )
cff_compute_max_advance( TT_Face face,
FT_Int* max_advance );
#endif /* 0 */
FT_LOCAL( FT_Error )
cff_slot_load( CFF_GlyphSlot glyph,
CFF_Size size,
FT_UInt glyph_index,
FT_Int32 load_flags );
FT_END_HEADER
#endif /* CFFGLOAD_H_ */
/* END */
File diff suppressed because it is too large Load Diff
+124
View File
@@ -0,0 +1,124 @@
/****************************************************************************
*
* cffload.h
*
* OpenType & CFF data/program tables loader (specification).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFLOAD_H_
#define CFFLOAD_H_
#include <freetype/internal/cfftypes.h>
#include "cffparse.h"
#include <freetype/internal/cffotypes.h> /* for CFF_Face */
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,
CFF_Face face,
FT_Bool pure_cff,
FT_Bool cff2 );
FT_LOCAL( void )
cff_font_done( CFF_Font font );
FT_LOCAL( FT_Error )
cff_load_private_dict( CFF_Font font,
CFF_SubFont subfont,
FT_UInt lenNDV,
FT_Fixed* NDV );
FT_LOCAL( FT_Byte )
cff_fd_select_get( CFF_FDSelect fdselect,
FT_UInt glyph_index );
FT_LOCAL( FT_Bool )
cff_blend_check_vector( CFF_Blend blend,
FT_UInt vsindex,
FT_UInt lenNDV,
FT_Fixed* NDV );
FT_LOCAL( FT_Error )
cff_blend_build_vector( CFF_Blend blend,
FT_UInt vsindex,
FT_UInt lenNDV,
FT_Fixed* NDV );
FT_LOCAL( void )
cff_blend_clear( CFF_SubFont subFont );
FT_LOCAL( FT_Error )
cff_blend_doBlend( CFF_SubFont subfont,
CFF_Parser parser,
FT_UInt numBlends );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_LOCAL( FT_Error )
cff_get_var_blend( FT_Face face,
FT_UInt *num_coords,
FT_Fixed* *coords,
FT_Fixed* *normalizedcoords,
FT_MM_Var* *mm_var );
FT_LOCAL( void )
cff_done_blend( FT_Face face );
#endif
FT_END_HEADER
#endif /* CFFLOAD_H_ */
/* END */
File diff suppressed because it is too large Load Diff
+84
View File
@@ -0,0 +1,84 @@
/****************************************************************************
*
* cffobjs.h
*
* OpenType objects manager (specification).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFOBJS_H_
#define CFFOBJS_H_
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cff_size_init( FT_Size size ); /* CFF_Size */
FT_LOCAL( void )
cff_size_done( FT_Size size ); /* CFF_Size */
FT_LOCAL( FT_Error )
cff_size_request( FT_Size size,
FT_Size_Request req );
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
FT_LOCAL( FT_Error )
cff_size_select( FT_Size size,
FT_ULong strike_index );
#endif
FT_LOCAL( void )
cff_slot_done( FT_GlyphSlot slot );
FT_LOCAL( FT_Error )
cff_slot_init( FT_GlyphSlot slot );
/**************************************************************************
*
* Face functions
*/
FT_LOCAL( FT_Error )
cff_face_init( FT_Stream stream,
FT_Face face, /* CFF_Face */
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params );
FT_LOCAL( void )
cff_face_done( FT_Face face ); /* CFF_Face */
/**************************************************************************
*
* Driver functions
*/
FT_LOCAL( FT_Error )
cff_driver_init( FT_Module module ); /* PS_Driver */
FT_LOCAL( void )
cff_driver_done( FT_Module module ); /* PS_Driver */
FT_END_HEADER
#endif /* CFFOBJS_H_ */
/* END */
File diff suppressed because it is too large Load Diff
+144
View File
@@ -0,0 +1,144 @@
/****************************************************************************
*
* cffparse.h
*
* CFF token stream parser (specification)
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFPARSE_H_
#define CFFPARSE_H_
#include <freetype/internal/cfftypes.h>
#include <freetype/internal/ftobjs.h>
FT_BEGIN_HEADER
/* CFF uses constant parser stack size; */
/* CFF2 can increase from default 193 */
#define CFF_MAX_STACK_DEPTH 96
/*
* There are plans to remove the `maxstack' operator in a forthcoming
* revision of the CFF2 specification, increasing the (then static) stack
* size to 513. By making the default stack size equal to the maximum
* stack size, the operator is essentially disabled, which has the
* desired effect in FreeType.
*/
#define CFF2_MAX_STACK 513
#define CFF2_DEFAULT_STACK 513
#define CFF_CODE_TOPDICT 0x1000
#define CFF_CODE_PRIVATE 0x2000
#define CFF2_CODE_TOPDICT 0x3000
#define CFF2_CODE_FONTDICT 0x4000
#define CFF2_CODE_PRIVATE 0x5000
typedef struct CFF_ParserRec_
{
FT_Library library;
FT_Byte* start;
FT_Byte* limit;
FT_Byte* cursor;
FT_Byte** stack;
FT_Byte** top;
FT_UInt stackSize; /* allocated size */
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
FT_ListRec t2_strings;
#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
FT_UInt object_code;
void* object;
FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */
FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */
} CFF_ParserRec, *CFF_Parser;
FT_LOCAL( FT_Long )
cff_parse_num( CFF_Parser parser,
FT_Byte** d );
FT_LOCAL( FT_Fixed )
cff_parse_fixed( CFF_Parser parser,
FT_Byte** d );
FT_LOCAL( FT_Error )
cff_parser_init( CFF_Parser parser,
FT_UInt code,
void* object,
FT_Library library,
FT_UInt stackSize,
FT_UShort num_designs,
FT_UShort num_axes );
FT_LOCAL( void )
cff_parser_done( CFF_Parser parser );
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_delta_fixed,
cff_kind_callback,
cff_kind_blend,
cff_kind_max /* do not remove */
};
/* now generate handlers for the most simple fields */
typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser );
typedef struct CFF_Field_Handler_
{
int kind;
int code;
FT_UInt offset;
FT_Byte size;
CFF_Field_Reader reader;
FT_UInt array_max;
FT_UInt count_offset;
#ifdef FT_DEBUG_LEVEL_TRACE
const char* id;
#endif
} CFF_Field_Handler;
FT_END_HEADER
#endif /* CFFPARSE_H_ */
/* END */
+150
View File
@@ -0,0 +1,150 @@
/****************************************************************************
*
* cfftoken.h
*
* CFF token definitions (specification only).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.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 CFF_CODE_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" )
#if 0
CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" )
#endif
CFF_FIELD_NUM ( 15, charset_offset, "charset" )
CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" )
CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" )
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" )
#endif
/* the next two operators were removed from the Type2 specification */
/* in version 16-March-2000 */
CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" )
#if 0
CFF_FIELD_CALLBACK( 0x11A, 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 CFF_CODE_PRIVATE
CFF_FIELD_DELTA_FIXED( 6, blue_values, 14, "BlueValues" )
CFF_FIELD_DELTA_FIXED( 7, other_blues, 10, "OtherBlues" )
CFF_FIELD_DELTA_FIXED( 8, family_blues, 14, "FamilyBlues" )
CFF_FIELD_DELTA_FIXED( 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" )
#undef FT_STRUCTURE
#define FT_STRUCTURE CFF_FontRecDictRec
#undef CFFCODE
#define CFFCODE CFF2_CODE_TOPDICT
CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" )
CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" )
CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" )
CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" )
CFF_FIELD_NUM ( 24, vstore_offset, "vstore" )
CFF_FIELD_CALLBACK( 25, maxstack, "maxstack" )
#undef FT_STRUCTURE
#define FT_STRUCTURE CFF_FontRecDictRec
#undef CFFCODE
#define CFFCODE CFF2_CODE_FONTDICT
CFF_FIELD_CALLBACK( 18, private_dict, "Private" )
CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" )
#undef FT_STRUCTURE
#define FT_STRUCTURE CFF_PrivateRec
#undef CFFCODE
#define CFFCODE CFF2_CODE_PRIVATE
CFF_FIELD_DELTA_FIXED( 6, blue_values, 14, "BlueValues" )
CFF_FIELD_DELTA_FIXED( 7, other_blues, 10, "OtherBlues" )
CFF_FIELD_DELTA_FIXED( 8, family_blues, 14, "FamilyBlues" )
CFF_FIELD_DELTA_FIXED( 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_NUM ( 0x111, language_group, "LanguageGroup" )
CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" )
CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" )
CFF_FIELD_BLEND ( 23, "blend" )
CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" )
/* END */
+23
View File
@@ -0,0 +1,23 @@
#
# FreeType 2 CFF module definition
#
# Copyright (C) 1996-2024 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
FTMODULE_H_COMMANDS += CFF_DRIVER
define CFF_DRIVER
$(OPEN_DRIVER) FT_Driver_ClassRec, cff_driver_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE)
endef
# EOF
+75
View File
@@ -0,0 +1,75 @@
#
# FreeType 2 OpenType/CFF driver configuration rules
#
# Copyright (C) 1996-2024 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# OpenType driver directory
#
CFF_DIR := $(SRC_DIR)/cff
CFF_COMPILE := $(CC) $(ANSIFLAGS) \
$I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) \
$(INCLUDE_FLAGS) \
$(FT_CFLAGS)
# CFF driver sources (i.e., C files)
#
CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \
$(CFF_DIR)/cffdrivr.c \
$(CFF_DIR)/cffgload.c \
$(CFF_DIR)/cffload.c \
$(CFF_DIR)/cffobjs.c \
$(CFF_DIR)/cffparse.c
# CFF driver headers
#
CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
$(CFF_DIR)/cfferrs.h \
$(CFF_DIR)/cfftoken.h
# CFF driver object(s)
#
# CFF_DRV_OBJ_M is used during `multi' builds
# CFF_DRV_OBJ_S is used during `single' builds
#
CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR)/%.c=$(OBJ_DIR)/%.$O)
CFF_DRV_OBJ_S := $(OBJ_DIR)/cff.$O
# CFF driver source file for single build
#
CFF_DRV_SRC_S := $(CFF_DIR)/cff.c
# CFF driver - single object
#
$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H)
$(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CFF_DRV_SRC_S))
# CFF driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(CFF_DIR)/%.c $(FREETYPE_H) $(CFF_DRV_H)
$(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(CFF_DRV_OBJ_S)
DRV_OBJS_M += $(CFF_DRV_OBJ_M)
# EOF
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,88 @@
/****************************************************************************
*
* afmparse.h
*
* AFM parser (specification).
*
* Copyright (C) 2006-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef AFMPARSE_H_
#define AFMPARSE_H_
#include <freetype/internal/psaux.h>
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
afm_parser_init( AFM_Parser parser,
FT_Memory memory,
FT_Byte* base,
FT_Byte* limit );
FT_LOCAL( void )
afm_parser_done( AFM_Parser parser );
FT_LOCAL( FT_Error )
afm_parser_parse( AFM_Parser parser );
enum AFM_ValueType_
{
AFM_VALUE_TYPE_STRING,
AFM_VALUE_TYPE_NAME,
AFM_VALUE_TYPE_FIXED, /* real number */
AFM_VALUE_TYPE_INTEGER,
AFM_VALUE_TYPE_BOOL,
AFM_VALUE_TYPE_INDEX /* glyph index */
};
typedef struct AFM_ValueRec_
{
enum AFM_ValueType_ type;
union
{
char* s;
FT_Fixed f;
FT_Int i;
FT_UInt u;
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_Int n );
/* read the next key from the next line or column */
FT_LOCAL( char* )
afm_parser_next_key( AFM_Parser parser,
FT_Bool line,
FT_Offset* len );
FT_END_HEADER
#endif /* AFMPARSE_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
/****************************************************************************
*
* cffdecode.h
*
* PostScript CFF (Type 2) decoding routines (specification).
*
* Copyright (C) 2017-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef CFFDECODE_H_
#define CFFDECODE_H_
#include <freetype/internal/psaux.h>
FT_BEGIN_HEADER
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,
CFF_Decoder_Get_Glyph_Callback get_callback,
CFF_Decoder_Free_Glyph_Callback free_callback );
FT_LOCAL( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder,
CFF_Size size,
FT_UInt glyph_index );
FT_LOCAL( FT_Int )
cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
FT_Int charcode );
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
FT_LOCAL( FT_Error )
cff_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len,
FT_Bool in_dict );
#endif
FT_END_HEADER
#endif
/* END */
@@ -0,0 +1,23 @@
#
# FreeType 2 PSaux module definition
#
# Copyright (C) 1996-2024 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
FTMODULE_H_COMMANDS += PSAUX_MODULE
define PSAUX_MODULE
$(OPEN_DRIVER) FT_Module_Class, psaux_module_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE)
endef
# EOF
@@ -0,0 +1,240 @@
/****************************************************************************
*
* psarrst.c
*
* Adobe's code for Array Stacks (body).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include "psft.h"
#include <freetype/internal/ftdebug.h>
#include "psglue.h"
#include "psarrst.h"
#include "pserror.h"
/*
* CF2_ArrStack uses an error pointer, to enable shared errors.
* Shared errors are necessary when multiple objects allow the program
* to continue after detecting errors. Only the first error should be
* recorded.
*/
FT_LOCAL_DEF( void )
cf2_arrstack_init( CF2_ArrStack arrstack,
FT_Memory memory,
FT_Error* error,
size_t sizeItem )
{
FT_ASSERT( arrstack );
/* initialize the structure */
arrstack->memory = memory;
arrstack->error = error;
arrstack->sizeItem = sizeItem;
arrstack->allocated = 0;
arrstack->count = 0;
arrstack->totalSize = 0;
arrstack->ptr = NULL;
}
FT_LOCAL_DEF( void )
cf2_arrstack_finalize( CF2_ArrStack arrstack )
{
FT_Memory memory = arrstack->memory; /* for FT_FREE */
FT_ASSERT( arrstack );
arrstack->allocated = 0;
arrstack->count = 0;
arrstack->totalSize = 0;
/* free the data buffer */
FT_FREE( arrstack->ptr );
}
/* allocate or reallocate the buffer size; */
/* return false on memory error */
static FT_Bool
cf2_arrstack_setNumElements( CF2_ArrStack arrstack,
size_t numElements )
{
FT_ASSERT( arrstack );
{
FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
FT_Memory memory = arrstack->memory; /* for FT_REALLOC */
size_t newSize = numElements * arrstack->sizeItem;
if ( numElements > FT_LONG_MAX / arrstack->sizeItem )
goto exit;
FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */
if ( !FT_QREALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
{
arrstack->allocated = numElements;
arrstack->totalSize = newSize;
if ( arrstack->count > numElements )
{
/* we truncated the list! */
CF2_SET_ERROR( arrstack->error, Stack_Overflow );
arrstack->count = numElements;
return FALSE;
}
return TRUE; /* success */
}
}
exit:
/* if there's not already an error, store this one */
CF2_SET_ERROR( arrstack->error, Out_Of_Memory );
return FALSE;
}
/* set the count, ensuring allocation is sufficient */
FT_LOCAL_DEF( void )
cf2_arrstack_setCount( CF2_ArrStack arrstack,
size_t numElements )
{
FT_ASSERT( arrstack );
if ( numElements > arrstack->allocated )
{
/* expand the allocation first */
if ( !cf2_arrstack_setNumElements( arrstack, numElements ) )
return;
}
arrstack->count = numElements;
}
/* clear the count */
FT_LOCAL_DEF( void )
cf2_arrstack_clear( CF2_ArrStack arrstack )
{
FT_ASSERT( arrstack );
arrstack->count = 0;
}
/* current number of items */
FT_LOCAL_DEF( size_t )
cf2_arrstack_size( const CF2_ArrStack arrstack )
{
FT_ASSERT( arrstack );
return arrstack->count;
}
FT_LOCAL_DEF( void* )
cf2_arrstack_getBuffer( const CF2_ArrStack arrstack )
{
FT_ASSERT( arrstack );
return arrstack->ptr;
}
/* return pointer to the given element */
FT_LOCAL_DEF( void* )
cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
size_t idx )
{
void* newPtr;
FT_ASSERT( arrstack );
if ( idx >= arrstack->count )
{
/* overflow */
CF2_SET_ERROR( arrstack->error, Stack_Overflow );
idx = 0; /* choose safe default */
}
newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem;
return newPtr;
}
/* push (append) an element at the end of the list; */
/* return false on memory error */
/* TODO: should there be a length param for extra checking? */
FT_LOCAL_DEF( void )
cf2_arrstack_push( CF2_ArrStack arrstack,
const void* ptr )
{
FT_ASSERT( arrstack );
if ( arrstack->count == arrstack->allocated )
{
/* increase the buffer size */
if ( !cf2_arrstack_setNumElements(
arrstack, arrstack->allocated * 2 + 16 ) )
{
/* on error, ignore the push */
return;
}
}
FT_ASSERT( ptr );
{
size_t offset = arrstack->count * arrstack->sizeItem;
void* newPtr = (FT_Byte*)arrstack->ptr + offset;
FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem );
arrstack->count += 1;
}
}
/* END */
@@ -0,0 +1,99 @@
/****************************************************************************
*
* psarrst.h
*
* Adobe's code for Array Stacks (specification).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSARRST_H_
#define PSARRST_H_
#include "pserror.h"
FT_BEGIN_HEADER
/* need to define the struct here (not opaque) so it can be allocated by */
/* clients */
typedef struct CF2_ArrStackRec_
{
FT_Memory memory;
FT_Error* error;
size_t sizeItem; /* bytes per element */
size_t allocated; /* items allocated */
size_t count; /* number of elements allocated */
size_t totalSize; /* total bytes allocated */
void* ptr; /* ptr to data */
} CF2_ArrStackRec, *CF2_ArrStack;
FT_LOCAL( void )
cf2_arrstack_init( CF2_ArrStack arrstack,
FT_Memory memory,
FT_Error* error,
size_t sizeItem );
FT_LOCAL( void )
cf2_arrstack_finalize( CF2_ArrStack arrstack );
FT_LOCAL( void )
cf2_arrstack_setCount( CF2_ArrStack arrstack,
size_t numElements );
FT_LOCAL( void )
cf2_arrstack_clear( CF2_ArrStack arrstack );
FT_LOCAL( size_t )
cf2_arrstack_size( const CF2_ArrStack arrstack );
FT_LOCAL( void* )
cf2_arrstack_getBuffer( const CF2_ArrStack arrstack );
FT_LOCAL( void* )
cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
size_t idx );
FT_LOCAL( void )
cf2_arrstack_push( CF2_ArrStack arrstack,
const void* ptr );
FT_END_HEADER
#endif /* PSARRST_H_ */
/* END */
+40
View File
@@ -0,0 +1,40 @@
/****************************************************************************
*
* psaux.c
*
* FreeType auxiliary PostScript driver component (body only).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "afmparse.c"
#include "psauxmod.c"
#include "psconv.c"
#include "psobjs.c"
#include "t1cmap.c"
#include "t1decode.c"
#include "cffdecode.c"
#include "psarrst.c"
#include "psblues.c"
#include "pserror.c"
#include "psfont.c"
#include "psft.c"
#include "pshints.c"
#include "psintrp.c"
#include "psread.c"
#include "psstack.c"
/* END */
@@ -0,0 +1,42 @@
/****************************************************************************
*
* psauxerr.h
*
* PS auxiliary module error codes (specification only).
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file is used to define the PS auxiliary module error enumeration
* constants.
*
*/
#ifndef PSAUXERR_H_
#define PSAUXERR_H_
#include <freetype/ftmoderr.h>
#undef FTERRORS_H_
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX PSaux_Err_
#define FT_ERR_BASE FT_Mod_Err_PSaux
#include <freetype/fterrors.h>
#endif /* PSAUXERR_H_ */
/* END */
@@ -0,0 +1,190 @@
/****************************************************************************
*
* psauxmod.c
*
* FreeType auxiliary PostScript module implementation (body).
*
* Copyright (C) 2000-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include "psauxmod.h"
#include "psobjs.h"
#include "t1decode.h"
#include "t1cmap.h"
#include "psft.h"
#include "cffdecode.h"
#ifndef T1_CONFIG_OPTION_NO_AFM
#include "afmparse.h"
#endif
FT_CALLBACK_TABLE_DEF
const PS_Table_FuncsRec ps_table_funcs =
{
ps_table_new, /* init */
ps_table_done, /* done */
ps_table_add, /* add */
ps_table_release /* release */
};
FT_CALLBACK_TABLE_DEF
const PS_Parser_FuncsRec ps_parser_funcs =
{
ps_parser_init, /* init */
ps_parser_done, /* done */
ps_parser_skip_spaces, /* skip_spaces */
ps_parser_skip_PS_token, /* skip_PS_token */
ps_parser_to_int, /* to_int */
ps_parser_to_fixed, /* to_fixed */
ps_parser_to_bytes, /* to_bytes */
ps_parser_to_coord_array, /* to_coord_array */
ps_parser_to_fixed_array, /* to_fixed_array */
ps_parser_to_token, /* to_token */
ps_parser_to_token_array, /* to_token_array */
ps_parser_load_field, /* load_field */
ps_parser_load_field_table /* load_field_table */
};
FT_CALLBACK_TABLE_DEF
const PS_Builder_FuncsRec ps_builder_funcs =
{
ps_builder_init, /* init */
ps_builder_done /* done */
};
FT_CALLBACK_TABLE_DEF
const T1_Builder_FuncsRec t1_builder_funcs =
{
t1_builder_init, /* init */
t1_builder_done, /* done */
t1_builder_check_points, /* check_points */
t1_builder_add_point, /* add_point */
t1_builder_add_point1, /* add_point1 */
t1_builder_add_contour, /* add_contour */
t1_builder_start_point, /* start_point */
t1_builder_close_contour /* close_contour */
};
FT_CALLBACK_TABLE_DEF
const T1_Decoder_FuncsRec t1_decoder_funcs =
{
t1_decoder_init, /* init */
t1_decoder_done, /* done */
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
t1_decoder_parse_charstrings, /* parse_charstrings_old */
#else
t1_decoder_parse_metrics, /* parse_metrics */
#endif
cf2_decoder_parse_charstrings /* parse_charstrings */
};
#ifndef T1_CONFIG_OPTION_NO_AFM
FT_CALLBACK_TABLE_DEF
const AFM_Parser_FuncsRec afm_parser_funcs =
{
afm_parser_init, /* init */
afm_parser_done, /* done */
afm_parser_parse /* parse */
};
#endif
FT_CALLBACK_TABLE_DEF
const T1_CMap_ClassesRec t1_cmap_classes =
{
&t1_cmap_standard_class_rec,
&t1_cmap_expert_class_rec,
&t1_cmap_custom_class_rec,
&t1_cmap_unicode_class_rec
};
FT_CALLBACK_TABLE_DEF
const CFF_Builder_FuncsRec cff_builder_funcs =
{
cff_builder_init, /* init */
cff_builder_done, /* done */
cff_check_points, /* check_points */
cff_builder_add_point, /* add_point */
cff_builder_add_point1, /* add_point1 */
cff_builder_add_contour, /* add_contour */
cff_builder_start_point, /* start_point */
cff_builder_close_contour /* close_contour */
};
FT_CALLBACK_TABLE_DEF
const CFF_Decoder_FuncsRec cff_decoder_funcs =
{
cff_decoder_init, /* init */
cff_decoder_prepare, /* prepare */
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
cff_decoder_parse_charstrings, /* parse_charstrings_old */
#endif
cf2_decoder_parse_charstrings /* parse_charstrings */
};
static
const PSAux_Interface psaux_interface =
{
&ps_table_funcs,
&ps_parser_funcs,
&t1_builder_funcs,
&t1_decoder_funcs,
t1_decrypt,
cff_random,
ps_decoder_init,
t1_make_subfont,
(const T1_CMap_ClassesRec*) &t1_cmap_classes,
#ifndef T1_CONFIG_OPTION_NO_AFM
&afm_parser_funcs,
#else
0,
#endif
&cff_decoder_funcs,
};
FT_DEFINE_MODULE(
psaux_module_class,
0,
sizeof ( FT_ModuleRec ),
"psaux",
0x20000L,
0x20000L,
&psaux_interface, /* module-specific interface */
(FT_Module_Constructor)NULL, /* module_init */
(FT_Module_Destructor) NULL, /* module_done */
(FT_Module_Requester) NULL /* get_interface */
)
/* END */
@@ -0,0 +1,60 @@
/****************************************************************************
*
* psauxmod.h
*
* FreeType auxiliary PostScript module implementation (specification).
*
* Copyright (C) 2000-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef PSAUXMOD_H_
#define PSAUXMOD_H_
#include <freetype/ftmodapi.h>
#include <freetype/internal/psaux.h>
FT_BEGIN_HEADER
FT_CALLBACK_TABLE
const CFF_Builder_FuncsRec cff_builder_funcs;
FT_CALLBACK_TABLE
const PS_Builder_FuncsRec ps_builder_funcs;
#ifndef T1_CONFIG_OPTION_NO_AFM
FT_CALLBACK_TABLE
const AFM_Parser_FuncsRec afm_parser_funcs;
#endif
FT_CALLBACK_TABLE
const T1_CMap_ClassesRec t1_cmap_classes;
FT_CALLBACK_TABLE
const CFF_Decoder_FuncsRec cff_decoder_funcs;
FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class;
FT_DECLARE_MODULE( psaux_module_class )
FT_END_HEADER
#endif /* PSAUXMOD_H_ */
/* END */
@@ -0,0 +1,571 @@
/****************************************************************************
*
* psblues.c
*
* Adobe's code for handling Blue Zones (body).
*
* Copyright 2009-2014 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include "psft.h"
#include <freetype/internal/ftdebug.h>
#include "psblues.h"
#include "pshints.h"
#include "psfont.h"
/**************************************************************************
*
* The macro FT_COMPONENT is used in trace mode. It is an implicit
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
* messages during execution.
*/
#undef FT_COMPONENT
#define FT_COMPONENT cf2blues
FT_LOCAL_DEF( void )
cf2_blues_init( CF2_Blues blues,
CF2_Font font )
{
/* pointer to parsed font object */
PS_Decoder* decoder = font->decoder;
CF2_Fixed zoneHeight;
CF2_Fixed maxZoneHeight = 0;
CF2_Fixed csUnitsPerPixel;
size_t numBlueValues;
size_t numOtherBlues;
size_t numFamilyBlues;
size_t numFamilyOtherBlues;
FT_Fixed* blueValues;
FT_Fixed* otherBlues;
FT_Fixed* familyBlues;
FT_Fixed* familyOtherBlues;
size_t i;
CF2_Fixed emBoxBottom, emBoxTop;
#if 0
CF2_Int unitsPerEm = font->unitsPerEm;
if ( unitsPerEm == 0 )
unitsPerEm = 1000;
#endif
FT_ZERO( blues );
blues->scale = font->innerTransform.d;
cf2_getBlueMetrics( decoder,
&blues->blueScale,
&blues->blueShift,
&blues->blueFuzz );
cf2_getBlueValues( decoder, &numBlueValues, &blueValues );
cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues );
cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues );
cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues );
/*
* synthetic em box hint heuristic
*
* Apply this when ideographic dictionary (LanguageGroup 1) has no
* real alignment zones. Adobe tools generate dummy zones at -250 and
* 1100 for a 1000 unit em. Fonts with ICF-based alignment zones
* should not enable the heuristic. When the heuristic is enabled,
* the font's blue zones are ignored.
*
*/
/* get em box from OS/2 typoAscender/Descender */
/* TODO: FreeType does not parse these metrics. Skip them for now. */
#if 0
FCM_getHorizontalLineMetrics( &e,
font->font,
&ascender,
&descender,
&linegap );
if ( ascender - descender == unitsPerEm )
{
emBoxBottom = cf2_intToFixed( descender );
emBoxTop = cf2_intToFixed( ascender );
}
else
#endif
{
emBoxBottom = CF2_ICF_Bottom;
emBoxTop = CF2_ICF_Top;
}
if ( cf2_getLanguageGroup( decoder ) == 1 &&
( numBlueValues == 0 ||
( numBlueValues == 4 &&
blueValues[0] < emBoxBottom &&
blueValues[1] < emBoxBottom &&
blueValues[2] > emBoxTop &&
blueValues[3] > emBoxTop ) ) )
{
/*
* Construct hint edges suitable for synthetic ghost hints at top
* and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted
* features above or below the last hinted edge. This also gives a
* net 1 pixel boost to the height of ideographic glyphs.
*
* Note: Adjust synthetic hints outward by epsilon (0x.0001) to
* avoid interference. E.g., some fonts have real hints at
* 880 and -120.
*/
blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON;
blues->emBoxBottomEdge.dsCoord = cf2_fixedRound(
FT_MulFix(
blues->emBoxBottomEdge.csCoord,
blues->scale ) ) -
CF2_MIN_COUNTER;
blues->emBoxBottomEdge.scale = blues->scale;
blues->emBoxBottomEdge.flags = CF2_GhostBottom |
CF2_Locked |
CF2_Synthetic;
blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON +
2 * font->darkenY;
blues->emBoxTopEdge.dsCoord = cf2_fixedRound(
FT_MulFix(
blues->emBoxTopEdge.csCoord,
blues->scale ) ) +
CF2_MIN_COUNTER;
blues->emBoxTopEdge.scale = blues->scale;
blues->emBoxTopEdge.flags = CF2_GhostTop |
CF2_Locked |
CF2_Synthetic;
blues->doEmBoxHints = TRUE; /* enable the heuristic */
return;
}
/* copy `BlueValues' and `OtherBlues' to a combined array of top and */
/* bottom zones */
for ( i = 0; i < numBlueValues; i += 2 )
{
blues->zone[blues->count].csBottomEdge = blueValues[i];
blues->zone[blues->count].csTopEdge = blueValues[i + 1];
zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge,
blues->zone[blues->count].csBottomEdge );
if ( zoneHeight < 0 )
{
FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
continue; /* reject this zone */
}
if ( zoneHeight > maxZoneHeight )
{
/* take maximum before darkening adjustment */
/* so overshoot suppression point doesn't change */
maxZoneHeight = zoneHeight;
}
/* adjust both edges of top zone upward by twice darkening amount */
if ( i != 0 )
{
blues->zone[blues->count].csTopEdge += 2 * font->darkenY;
blues->zone[blues->count].csBottomEdge += 2 * font->darkenY;
}
/* first `BlueValue' is bottom zone; others are top */
if ( i == 0 )
{
blues->zone[blues->count].bottomZone =
TRUE;
blues->zone[blues->count].csFlatEdge =
blues->zone[blues->count].csTopEdge;
}
else
{
blues->zone[blues->count].bottomZone =
FALSE;
blues->zone[blues->count].csFlatEdge =
blues->zone[blues->count].csBottomEdge;
}
blues->count += 1;
}
for ( i = 0; i < numOtherBlues; i += 2 )
{
blues->zone[blues->count].csBottomEdge = otherBlues[i];
blues->zone[blues->count].csTopEdge = otherBlues[i + 1];
zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge,
blues->zone[blues->count].csBottomEdge );
if ( zoneHeight < 0 )
{
FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
continue; /* reject this zone */
}
if ( zoneHeight > maxZoneHeight )
{
/* take maximum before darkening adjustment */
/* so overshoot suppression point doesn't change */
maxZoneHeight = zoneHeight;
}
/* Note: bottom zones are not adjusted for darkening amount */
/* all OtherBlues are bottom zone */
blues->zone[blues->count].bottomZone =
TRUE;
blues->zone[blues->count].csFlatEdge =
blues->zone[blues->count].csTopEdge;
blues->count += 1;
}
/* Adjust for FamilyBlues */
/* Search for the nearest flat edge in `FamilyBlues' or */
/* `FamilyOtherBlues'. According to the Black Book, any matching edge */
/* must be within one device pixel */
csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale );
/* loop on all zones in this font */
for ( i = 0; i < blues->count; i++ )
{
size_t j;
CF2_Fixed minDiff;
CF2_Fixed flatFamilyEdge, diff;
/* value for this font */
CF2_Fixed flatEdge = blues->zone[i].csFlatEdge;
if ( blues->zone[i].bottomZone )
{
/* In a bottom zone, the top edge is the flat edge. */
/* Search `FamilyOtherBlues' for bottom zones; look for closest */
/* Family edge that is within the one pixel threshold. */
minDiff = CF2_FIXED_MAX;
for ( j = 0; j < numFamilyOtherBlues; j += 2 )
{
/* top edge */
flatFamilyEdge = familyOtherBlues[j + 1];
diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) );
if ( diff < minDiff && diff < csUnitsPerPixel )
{
blues->zone[i].csFlatEdge = flatFamilyEdge;
minDiff = diff;
if ( diff == 0 )
break;
}
}
/* check the first member of FamilyBlues, which is a bottom zone */
if ( numFamilyBlues >= 2 )
{
/* top edge */
flatFamilyEdge = familyBlues[1];
diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) );
if ( diff < minDiff && diff < csUnitsPerPixel )
blues->zone[i].csFlatEdge = flatFamilyEdge;
}
}
else
{
/* In a top zone, the bottom edge is the flat edge. */
/* Search `FamilyBlues' for top zones; skip first zone, which is a */
/* bottom zone; look for closest Family edge that is within the */
/* one pixel threshold */
minDiff = CF2_FIXED_MAX;
for ( j = 2; j < numFamilyBlues; j += 2 )
{
/* bottom edge */
flatFamilyEdge = familyBlues[j];
/* adjust edges of top zone upward by twice darkening amount */
flatFamilyEdge += 2 * font->darkenY; /* bottom edge */
diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) );
if ( diff < minDiff && diff < csUnitsPerPixel )
{
blues->zone[i].csFlatEdge = flatFamilyEdge;
minDiff = diff;
if ( diff == 0 )
break;
}
}
}
}
/* TODO: enforce separation of zones, including BlueFuzz */
/* Adjust BlueScale; similar to AdjustBlueScale() in coretype */
/* `bcsetup.c'. */
if ( maxZoneHeight > 0 )
{
if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ),
maxZoneHeight ) )
{
/* clamp at maximum scale */
blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ),
maxZoneHeight );
}
/*
* TODO: Revisit the bug fix for 613448. The minimum scale
* requirement catches a number of library fonts. For
* example, with default BlueScale (.039625) and 0.4 minimum,
* the test below catches any font with maxZoneHeight < 10.1.
* There are library fonts ranging from 2 to 10 that get
* caught, including e.g., Eurostile LT Std Medium with
* maxZoneHeight of 6.
*
*/
#if 0
if ( blueScale < .4 / maxZoneHeight )
{
tetraphilia_assert( 0 );
/* clamp at minimum scale, per bug 0613448 fix */
blueScale = .4 / maxZoneHeight;
}
#endif
}
/*
* Suppress overshoot and boost blue zones at small sizes. Boost
* amount varies linearly from 0.5 pixel near 0 to 0 pixel at
* blueScale cutoff.
* Note: This boost amount is different from the coretype heuristic.
*
*/
if ( blues->scale < blues->blueScale )
{
blues->suppressOvershoot = TRUE;
/* Change rounding threshold for `dsFlatEdge'. */
/* Note: constant changed from 0.5 to 0.6 to avoid a problem with */
/* 10ppem Arial */
blues->boost = cf2_doubleToFixed( .6 ) -
FT_MulDiv( cf2_doubleToFixed ( .6 ),
blues->scale,
blues->blueScale );
if ( blues->boost > 0x7FFF )
{
/* boost must remain less than 0.5, or baseline could go negative */
blues->boost = 0x7FFF;
}
}
/* boost and darkening have similar effects; don't do both */
if ( font->stemDarkened )
blues->boost = 0;
/* set device space alignment for each zone; */
/* apply boost amount before rounding flat edge */
for ( i = 0; i < blues->count; i++ )
{
if ( blues->zone[i].bottomZone )
blues->zone[i].dsFlatEdge = cf2_fixedRound(
FT_MulFix(
blues->zone[i].csFlatEdge,
blues->scale ) -
blues->boost );
else
blues->zone[i].dsFlatEdge = cf2_fixedRound(
FT_MulFix(
blues->zone[i].csFlatEdge,
blues->scale ) +
blues->boost );
}
}
/*
* Check whether `stemHint' is captured by one of the blue zones.
*
* Zero, one or both edges may be valid; only valid edges can be
* captured. For compatibility with CoolType, search top and bottom
* zones in the same pass (see `BlueLock'). If a hint is captured,
* return true and position the edge(s) in one of 3 ways:
*
* 1) If `BlueScale' suppresses overshoot, position the captured edge
* at the flat edge of the zone.
* 2) If overshoot is not suppressed and `BlueShift' requires
* overshoot, position the captured edge a minimum of 1 device pixel
* from the flat edge.
* 3) If overshoot is not suppressed or required, position the captured
* edge at the nearest device pixel.
*
*/
FT_LOCAL_DEF( FT_Bool )
cf2_blues_capture( const CF2_Blues blues,
CF2_Hint bottomHintEdge,
CF2_Hint topHintEdge )
{
/* TODO: validate? */
CF2_Fixed csFuzz = blues->blueFuzz;
/* new position of captured edge */
CF2_Fixed dsNew;
/* amount that hint is moved when positioned */
CF2_Fixed dsMove = 0;
FT_Bool captured = FALSE;
CF2_UInt i;
/* assert edge flags are consistent */
FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) &&
!cf2_hint_isBottom( topHintEdge ) );
/* TODO: search once without blue fuzz for compatibility with coretype? */
for ( i = 0; i < blues->count; i++ )
{
if ( blues->zone[i].bottomZone &&
cf2_hint_isBottom( bottomHintEdge ) )
{
if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <=
bottomHintEdge->csCoord &&
bottomHintEdge->csCoord <=
ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) )
{
/* bottom edge captured by bottom zone */
if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge;
else if ( SUB_INT32( blues->zone[i].csTopEdge,
bottomHintEdge->csCoord ) >=
blues->blueShift )
{
/* guarantee minimum of 1 pixel overshoot */
dsNew = FT_MIN(
cf2_fixedRound( bottomHintEdge->dsCoord ),
SUB_INT32( blues->zone[i].dsFlatEdge,
cf2_intToFixed( 1 ) ) );
}
else
{
/* simply round captured edge */
dsNew = cf2_fixedRound( bottomHintEdge->dsCoord );
}
dsMove = SUB_INT32( dsNew, bottomHintEdge->dsCoord );
captured = TRUE;
break;
}
}
if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) )
{
if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <=
topHintEdge->csCoord &&
topHintEdge->csCoord <=
ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) )
{
/* top edge captured by top zone */
if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge;
else if ( SUB_INT32( topHintEdge->csCoord,
blues->zone[i].csBottomEdge ) >=
blues->blueShift )
{
/* guarantee minimum of 1 pixel overshoot */
dsNew = FT_MAX(
cf2_fixedRound( topHintEdge->dsCoord ),
blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) );
}
else
{
/* simply round captured edge */
dsNew = cf2_fixedRound( topHintEdge->dsCoord );
}
dsMove = SUB_INT32( dsNew, topHintEdge->dsCoord );
captured = TRUE;
break;
}
}
}
if ( captured )
{
/* move both edges and flag them `locked' */
if ( cf2_hint_isValid( bottomHintEdge ) )
{
bottomHintEdge->dsCoord = ADD_INT32( bottomHintEdge->dsCoord,
dsMove );
cf2_hint_lock( bottomHintEdge );
}
if ( cf2_hint_isValid( topHintEdge ) )
{
topHintEdge->dsCoord = ADD_INT32( topHintEdge->dsCoord, dsMove );
cf2_hint_lock( topHintEdge );
}
}
return captured;
}
/* END */
@@ -0,0 +1,185 @@
/****************************************************************************
*
* psblues.h
*
* Adobe's code for handling Blue Zones (specification).
*
* Copyright 2009-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
/*
* A `CF2_Blues' object stores the blue zones (horizontal alignment
* zones) of a font. These are specified in the CFF private dictionary
* by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'.
* Each zone is defined by a top and bottom edge in character space.
* Further, each zone is either a top zone or a bottom zone, as recorded
* by `bottomZone'.
*
* The maximum number of `BlueValues' and `FamilyBlues' is 7 each.
* However, these are combined to produce a total of 7 zones.
* Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues'
* is 5 and these are combined to produce an additional 5 zones.
*
* Blue zones are used to `capture' hints and force them to a common
* alignment point. This alignment is recorded in device space in
* `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be
* constructed independently of scaling. Construction may occur once
* the matrix is known. Other features implemented in the Capture
* method are overshoot suppression, overshoot enforcement, and Blue
* Boost.
*
* Capture is determined by `BlueValues' and `OtherBlues', but the
* alignment point may be adjusted to the scaled flat edge of
* `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the
* curved edge of a zone.
*
*/
#ifndef PSBLUES_H_
#define PSBLUES_H_
#include "psglue.h"
FT_BEGIN_HEADER
/*
* `CF2_Hint' is shared by `cf2hints.h' and
* `cf2blues.h', but `cf2blues.h' depends on
* `cf2hints.h', so define it here. Note: The typedef is in
* `cf2glue.h'.
*
*/
enum
{
CF2_GhostBottom = 0x1, /* a single bottom edge */
CF2_GhostTop = 0x2, /* a single top edge */
CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */
CF2_PairTop = 0x8, /* the top edge of a stem hint */
CF2_Locked = 0x10, /* this edge has been aligned */
/* by a blue zone */
CF2_Synthetic = 0x20 /* this edge was synthesized */
};
/*
* Default value for OS/2 typoAscender/Descender when their difference
* is not equal to `unitsPerEm'. The default is based on -250 and 1100
* in `CF2_Blues', assuming 1000 units per em here.
*
*/
enum
{
CF2_ICF_Top = cf2_intToFixed( 880 ),
CF2_ICF_Bottom = cf2_intToFixed( -120 )
};
/*
* Constant used for hint adjustment and for synthetic em box hint
* placement.
*/
#define CF2_MIN_COUNTER cf2_doubleToFixed( 0.5 )
/* shared typedef is in cf2glue.h */
struct CF2_HintRec_
{
CF2_UInt flags; /* attributes of the edge */
size_t index; /* index in original stem hint array */
/* (if not synthetic) */
CF2_Fixed csCoord;
CF2_Fixed dsCoord;
CF2_Fixed scale;
};
typedef struct CF2_BlueRec_
{
CF2_Fixed csBottomEdge;
CF2_Fixed csTopEdge;
CF2_Fixed csFlatEdge; /* may be from either local or Family zones */
CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */
/* of top zone (rounded) */
FT_Bool bottomZone;
} CF2_BlueRec;
/* max total blue zones is 12 */
enum
{
CF2_MAX_BLUES = 7,
CF2_MAX_OTHERBLUES = 5
};
typedef struct CF2_BluesRec_
{
CF2_Fixed scale;
CF2_UInt count;
FT_Bool suppressOvershoot;
FT_Bool doEmBoxHints;
CF2_Fixed blueScale;
CF2_Fixed blueShift;
CF2_Fixed blueFuzz;
CF2_Fixed boost;
CF2_HintRec emBoxTopEdge;
CF2_HintRec emBoxBottomEdge;
CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES];
} CF2_BluesRec, *CF2_Blues;
FT_LOCAL( void )
cf2_blues_init( CF2_Blues blues,
CF2_Font font );
FT_LOCAL( FT_Bool )
cf2_blues_capture( const CF2_Blues blues,
CF2_Hint bottomHintEdge,
CF2_Hint topHintEdge );
FT_END_HEADER
#endif /* PSBLUES_H_ */
/* END */
+610
View File
@@ -0,0 +1,610 @@
/****************************************************************************
*
* psconv.c
*
* Some convenience conversions (body).
*
* Copyright (C) 2006-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include <freetype/internal/psaux.h>
#include <freetype/internal/ftdebug.h>
#include "psconv.h"
#include "psauxerr.h"
/**************************************************************************
*
* The macro FT_COMPONENT is used in trace mode. It is an implicit
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
* messages during execution.
*/
#undef FT_COMPONENT
#define FT_COMPONENT psconv
/* The following array is used by various functions to quickly convert */
/* digits (both decimal and non-decimal) into numbers. */
#if 'A' == 65
/* ASCII */
static const FT_Char ft_char_table[128] =
{
/* 0x00 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
};
/* no character >= 0x80 can represent a valid number */
#define OP >=
#endif /* 'A' == 65 */
#if 'A' == 193
/* EBCDIC */
static const FT_Char ft_char_table[128] =
{
/* 0x80 */
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
-1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
-1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
-1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
-1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
};
/* no character < 0x80 can represent a valid number */
#define OP <
#endif /* 'A' == 193 */
FT_LOCAL_DEF( FT_Long )
PS_Conv_Strtol( FT_Byte** cursor,
FT_Byte* limit,
FT_Long base )
{
FT_Byte* p = *cursor;
FT_Long num = 0;
FT_Bool sign = 0;
FT_Bool have_overflow = 0;
FT_Long num_limit;
FT_Char c_limit;
if ( p >= limit )
goto Bad;
if ( base < 2 || base > 36 )
{
FT_TRACE4(( "!!!INVALID BASE:!!!" ));
return 0;
}
if ( *p == '-' || *p == '+' )
{
sign = FT_BOOL( *p == '-' );
p++;
if ( p == limit )
goto Bad;
/* only a single sign is allowed */
if ( *p == '-' || *p == '+' )
return 0;
}
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;
/* only a single sign is allowed */
if ( *p == '-' || *p == '+' )
return 0;
}
/* read the integer part */
if ( *p != '.' )
{
curp = p;
integral = PS_Conv_ToInt( &p, limit );
if ( p == curp )
return 0;
if ( integral > 0x7FFF )
have_overflow = 1;
else
integral = (FT_Fixed)( (FT_UInt32)integral << 16 );
}
/* read the decimal part */
if ( p < limit && *p == '.' )
{
p++;
for ( ; p < limit; p++ )
{
FT_Char c;
if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
break;
c = ft_char_table[*p & 0x7F];
if ( c < 0 || c >= 10 )
break;
/* only add digit if we don't overflow */
if ( divider < 0xCCCCCCCL && decimal < 0xCCCCCCCL )
{
decimal = decimal * 10 + c;
if ( !integral && power_ten > 0 )
power_ten--;
else
divider *= 10;
}
}
}
/* read exponent, if any */
if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
{
FT_Long exponent;
p++;
curp = p;
exponent = PS_Conv_ToInt( &p, limit );
if ( curp == p )
return 0;
/* arbitrarily limit exponent */
if ( exponent > 1000 )
have_overflow = 1;
else if ( exponent < -1000 )
have_underflow = 1;
else
power_ten += exponent;
}
*cursor = p;
if ( !integral && !decimal )
return 0;
if ( have_overflow )
goto Overflow;
if ( have_underflow )
goto Underflow;
while ( power_ten > 0 )
{
if ( integral >= 0xCCCCCCCL )
goto Overflow;
integral *= 10;
if ( decimal >= 0xCCCCCCCL )
{
if ( divider == 1 )
goto Overflow;
divider /= 10;
}
else
decimal *= 10;
power_ten--;
}
while ( power_ten < 0 )
{
integral /= 10;
if ( divider < 0xCCCCCCCL )
divider *= 10;
else
decimal /= 10;
if ( !integral && !decimal )
goto Underflow;
power_ten++;
}
if ( decimal )
{
decimal = FT_DivFix( decimal, divider );
/* it's not necessary to check this addition for overflow */
/* due to the structure of the real number representation */
integral += decimal;
}
Exit:
if ( sign )
integral = -integral;
return integral;
Bad:
FT_TRACE4(( "!!!END OF DATA:!!!" ));
return 0;
Overflow:
integral = 0x7FFFFFFFL;
FT_TRACE4(( "!!!OVERFLOW:!!!" ));
goto Exit;
Underflow:
FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
return 0;
}
#if 0
FT_LOCAL_DEF( FT_UInt )
PS_Conv_StringDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
FT_Offset n )
{
FT_Byte* p;
FT_UInt r = 0;
for ( p = *cursor; r < n && p < limit; p++ )
{
FT_Byte b;
if ( *p != '\\' )
{
buffer[r++] = *p;
continue;
}
p++;
switch ( *p )
{
case 'n':
b = '\n';
break;
case 'r':
b = '\r';
break;
case 't':
b = '\t';
break;
case 'b':
b = '\b';
break;
case 'f':
b = '\f';
break;
case '\r':
p++;
if ( *p != '\n' )
{
b = *p;
break;
}
/* no break */
case '\n':
continue;
break;
default:
if ( IS_PS_DIGIT( *p ) )
{
b = *p - '0';
p++;
if ( IS_PS_DIGIT( *p ) )
{
b = b * 8 + *p - '0';
p++;
if ( IS_PS_DIGIT( *p ) )
b = b * 8 + *p - '0';
else
{
buffer[r++] = b;
b = *p;
}
}
else
{
buffer[r++] = b;
b = *p;
}
}
else
b = *p;
break;
}
buffer[r++] = b;
}
*cursor = p;
return r;
}
#endif /* 0 */
FT_LOCAL_DEF( FT_UInt )
PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
FT_Offset n )
{
FT_Byte* p;
FT_UInt r = 0;
FT_UInt w = 0;
FT_UInt pad = 0x01;
n *= 2;
#if 1
p = *cursor;
if ( p >= limit )
return 0;
if ( n > (FT_UInt)( limit - p ) )
n = (FT_UInt)( limit - p );
/* we try to process two nibbles at a time to be as fast as possible */
for ( ; r < n; r++ )
{
FT_UInt c = p[r];
if ( IS_PS_SPACE( c ) )
continue;
if ( c OP 0x80 )
break;
c = (FT_UInt)ft_char_table[c & 0x7F];
if ( c >= 16 )
break;
pad = ( pad << 4 ) | c;
if ( pad & 0x100 )
{
buffer[w++] = (FT_Byte)pad;
pad = 0x01;
}
}
if ( pad != 0x01 )
buffer[w++] = (FT_Byte)( pad << 4 );
*cursor = p + r;
return w;
#else /* 0 */
for ( r = 0; r < n; r++ )
{
FT_Char c;
if ( IS_PS_SPACE( *p ) )
continue;
if ( *p OP 0x80 )
break;
c = ft_char_table[*p & 0x7F];
if ( (unsigned)c >= 16 )
break;
if ( r & 1 )
{
*buffer = (FT_Byte)( *buffer + c );
buffer++;
}
else
*buffer = (FT_Byte)( c << 4 );
r++;
}
*cursor = p;
return ( r + 1 ) / 2;
#endif /* 0 */
}
FT_LOCAL_DEF( FT_UInt )
PS_Conv_EexecDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
FT_Offset n,
FT_UShort* seed )
{
FT_Byte* p;
FT_UInt r;
FT_UInt s = *seed;
#if 1
p = *cursor;
if ( p >= limit )
return 0;
if ( n > (FT_UInt)( limit - p ) )
n = (FT_UInt)( limit - p );
for ( r = 0; r < n; r++ )
{
FT_UInt val = p[r];
FT_UInt b = ( val ^ ( s >> 8 ) );
s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
buffer[r] = (FT_Byte) b;
}
*cursor = p + n;
*seed = (FT_UShort)s;
#else /* 0 */
for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
{
FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
*buffer++ = b;
}
*cursor = p;
*seed = s;
#endif /* 0 */
return r;
}
/* END */
@@ -0,0 +1,70 @@
/****************************************************************************
*
* psconv.h
*
* Some convenience conversions (specification).
*
* Copyright (C) 2006-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef PSCONV_H_
#define PSCONV_H_
#include <freetype/internal/psaux.h>
FT_BEGIN_HEADER
FT_LOCAL( FT_Long )
PS_Conv_Strtol( FT_Byte** cursor,
FT_Byte* limit,
FT_Long base );
FT_LOCAL( FT_Long )
PS_Conv_ToInt( FT_Byte** cursor,
FT_Byte* limit );
FT_LOCAL( FT_Fixed )
PS_Conv_ToFixed( FT_Byte** cursor,
FT_Byte* limit,
FT_Long power_ten );
#if 0
FT_LOCAL( FT_UInt )
PS_Conv_StringDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
FT_Offset n );
#endif
FT_LOCAL( FT_UInt )
PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
FT_Offset n );
FT_LOCAL( FT_UInt )
PS_Conv_EexecDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
FT_Offset n,
FT_UShort* seed );
FT_END_HEADER
#endif /* PSCONV_H_ */
/* END */
@@ -0,0 +1,52 @@
/****************************************************************************
*
* pserror.c
*
* Adobe's code for error handling (body).
*
* Copyright 2006-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include "psft.h"
#include "pserror.h"
FT_LOCAL_DEF( void )
cf2_setError( FT_Error* error,
FT_Error value )
{
if ( error && !*error )
*error = value;
}
/* END */
@@ -0,0 +1,120 @@
/****************************************************************************
*
* pserror.h
*
* Adobe's code for error handling (specification).
*
* Copyright 2006-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSERROR_H_
#define PSERROR_H_
#include <freetype/ftmoderr.h>
#undef FTERRORS_H_
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX CF2_Err_
#define FT_ERR_BASE FT_Mod_Err_CF2
#include <freetype/fterrors.h>
#include <freetype/internal/compiler-macros.h>
#include "psft.h"
FT_BEGIN_HEADER
/*
* A poor-man error facility.
*
* This code being written in vanilla C, doesn't have the luxury of a
* language-supported exception mechanism such as the one available in
* Java. Instead, we are stuck with using error codes that must be
* carefully managed and preserved. However, it is convenient for us to
* model our error mechanism on a Java-like exception mechanism.
* When we assign an error code we are thus `throwing' an error.
*
* The preservation of an error code is done by coding convention.
* Upon a function call if the error code is anything other than
* `FT_Err_Ok', which is guaranteed to be zero, we
* will return without altering that error. This will allow the
* error to propagate and be handled at the appropriate location in
* the code.
*
* This allows a style of code where the error code is initialized
* up front and a block of calls are made with the error code only
* being checked after the block. If a new error occurs, the original
* error will be preserved and a functional no-op should result in any
* subsequent function that has an initial error code not equal to
* `FT_Err_Ok'.
*
* Errors are encoded by calling the `FT_THROW' macro. For example,
*
* {
* FT_Error e;
*
*
* ...
* e = FT_THROW( Out_Of_Memory );
* }
*
*/
/* Set error code to a particular value. */
FT_LOCAL( void )
cf2_setError( FT_Error* error,
FT_Error value );
/*
* A macro that conditionally sets an error code.
*
* This macro will first check whether `error' is set;
* if not, it will set it to `e'.
*
*/
#define CF2_SET_ERROR( error, e ) \
cf2_setError( error, FT_THROW( e ) )
FT_END_HEADER
#endif /* PSERROR_H_ */
/* END */
@@ -0,0 +1,94 @@
/****************************************************************************
*
* psfixed.h
*
* Adobe's code for Fixed-Point Mathematics (specification only).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSFIXED_H_
#define PSFIXED_H_
FT_BEGIN_HEADER
/* rasterizer integer and fixed-point arithmetic must be 32-bit */
#define CF2_Fixed CF2_F16Dot16
typedef FT_Int32 CF2_Frac; /* 2.30 fixed-point */
#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL )
#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L )
#define CF2_FIXED_ONE ( (CF2_Fixed)0x10000L )
#define CF2_FIXED_EPSILON ( (CF2_Fixed)0x0001 )
/* in C 89, left and right shift of negative numbers is */
/* implementation specific behaviour in the general case */
#define cf2_intToFixed( i ) \
( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) )
#define cf2_fixedToInt( x ) \
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
#define cf2_fixedRound( x ) \
( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) )
#define cf2_doubleToFixed( f ) \
( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) )
#define cf2_fixedAbs( x ) \
( (x) < 0 ? NEG_INT32( x ) : (x) )
#define cf2_fixedFloor( x ) \
( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) )
#define cf2_fixedFraction( x ) \
( (x) - cf2_fixedFloor( x ) )
#define cf2_fracToFixed( x ) \
( ( (x) + 0x2000 - ( (x) < 0 ) ) >> 14 )
/* signed numeric types */
typedef enum CF2_NumberType_
{
CF2_NumberFixed, /* 16.16 */
CF2_NumberFrac, /* 2.30 */
CF2_NumberInt /* 32.0 */
} CF2_NumberType;
FT_END_HEADER
#endif /* PSFIXED_H_ */
/* END */
+566
View File
@@ -0,0 +1,566 @@
/****************************************************************************
*
* psfont.c
*
* Adobe's code for font instances (body).
*
* Copyright 2007-2014 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include <freetype/internal/ftcalc.h>
#include "psft.h"
#include "psglue.h"
#include "psfont.h"
#include "pserror.h"
#include "psintrp.h"
/* Compute a stem darkening amount in character space. */
static void
cf2_computeDarkening( CF2_Fixed emRatio,
CF2_Fixed ppem,
CF2_Fixed stemWidth,
CF2_Fixed* darkenAmount,
CF2_Fixed boldenAmount,
FT_Bool stemDarkened,
FT_Int* darkenParams )
{
/*
* Total darkening amount is computed in 1000 unit character space
* using the modified 5 part curve as Adobe's Avalon rasterizer.
* The darkening amount is smaller for thicker stems.
* It becomes zero when the stem is thicker than 2.333 pixels.
*
* By default, we use
*
* darkenAmount = 0.4 pixels if scaledStem <= 0.5 pixels,
* darkenAmount = 0.275 pixels if 1 <= scaledStem <= 1.667 pixels,
* darkenAmount = 0 pixel if scaledStem >= 2.333 pixels,
*
* and piecewise linear in-between:
*
*
* darkening
* ^
* |
* | (x1,y1)
* |--------+
* | \
* | \
* | \ (x3,y3)
* | +----------+
* | (x2,y2) \
* | \
* | \
* | +-----------------
* | (x4,y4)
* +---------------------------------------------> stem
* thickness
*
*
* This corresponds to the following values for the
* `darkening-parameters' property:
*
* (x1, y1) = (500, 400)
* (x2, y2) = (1000, 275)
* (x3, y3) = (1667, 275)
* (x4, y4) = (2333, 0)
*
*/
/* Internal calculations are done in units per thousand for */
/* convenience. The x axis is scaled stem width in */
/* thousandths of a pixel. That is, 1000 is 1 pixel. */
/* The y axis is darkening amount in thousandths of a pixel.*/
/* In the code, below, dividing by ppem and */
/* adjusting for emRatio converts darkenAmount to character */
/* space (font units). */
CF2_Fixed stemWidthPer1000, scaledStem;
FT_Int logBase2;
*darkenAmount = 0;
if ( boldenAmount == 0 && !stemDarkened )
return;
/* protect against range problems and divide by zero */
if ( emRatio < cf2_doubleToFixed( .01 ) )
return;
if ( stemDarkened )
{
FT_Int x1 = darkenParams[0];
FT_Int y1 = darkenParams[1];
FT_Int x2 = darkenParams[2];
FT_Int y2 = darkenParams[3];
FT_Int x3 = darkenParams[4];
FT_Int y3 = darkenParams[5];
FT_Int x4 = darkenParams[6];
FT_Int y4 = darkenParams[7];
/* convert from true character space to 1000 unit character space; */
/* add synthetic emboldening effect */
/* `stemWidthPer1000' will not overflow for a legitimate font */
stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
/* `scaledStem' can easily overflow, so we must clamp its maximum */
/* value; the test doesn't need to be precise, but must be */
/* conservative. The clamp value (default 2333) where */
/* `darkenAmount' is zero is well below the overflow value of */
/* 32767. */
/* */
/* FT_MSB computes the integer part of the base 2 logarithm. The */
/* number of bits for the product is 1 or 2 more than the sum of */
/* logarithms; remembering that the 16 lowest bits of the fraction */
/* are dropped this is correct to within a factor of almost 4. */
/* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and */
/* is flagged as possible overflow because 0xFF.FFFF * 0xFF.FFFF = */
/* 0xFFFF.FE00 is also 23+23. */
logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) +
FT_MSB( (FT_UInt32)ppem );
if ( logBase2 >= 46 )
/* possible overflow */
scaledStem = cf2_intToFixed( x4 );
else
scaledStem = FT_MulFix( stemWidthPer1000, ppem );
/* now apply the darkening parameters */
if ( scaledStem < cf2_intToFixed( x1 ) )
*darkenAmount = FT_DivFix( cf2_intToFixed( y1 ), ppem );
else if ( scaledStem < cf2_intToFixed( x2 ) )
{
FT_Int xdelta = x2 - x1;
FT_Int ydelta = y2 - y1;
FT_Int x = stemWidthPer1000 -
FT_DivFix( cf2_intToFixed( x1 ), ppem );
if ( !xdelta )
goto Try_x3;
*darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
FT_DivFix( cf2_intToFixed( y1 ), ppem );
}
else if ( scaledStem < cf2_intToFixed( x3 ) )
{
Try_x3:
{
FT_Int xdelta = x3 - x2;
FT_Int ydelta = y3 - y2;
FT_Int x = stemWidthPer1000 -
FT_DivFix( cf2_intToFixed( x2 ), ppem );
if ( !xdelta )
goto Try_x4;
*darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
FT_DivFix( cf2_intToFixed( y2 ), ppem );
}
}
else if ( scaledStem < cf2_intToFixed( x4 ) )
{
Try_x4:
{
FT_Int xdelta = x4 - x3;
FT_Int ydelta = y4 - y3;
FT_Int x = stemWidthPer1000 -
FT_DivFix( cf2_intToFixed( x3 ), ppem );
if ( !xdelta )
goto Use_y4;
*darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
FT_DivFix( cf2_intToFixed( y3 ), ppem );
}
}
else
{
Use_y4:
*darkenAmount = FT_DivFix( cf2_intToFixed( y4 ), ppem );
}
/* use half the amount on each side and convert back to true */
/* character space */
*darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio );
}
/* add synthetic emboldening effect in character space */
*darkenAmount += boldenAmount / 2;
}
/* set up values for the current FontDict and matrix; */
/* called for each glyph to be rendered */
/* caller's transform is adjusted for subpixel positioning */
static void
cf2_font_setup( CF2_Font font,
const CF2_Matrix* transform )
{
/* pointer to parsed font object */
PS_Decoder* decoder = font->decoder;
FT_Bool needExtraSetup = FALSE;
CFF_VStoreRec* vstore;
FT_Bool hasVariations = FALSE;
/* character space units */
CF2_Fixed boldenX = font->syntheticEmboldeningAmountX;
CF2_Fixed boldenY = font->syntheticEmboldeningAmountY;
CFF_SubFont subFont;
CF2_Fixed ppem;
CF2_UInt lenNormalizedV = 0;
FT_Fixed* normalizedV = NULL;
/* clear previous error */
font->error = FT_Err_Ok;
/* if a CID fontDict has changed, we need to recompute some cached */
/* data */
subFont = cf2_getSubfont( decoder );
if ( font->lastSubfont != subFont )
{
font->lastSubfont = subFont;
needExtraSetup = TRUE;
}
if ( !font->isT1 )
{
/* check for variation vectors */
vstore = cf2_getVStore( decoder );
hasVariations = ( vstore->dataCount != 0 );
if ( hasVariations )
{
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload;
/* check whether Private DICT in this subfont needs to be reparsed */
font->error = cf2_getNormalizedVector( decoder,
&lenNormalizedV,
&normalizedV );
if ( font->error )
return;
if ( cffload->blend_check_vector( &subFont->blend,
subFont->private_dict.vsindex,
lenNormalizedV,
normalizedV ) )
{
/* blend has changed, reparse */
cffload->load_private_dict( decoder->cff,
subFont,
lenNormalizedV,
normalizedV );
needExtraSetup = TRUE;
}
#endif
/* copy from subfont */
font->blend.font = subFont->blend.font;
/* clear state of charstring blend */
font->blend.usedBV = FALSE;
/* initialize value for charstring */
font->vsindex = subFont->private_dict.vsindex;
/* store vector inputs for blends in charstring */
font->lenNDV = lenNormalizedV;
font->NDV = normalizedV;
}
}
/* if ppem has changed, we need to recompute some cached data */
/* note: because of CID font matrix concatenation, ppem and transform */
/* do not necessarily track. */
ppem = cf2_getPpemY( decoder );
if ( font->ppem != ppem )
{
font->ppem = ppem;
needExtraSetup = TRUE;
}
/* copy hinted flag on each call */
font->hinted = FT_BOOL( font->renderingFlags & CF2_FlagsHinted );
/* determine if transform has changed; */
/* include Fontmatrix but ignore translation */
if ( ft_memcmp( transform,
&font->currentTransform,
4 * sizeof ( CF2_Fixed ) ) != 0 )
{
/* save `key' information for `cache of one' matrix data; */
/* save client transform, without the translation */
font->currentTransform = *transform;
font->currentTransform.tx =
font->currentTransform.ty = cf2_intToFixed( 0 );
/* TODO: FreeType transform is simple scalar; for now, use identity */
/* for outer */
font->innerTransform = *transform;
font->outerTransform.a =
font->outerTransform.d = cf2_intToFixed( 1 );
font->outerTransform.b =
font->outerTransform.c = cf2_intToFixed( 0 );
needExtraSetup = TRUE;
}
/*
* font->darkened is set to true if there is a stem darkening request or
* the font is synthetic emboldened.
* font->darkened controls whether to adjust blue zones, winding order,
* and hinting.
*
*/
if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) )
{
font->stemDarkened =
FT_BOOL( font->renderingFlags & CF2_FlagsDarkened );
/* blue zones depend on darkened flag */
needExtraSetup = TRUE;
}
/* recompute variables that are dependent on transform or FontDict or */
/* darken flag */
if ( needExtraSetup )
{
/* StdVW is found in the private dictionary; */
/* recompute darkening amounts whenever private dictionary or */
/* transform change */
/* Note: a rendering flag turns darkening on or off, so we want to */
/* store the `on' amounts; */
/* darkening amount is computed in character space */
/* TODO: testing size-dependent darkening here; */
/* what to do for rotations? */
CF2_Fixed emRatio;
CF2_Fixed stdHW;
CF2_Int unitsPerEm = font->unitsPerEm;
if ( unitsPerEm == 0 )
unitsPerEm = 1000;
ppem = FT_MAX( cf2_intToFixed( 4 ),
font->ppem ); /* use minimum ppem of 4 */
#if 0
/* since vstem is measured in the x-direction, we use the `a' member */
/* of the fontMatrix */
emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a );
#endif
/* Freetype does not preserve the fontMatrix when parsing; use */
/* unitsPerEm instead. */
/* TODO: check precision of this */
emRatio = cf2_intToFixed( 1000 ) / unitsPerEm;
font->stdVW = cf2_getStdVW( decoder );
if ( font->stdVW <= 0 )
font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
if ( boldenX > 0 )
{
/* Ensure that boldenX is at least 1 pixel for synthetic bold font */
/* (similar to what Avalon does) */
boldenX = FT_MAX( boldenX,
FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) );
/* Synthetic emboldening adds at least 1 pixel to darkenX, while */
/* stem darkening adds at most half pixel. Since the purpose of */
/* stem darkening (readability at small sizes) is met with */
/* synthetic emboldening, no need to add stem darkening for a */
/* synthetic bold font. */
cf2_computeDarkening( emRatio,
ppem,
font->stdVW,
&font->darkenX,
boldenX,
FALSE,
font->darkenParams );
}
else
cf2_computeDarkening( emRatio,
ppem,
font->stdVW,
&font->darkenX,
0,
font->stemDarkened,
font->darkenParams );
#if 0
/* since hstem is measured in the y-direction, we use the `d' member */
/* of the fontMatrix */
/* TODO: use the same units per em as above; check this */
emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d );
#endif
/* set the default stem width, because it must be the same for all */
/* family members; */
/* choose a constant for StdHW that depends on font contrast */
stdHW = cf2_getStdHW( decoder );
if ( stdHW > 0 && font->stdVW > MUL_INT32( 2, stdHW ) )
font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
else
{
/* low contrast font gets less hstem darkening */
font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio );
}
cf2_computeDarkening( emRatio,
ppem,
font->stdHW,
&font->darkenY,
boldenY,
font->stemDarkened,
font->darkenParams );
if ( font->darkenX != 0 || font->darkenY != 0 )
font->darkened = TRUE;
else
font->darkened = FALSE;
font->reverseWinding = FALSE; /* initial expectation is CCW */
/* compute blue zones for this instance */
cf2_blues_init( &font->blues, font );
} /* needExtraSetup */
}
/* equivalent to AdobeGetOutline */
FT_LOCAL_DEF( FT_Error )
cf2_getGlyphOutline( CF2_Font font,
CF2_Buffer charstring,
const CF2_Matrix* transform,
CF2_F16Dot16* glyphWidth )
{
FT_Error lastError = FT_Err_Ok;
FT_Vector translation;
#if 0
FT_Vector advancePoint;
#endif
CF2_Fixed advWidth = 0;
FT_Bool needWinding;
/* Note: use both integer and fraction for outlines. This allows bbox */
/* to come out directly. */
translation.x = transform->tx;
translation.y = transform->ty;
/* set up values based on transform */
cf2_font_setup( font, transform );
if ( font->error )
goto exit; /* setup encountered an error */
/* reset darken direction */
font->reverseWinding = FALSE;
/* winding order only affects darkening */
needWinding = font->darkened;
while ( 1 )
{
/* reset output buffer */
cf2_outline_reset( &font->outline );
/* build the outline, passing the full translation */
cf2_interpT2CharString( font,
charstring,
(CF2_OutlineCallbacks)&font->outline,
&translation,
FALSE,
0,
0,
&advWidth );
if ( font->error )
goto exit;
if ( !needWinding )
break;
/* check winding order */
if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */
break;
/* invert darkening and render again */
/* TODO: this should be a parameter to getOutline-computeOffset */
font->reverseWinding = TRUE;
needWinding = FALSE; /* exit after next iteration */
}
/* finish storing client outline */
cf2_outline_close( &font->outline );
exit:
/* FreeType just wants the advance width; there is no translation */
*glyphWidth = advWidth;
/* free resources and collect errors from objects we've used */
cf2_setError( &font->error, lastError );
return font->error;
}
/* END */
+134
View File
@@ -0,0 +1,134 @@
/****************************************************************************
*
* psfont.h
*
* Adobe's code for font instances (specification).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSFONT_H_
#define PSFONT_H_
#include <freetype/internal/services/svcfftl.h>
#include "psft.h"
#include "psblues.h"
FT_BEGIN_HEADER
#define CF2_OPERAND_STACK_SIZE 48
#define CF2_MAX_SUBR 16 /* maximum subroutine nesting; */
/* only 10 are allowed but there exist */
/* fonts like `HiraKakuProN-W3.ttf' */
/* (Hiragino Kaku Gothic ProN W3; */
/* 8.2d6e1; 2014-12-19) that exceed */
/* this limit */
#define CF2_STORAGE_SIZE 32
/* typedef is in `cf2glue.h' */
struct CF2_FontRec_
{
FT_Memory memory;
FT_Error error; /* shared error for this instance */
FT_Bool isT1;
FT_Bool isCFF2;
CF2_RenderingFlags renderingFlags;
/* variables that depend on Transform: */
/* the following have zero translation; */
/* inner * outer = font * original */
CF2_Matrix currentTransform; /* original client matrix */
CF2_Matrix innerTransform; /* for hinting; erect, scaled */
CF2_Matrix outerTransform; /* post hinting; includes rotations */
CF2_Fixed ppem; /* transform-dependent */
/* variation data */
CFF_BlendRec blend; /* cached charstring blend vector */
CF2_UInt vsindex; /* current vsindex */
CF2_UInt lenNDV; /* current length NDV or zero */
FT_Fixed* NDV; /* ptr to current NDV or NULL */
CF2_Int unitsPerEm;
CF2_Fixed syntheticEmboldeningAmountX; /* character space units */
CF2_Fixed syntheticEmboldeningAmountY; /* character space units */
/* FreeType related members */
CF2_OutlineRec outline; /* freetype glyph outline functions */
PS_Decoder* decoder;
CFF_SubFont lastSubfont; /* FreeType parsed data; */
/* top font or subfont */
/* these flags can vary from one call to the next */
FT_Bool hinted;
FT_Bool darkened; /* true if stemDarkened or synthetic bold */
/* i.e. darkenX != 0 || darkenY != 0 */
FT_Bool stemDarkened;
FT_Int darkenParams[8]; /* 1000 unit character space */
/* variables that depend on both FontDict and Transform */
CF2_Fixed stdVW; /* in character space; depends on dict entry */
CF2_Fixed stdHW; /* in character space; depends on dict entry */
CF2_Fixed darkenX; /* character space units */
CF2_Fixed darkenY; /* depends on transform */
/* and private dict (StdVW) */
FT_Bool reverseWinding; /* darken assuming */
/* counterclockwise winding */
CF2_BluesRec blues; /* computed zone data */
FT_Service_CFFLoad cffload; /* pointer to cff functions */
};
FT_LOCAL( FT_Error )
cf2_getGlyphOutline( CF2_Font font,
CF2_Buffer charstring,
const CF2_Matrix* transform,
CF2_F16Dot16* glyphWidth );
FT_END_HEADER
#endif /* PSFONT_H_ */
/* END */
+895
View File
@@ -0,0 +1,895 @@
/****************************************************************************
*
* psft.c
*
* FreeType Glue Component to Adobe's Interpreter (body).
*
* Copyright 2013-2014 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include "psft.h"
#include <freetype/internal/ftdebug.h>
#include "psfont.h"
#include "pserror.h"
#include "psobjs.h"
#include "cffdecode.h"
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include <freetype/ftmm.h>
#include <freetype/internal/services/svmm.h>
#endif
#include <freetype/internal/services/svcfftl.h>
#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
/*
* This check should avoid most internal overflow cases. Clients should
* generally respond to `Glyph_Too_Big' by getting a glyph outline
* at EM size, scaling it and filling it as a graphics operation.
*
*/
static FT_Error
cf2_checkTransform( const CF2_Matrix* transform,
CF2_Int unitsPerEm )
{
CF2_Fixed maxScale;
if ( transform->a <= 0 || transform->d <= 0 )
return FT_THROW( Invalid_Size_Handle );
FT_ASSERT( unitsPerEm > 0 );
FT_ASSERT( transform->b == 0 && transform->c == 0 );
FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
if ( unitsPerEm > 0x7FFF )
return FT_THROW( Glyph_Too_Big );
maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) );
if ( transform->a > maxScale || transform->d > maxScale )
return FT_THROW( Glyph_Too_Big );
return FT_Err_Ok;
}
static void
cf2_setGlyphWidth( CF2_Outline outline,
CF2_Fixed width )
{
PS_Decoder* decoder = outline->decoder;
FT_ASSERT( decoder );
if ( !decoder->builder.is_t1 )
*decoder->glyph_width = cf2_fixedToInt( width );
}
/* Clean up font instance. */
static void
cf2_free_instance( void* ptr )
{
CF2_Font font = (CF2_Font)ptr;
if ( font )
{
FT_Memory memory = font->memory;
FT_FREE( font->blend.lastNDV );
FT_FREE( font->blend.BV );
}
}
/*********************************************
*
* functions for handling client outline;
* FreeType uses coordinates in 26.6 format
*
*/
static void
cf2_builder_moveTo( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params )
{
/* downcast the object pointer */
CF2_Outline outline = (CF2_Outline)callbacks;
PS_Builder* builder;
(void)params; /* only used in debug mode */
FT_ASSERT( outline && outline->decoder );
FT_ASSERT( params->op == CF2_PathOpMoveTo );
builder = &outline->decoder->builder;
/* note: two successive moves simply close the contour twice */
ps_builder_close_contour( builder );
builder->path_begun = 0;
}
static void
cf2_builder_lineTo( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params )
{
FT_Error error;
/* downcast the object pointer */
CF2_Outline outline = (CF2_Outline)callbacks;
PS_Builder* builder;
FT_ASSERT( outline && outline->decoder );
FT_ASSERT( params->op == CF2_PathOpLineTo );
builder = &outline->decoder->builder;
if ( !builder->path_begun )
{
/* record the move before the line; also check points and set */
/* `path_begun' */
error = ps_builder_start_point( builder,
params->pt0.x,
params->pt0.y );
if ( error )
{
if ( !*callbacks->error )
*callbacks->error = error;
return;
}
}
/* `ps_builder_add_point1' includes a check_points call for one point */
error = ps_builder_add_point1( builder,
params->pt1.x,
params->pt1.y );
if ( error )
{
if ( !*callbacks->error )
*callbacks->error = error;
return;
}
}
static void
cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params )
{
FT_Error error;
/* downcast the object pointer */
CF2_Outline outline = (CF2_Outline)callbacks;
PS_Builder* builder;
FT_ASSERT( outline && outline->decoder );
FT_ASSERT( params->op == CF2_PathOpCubeTo );
builder = &outline->decoder->builder;
if ( !builder->path_begun )
{
/* record the move before the line; also check points and set */
/* `path_begun' */
error = ps_builder_start_point( builder,
params->pt0.x,
params->pt0.y );
if ( error )
{
if ( !*callbacks->error )
*callbacks->error = error;
return;
}
}
/* prepare room for 3 points: 2 off-curve, 1 on-curve */
error = ps_builder_check_points( builder, 3 );
if ( error )
{
if ( !*callbacks->error )
*callbacks->error = error;
return;
}
ps_builder_add_point( builder,
params->pt1.x,
params->pt1.y, 0 );
ps_builder_add_point( builder,
params->pt2.x,
params->pt2.y, 0 );
ps_builder_add_point( builder,
params->pt3.x,
params->pt3.y, 1 );
}
static void
cf2_outline_init( CF2_Outline outline,
FT_Memory memory,
FT_Error* error )
{
FT_ZERO( outline );
outline->root.memory = memory;
outline->root.error = error;
outline->root.moveTo = cf2_builder_moveTo;
outline->root.lineTo = cf2_builder_lineTo;
outline->root.cubeTo = cf2_builder_cubeTo;
}
/* get scaling and hint flag from GlyphSlot */
static void
cf2_getScaleAndHintFlag( PS_Decoder* decoder,
CF2_Fixed* x_scale,
CF2_Fixed* y_scale,
FT_Bool* hinted,
FT_Bool* scaled )
{
FT_ASSERT( decoder && decoder->builder.glyph );
/* note: FreeType scale includes a factor of 64 */
*hinted = decoder->builder.glyph->hint;
*scaled = decoder->builder.glyph->scaled;
if ( *hinted )
{
*x_scale = ADD_INT32( decoder->builder.glyph->x_scale, 32 ) / 64;
*y_scale = ADD_INT32( decoder->builder.glyph->y_scale, 32 ) / 64;
}
else
{
/* for unhinted outlines, `cff_slot_load' does the scaling, */
/* thus render at `unity' scale */
*x_scale = 0x0400; /* 1/64 as 16.16 */
*y_scale = 0x0400;
}
}
/* get units per em from `FT_Face' */
/* TODO: should handle font matrix concatenation? */
static FT_UShort
cf2_getUnitsPerEm( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->builder.face );
return decoder->builder.face->units_per_EM;
}
/* Main entry point: Render one glyph. */
FT_LOCAL_DEF( FT_Error )
cf2_decoder_parse_charstrings( PS_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len )
{
FT_Memory memory;
FT_Error error = FT_Err_Ok;
CF2_Font font;
FT_Bool is_t1 = decoder->builder.is_t1;
FT_ASSERT( decoder &&
( is_t1 || decoder->cff ) );
if ( is_t1 && !decoder->current_subfont )
{
FT_ERROR(( "cf2_decoder_parse_charstrings (Type 1): "
"SubFont missing. Use `t1_make_subfont' first\n" ));
return FT_THROW( Invalid_Table );
}
memory = decoder->builder.memory;
/* CF2 data is saved here across glyphs */
font = (CF2_Font)decoder->cf2_instance->data;
/* on first glyph, allocate instance structure */
if ( !decoder->cf2_instance->data )
{
decoder->cf2_instance->finalizer =
(FT_Generic_Finalizer)cf2_free_instance;
if ( FT_ALLOC( decoder->cf2_instance->data,
sizeof ( CF2_FontRec ) ) )
return FT_THROW( Out_Of_Memory );
font = (CF2_Font)decoder->cf2_instance->data;
font->memory = memory;
if ( !is_t1 )
font->cffload = (FT_Service_CFFLoad)decoder->cff->cffload;
/* initialize a client outline, to be shared by each glyph rendered */
cf2_outline_init( &font->outline, font->memory, &font->error );
}
/* save decoder; it is a stack variable and will be different on each */
/* call */
font->decoder = decoder;
font->outline.decoder = decoder;
{
/* build parameters for Adobe engine */
PS_Builder* builder = &decoder->builder;
PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face );
FT_Bool no_stem_darkening_driver =
driver->no_stem_darkening;
FT_Char no_stem_darkening_font =
builder->face->internal->no_stem_darkening;
/* local error */
FT_Error error2 = FT_Err_Ok;
CF2_BufferRec buf;
CF2_Matrix transform;
CF2_F16Dot16 glyphWidth;
FT_Bool hinted;
FT_Bool scaled;
/* FreeType has already looked up the GID; convert to */
/* `RegionBuffer', assuming that the input has been validated */
FT_ASSERT( charstring_base + charstring_len >= charstring_base );
FT_ZERO( &buf );
buf.start =
buf.ptr = charstring_base;
buf.end = FT_OFFSET( charstring_base, charstring_len );
FT_ZERO( &transform );
cf2_getScaleAndHintFlag( decoder,
&transform.a,
&transform.d,
&hinted,
&scaled );
if ( is_t1 )
font->isCFF2 = FALSE;
else
{
/* copy isCFF2 boolean from TT_Face to CF2_Font */
font->isCFF2 = ((TT_Face)builder->face)->is_cff2;
}
font->isT1 = is_t1;
font->renderingFlags = 0;
if ( hinted )
font->renderingFlags |= CF2_FlagsHinted;
if ( scaled && ( !no_stem_darkening_font ||
( no_stem_darkening_font < 0 &&
!no_stem_darkening_driver ) ) )
font->renderingFlags |= CF2_FlagsDarkened;
font->darkenParams[0] = driver->darken_params[0];
font->darkenParams[1] = driver->darken_params[1];
font->darkenParams[2] = driver->darken_params[2];
font->darkenParams[3] = driver->darken_params[3];
font->darkenParams[4] = driver->darken_params[4];
font->darkenParams[5] = driver->darken_params[5];
font->darkenParams[6] = driver->darken_params[6];
font->darkenParams[7] = driver->darken_params[7];
/* now get an outline for this glyph; */
/* also get units per em to validate scale */
font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder );
if ( scaled )
{
error2 = cf2_checkTransform( &transform, font->unitsPerEm );
if ( error2 )
return error2;
}
error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth );
if ( error2 )
return FT_ERR( Invalid_File_Format );
cf2_setGlyphWidth( &font->outline, glyphWidth );
return FT_Err_Ok;
}
}
/* get pointer to current FreeType subfont (based on current glyphID) */
FT_LOCAL_DEF( CFF_SubFont )
cf2_getSubfont( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return decoder->current_subfont;
}
/* get pointer to VStore structure */
FT_LOCAL_DEF( CFF_VStore )
cf2_getVStore( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->cff );
return &decoder->cff->vstore;
}
/* get maxstack value from CFF2 Top DICT */
FT_LOCAL_DEF( FT_UInt )
cf2_getMaxstack( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->cff );
return decoder->cff->top_font.font_dict.maxstack;
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
/* Get normalized design vector for current render request; */
/* return pointer and length. */
/* */
/* Note: Uses FT_Fixed not CF2_Fixed for the vector. */
FT_LOCAL_DEF( FT_Error )
cf2_getNormalizedVector( PS_Decoder* decoder,
CF2_UInt *len,
FT_Fixed* *vec )
{
TT_Face face;
FT_Service_MultiMasters mm;
FT_ASSERT( decoder && decoder->builder.face );
FT_ASSERT( vec && len );
FT_ASSERT( !decoder->builder.is_t1 );
face = (TT_Face)decoder->builder.face;
mm = (FT_Service_MultiMasters)face->mm;
return mm->get_var_blend( FT_FACE( face ), len, NULL, vec, NULL );
}
#endif
/* get `y_ppem' from `CFF_Size' */
FT_LOCAL_DEF( CF2_Fixed )
cf2_getPpemY( PS_Decoder* decoder )
{
FT_ASSERT( decoder &&
decoder->builder.face &&
decoder->builder.face->size );
/*
* Note that `y_ppem' can be zero if there wasn't a call to
* `FT_Set_Char_Size' or something similar. However, this isn't a
* problem since we come to this place in the code only if
* FT_LOAD_NO_SCALE is set (the other case gets caught by
* `cf2_checkTransform'). The ppem value is needed to compute the stem
* darkening, which is disabled for getting the unscaled outline.
*
*/
return cf2_intToFixed(
decoder->builder.face->size->metrics.y_ppem );
}
/* get standard stem widths for the current subfont; */
/* FreeType stores these as integer font units */
/* (note: variable names seem swapped) */
FT_LOCAL_DEF( CF2_Fixed )
cf2_getStdVW( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.standard_height );
}
FT_LOCAL_DEF( CF2_Fixed )
cf2_getStdHW( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.standard_width );
}
/* note: FreeType stores 1000 times the actual value for `BlueScale' */
FT_LOCAL_DEF( void )
cf2_getBlueMetrics( PS_Decoder* decoder,
CF2_Fixed* blueScale,
CF2_Fixed* blueShift,
CF2_Fixed* blueFuzz )
{
FT_ASSERT( decoder && decoder->current_subfont );
*blueScale = FT_DivFix(
decoder->current_subfont->private_dict.blue_scale,
cf2_intToFixed( 1000 ) );
*blueShift = cf2_intToFixed(
decoder->current_subfont->private_dict.blue_shift );
*blueFuzz = cf2_intToFixed(
decoder->current_subfont->private_dict.blue_fuzz );
}
/* get blue values counts and arrays; the FreeType parser has validated */
/* the counts and verified that each is an even number */
FT_LOCAL_DEF( void )
cf2_getBlueValues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_blue_values;
*data = (FT_Fixed*)
&decoder->current_subfont->private_dict.blue_values;
}
FT_LOCAL_DEF( void )
cf2_getOtherBlues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_other_blues;
*data = (FT_Fixed*)
&decoder->current_subfont->private_dict.other_blues;
}
FT_LOCAL_DEF( void )
cf2_getFamilyBlues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_family_blues;
*data = (FT_Fixed*)
&decoder->current_subfont->private_dict.family_blues;
}
FT_LOCAL_DEF( void )
cf2_getFamilyOtherBlues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_family_other_blues;
*data = (FT_Fixed*)
&decoder->current_subfont->private_dict.family_other_blues;
}
FT_LOCAL_DEF( CF2_Int )
cf2_getLanguageGroup( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return decoder->current_subfont->private_dict.language_group;
}
/* convert unbiased subroutine index to `CF2_Buffer' and */
/* return 0 on success */
FT_LOCAL_DEF( CF2_Int )
cf2_initGlobalRegionBuffer( PS_Decoder* decoder,
CF2_Int subrNum,
CF2_Buffer buf )
{
CF2_UInt idx;
FT_ASSERT( decoder );
FT_ZERO( buf );
idx = (CF2_UInt)( subrNum + decoder->globals_bias );
if ( idx >= decoder->num_globals )
return TRUE; /* error */
FT_ASSERT( decoder->globals );
buf->start =
buf->ptr = decoder->globals[idx];
buf->end = decoder->globals[idx + 1];
return FALSE; /* success */
}
/* convert AdobeStandardEncoding code to CF2_Buffer; */
/* used for seac component */
FT_LOCAL_DEF( FT_Error )
cf2_getSeacComponent( PS_Decoder* decoder,
CF2_Int code,
CF2_Buffer buf )
{
CF2_Int gid;
FT_Byte* charstring;
FT_ULong len;
FT_Error error;
FT_ASSERT( decoder );
FT_ASSERT( !decoder->builder.is_t1 );
FT_ZERO( buf );
#ifdef FT_CONFIG_OPTION_INCREMENTAL
/* Incremental fonts don't necessarily have valid charsets. */
/* They use the character code, not the glyph index, in this case. */
if ( decoder->builder.face->internal->incremental_interface )
gid = code;
else
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
{
gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
if ( gid < 0 )
return FT_THROW( Invalid_Glyph_Format );
}
error = decoder->get_glyph_callback( (TT_Face)decoder->builder.face,
(CF2_UInt)gid,
&charstring,
&len );
/* TODO: for now, just pass the FreeType error through */
if ( error )
return error;
/* assume input has been validated */
FT_ASSERT( charstring + len >= charstring );
buf->start = charstring;
buf->end = FT_OFFSET( charstring, len );
buf->ptr = buf->start;
return FT_Err_Ok;
}
FT_LOCAL_DEF( void )
cf2_freeSeacComponent( PS_Decoder* decoder,
CF2_Buffer buf )
{
FT_ASSERT( decoder );
FT_ASSERT( !decoder->builder.is_t1 );
decoder->free_glyph_callback( (TT_Face)decoder->builder.face,
(FT_Byte**)&buf->start,
(FT_ULong)( buf->end - buf->start ) );
}
FT_LOCAL_DEF( FT_Error )
cf2_getT1SeacComponent( PS_Decoder* decoder,
FT_UInt glyph_index,
CF2_Buffer buf )
{
FT_Data glyph_data;
FT_Error error = FT_Err_Ok;
T1_Face face = (T1_Face)decoder->builder.face;
T1_Font type1 = &face->type1;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
FT_Incremental_InterfaceRec *inc =
face->root.internal->incremental_interface;
/* For incremental fonts get the character data using the */
/* callback function. */
if ( inc )
error = inc->funcs->get_glyph_data( inc->object,
glyph_index, &glyph_data );
else
#endif
/* For ordinary fonts get the character data stored in the face record. */
{
glyph_data.pointer = type1->charstrings[glyph_index];
glyph_data.length = type1->charstrings_len[glyph_index];
}
if ( !error )
{
FT_Byte* charstring_base = (FT_Byte*)glyph_data.pointer;
FT_ULong charstring_len = glyph_data.length;
FT_ASSERT( charstring_base + charstring_len >= charstring_base );
FT_ZERO( buf );
buf->start =
buf->ptr = charstring_base;
buf->end = charstring_base + charstring_len;
}
return error;
}
FT_LOCAL_DEF( void )
cf2_freeT1SeacComponent( PS_Decoder* decoder,
CF2_Buffer buf )
{
#ifdef FT_CONFIG_OPTION_INCREMENTAL
T1_Face face;
FT_Data data;
FT_ASSERT( decoder );
face = (T1_Face)decoder->builder.face;
data.pointer = buf->start;
data.length = (FT_UInt)( buf->end - buf->start );
if ( face->root.internal->incremental_interface )
face->root.internal->incremental_interface->funcs->free_glyph_data(
face->root.internal->incremental_interface->object,
&data );
#else /* !FT_CONFIG_OPTION_INCREMENTAL */
FT_UNUSED( decoder );
FT_UNUSED( buf );
#endif /* !FT_CONFIG_OPTION_INCREMENTAL */
}
FT_LOCAL_DEF( CF2_Int )
cf2_initLocalRegionBuffer( PS_Decoder* decoder,
CF2_Int subrNum,
CF2_Buffer buf )
{
CF2_UInt idx;
FT_ASSERT( decoder );
FT_ZERO( buf );
idx = (CF2_UInt)( subrNum + decoder->locals_bias );
if ( idx >= decoder->num_locals )
return TRUE; /* error */
FT_ASSERT( decoder->locals );
buf->start = decoder->locals[idx];
if ( decoder->builder.is_t1 )
{
/* 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. */
if ( decoder->locals_len )
buf->end = FT_OFFSET( buf->start, decoder->locals_len[idx] );
else
{
/* We are using subroutines from a CID font. We must adjust */
/* for the seed bytes. */
buf->start += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
buf->end = decoder->locals[idx + 1];
}
if ( !buf->start )
{
FT_ERROR(( "cf2_initLocalRegionBuffer (Type 1 mode):"
" invoking empty subrs\n" ));
}
}
else
{
buf->end = decoder->locals[idx + 1];
}
buf->ptr = buf->start;
return FALSE; /* success */
}
FT_LOCAL_DEF( CF2_Fixed )
cf2_getDefaultWidthX( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.default_width );
}
FT_LOCAL_DEF( CF2_Fixed )
cf2_getNominalWidthX( PS_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.nominal_width );
}
FT_LOCAL_DEF( void )
cf2_outline_reset( CF2_Outline outline )
{
PS_Decoder* decoder = outline->decoder;
FT_ASSERT( decoder );
outline->root.windingMomentum = 0;
FT_GlyphLoader_Rewind( decoder->builder.loader );
}
FT_LOCAL_DEF( void )
cf2_outline_close( CF2_Outline outline )
{
PS_Decoder* decoder = outline->decoder;
FT_ASSERT( decoder );
ps_builder_close_contour( &decoder->builder );
FT_GlyphLoader_Add( decoder->builder.loader );
}
/* END */
+167
View File
@@ -0,0 +1,167 @@
/****************************************************************************
*
* psft.h
*
* FreeType Glue Component to Adobe's Interpreter (specification).
*
* Copyright 2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSFT_H_
#define PSFT_H_
#include <freetype/internal/compiler-macros.h>
#include "pstypes.h"
/* TODO: disable asserts for now */
#define CF2_NDEBUG
#include <freetype/ftsystem.h>
#include "psglue.h"
#include <freetype/internal/psaux.h> /* for PS_Decoder */
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cf2_decoder_parse_charstrings( PS_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len );
FT_LOCAL( CFF_SubFont )
cf2_getSubfont( PS_Decoder* decoder );
FT_LOCAL( CFF_VStore )
cf2_getVStore( PS_Decoder* decoder );
FT_LOCAL( FT_UInt )
cf2_getMaxstack( PS_Decoder* decoder );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_LOCAL( FT_Error )
cf2_getNormalizedVector( PS_Decoder* decoder,
CF2_UInt *len,
FT_Fixed* *vec );
#endif
FT_LOCAL( CF2_Fixed )
cf2_getPpemY( PS_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getStdVW( PS_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getStdHW( PS_Decoder* decoder );
FT_LOCAL( void )
cf2_getBlueMetrics( PS_Decoder* decoder,
CF2_Fixed* blueScale,
CF2_Fixed* blueShift,
CF2_Fixed* blueFuzz );
FT_LOCAL( void )
cf2_getBlueValues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data );
FT_LOCAL( void )
cf2_getOtherBlues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data );
FT_LOCAL( void )
cf2_getFamilyBlues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data );
FT_LOCAL( void )
cf2_getFamilyOtherBlues( PS_Decoder* decoder,
size_t* count,
FT_Fixed* *data );
FT_LOCAL( CF2_Int )
cf2_getLanguageGroup( PS_Decoder* decoder );
FT_LOCAL( CF2_Int )
cf2_initGlobalRegionBuffer( PS_Decoder* decoder,
CF2_Int subrNum,
CF2_Buffer buf );
FT_LOCAL( FT_Error )
cf2_getSeacComponent( PS_Decoder* decoder,
CF2_Int code,
CF2_Buffer buf );
FT_LOCAL( void )
cf2_freeSeacComponent( PS_Decoder* decoder,
CF2_Buffer buf );
FT_LOCAL( CF2_Int )
cf2_initLocalRegionBuffer( PS_Decoder* decoder,
CF2_Int subrNum,
CF2_Buffer buf );
FT_LOCAL( CF2_Fixed )
cf2_getDefaultWidthX( PS_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getNominalWidthX( PS_Decoder* decoder );
FT_LOCAL( FT_Error )
cf2_getT1SeacComponent( PS_Decoder* decoder,
FT_UInt glyph_index,
CF2_Buffer buf );
FT_LOCAL( void )
cf2_freeT1SeacComponent( PS_Decoder* decoder,
CF2_Buffer buf );
/*
* FreeType client outline
*
* process output from the charstring interpreter
*/
typedef struct CF2_OutlineRec_
{
CF2_OutlineCallbacksRec root; /* base class must be first */
PS_Decoder* decoder;
} CF2_OutlineRec, *CF2_Outline;
FT_LOCAL( void )
cf2_outline_reset( CF2_Outline outline );
FT_LOCAL( void )
cf2_outline_close( CF2_Outline outline );
FT_END_HEADER
#endif /* PSFT_H_ */
/* END */
+144
View File
@@ -0,0 +1,144 @@
/****************************************************************************
*
* psglue.h
*
* Adobe's code for shared stuff (specification only).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSGLUE_H_
#define PSGLUE_H_
/* common includes for other modules */
#include "pserror.h"
#include "psfixed.h"
#include "psarrst.h"
#include "psread.h"
FT_BEGIN_HEADER
/* rendering parameters */
/* apply hints to rendered glyphs */
#define CF2_FlagsHinted 1
/* for testing */
#define CF2_FlagsDarkened 2
/* type for holding the flags */
typedef CF2_Int CF2_RenderingFlags;
/* elements of a glyph outline */
typedef enum CF2_PathOp_
{
CF2_PathOpMoveTo = 1, /* change the current point */
CF2_PathOpLineTo = 2, /* line */
CF2_PathOpQuadTo = 3, /* quadratic curve */
CF2_PathOpCubeTo = 4 /* cubic curve */
} CF2_PathOp;
/* a matrix of fixed-point values */
typedef struct CF2_Matrix_
{
CF2_F16Dot16 a;
CF2_F16Dot16 b;
CF2_F16Dot16 c;
CF2_F16Dot16 d;
CF2_F16Dot16 tx;
CF2_F16Dot16 ty;
} CF2_Matrix;
/* these typedefs are needed by more than one header file */
/* and gcc compiler doesn't allow redefinition */
typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font;
typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint;
/* A common structure for all callback parameters. */
/* */
/* Some members may be unused. For example, `pt0' is not used for */
/* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */
/* is included for each path element for generality; curve conversions */
/* need it. The `op' parameter allows one function to handle multiple */
/* element types. */
typedef struct CF2_CallbackParamsRec_
{
FT_Vector pt0;
FT_Vector pt1;
FT_Vector pt2;
FT_Vector pt3;
CF2_Int op;
} CF2_CallbackParamsRec, *CF2_CallbackParams;
/* forward reference */
typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec,
*CF2_OutlineCallbacks;
/* callback function pointers */
typedef void
(*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params );
struct CF2_OutlineCallbacksRec_
{
CF2_Callback_Type moveTo;
CF2_Callback_Type lineTo;
CF2_Callback_Type quadTo;
CF2_Callback_Type cubeTo;
CF2_Int windingMomentum; /* for winding order detection */
FT_Memory memory;
FT_Error* error;
};
FT_END_HEADER
#endif /* PSGLUE_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,288 @@
/****************************************************************************
*
* pshints.h
*
* Adobe's code for handling CFF hints (body).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSHINT_H_
#define PSHINT_H_
FT_BEGIN_HEADER
enum
{
CF2_MAX_HINTS = 96 /* maximum # of hints */
};
/*
* A HintMask object stores a bit mask that specifies which hints in the
* charstring are active at a given time. Hints in CFF must be declared
* at the start, before any drawing operators, with horizontal hints
* preceding vertical hints. The HintMask is ordered the same way, with
* horizontal hints immediately followed by vertical hints. Clients are
* responsible for knowing how many of each type are present.
*
* The maximum total number of hints is 96, as specified by the CFF
* specification.
*
* A HintMask is built 0 or more times while interpreting a charstring, by
* the HintMask operator. There is only one HintMask, but it is built or
* rebuilt each time there is a hint substitution (HintMask operator) in
* the charstring. A default HintMask with all bits set is built if there
* has been no HintMask operator prior to the first drawing operator.
*
*/
typedef struct CF2_HintMaskRec_
{
FT_Error* error;
FT_Bool isValid;
FT_Bool isNew;
size_t bitCount;
size_t byteCount;
FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8];
} CF2_HintMaskRec, *CF2_HintMask;
typedef struct CF2_StemHintRec_
{
FT_Bool used; /* DS positions are valid */
CF2_Fixed min; /* original character space value */
CF2_Fixed max;
CF2_Fixed minDS; /* DS position after first use */
CF2_Fixed maxDS;
} CF2_StemHintRec, *CF2_StemHint;
/*
* A HintMap object stores a piecewise linear function for mapping
* y-coordinates from character space to device space, providing
* appropriate pixel alignment to stem edges.
*
* The map is implemented as an array of `CF2_Hint' elements, each
* representing an edge. When edges are paired, as from stem hints, the
* bottom edge must immediately precede the top edge in the array.
* Element character space AND device space positions must both increase
* monotonically in the array. `CF2_Hint' elements are also used as
* parameters to `cf2_blues_capture'.
*
* The `cf2_hintmap_build' method must be called before any drawing
* operation (beginning with a Move operator) and at each hint
* substitution (HintMask operator).
*
* The `cf2_hintmap_map' method is called to transform y-coordinates at
* each drawing operation (move, line, curve).
*
*/
/* TODO: make this a CF2_ArrStack and add a deep copy method */
enum
{
CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2
};
typedef struct CF2_HintMapRec_
{
CF2_Font font;
/* initial map based on blue zones */
struct CF2_HintMapRec_* initialHintMap;
/* working storage for 2nd pass adjustHints */
CF2_ArrStack hintMoves;
FT_Bool isValid;
FT_Bool hinted;
CF2_Fixed scale;
CF2_UInt count;
/* start search from this index */
CF2_UInt lastIndex;
CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */
} CF2_HintMapRec, *CF2_HintMap;
FT_LOCAL( FT_Bool )
cf2_hint_isValid( const CF2_Hint hint );
FT_LOCAL( FT_Bool )
cf2_hint_isTop( const CF2_Hint hint );
FT_LOCAL( FT_Bool )
cf2_hint_isBottom( const CF2_Hint hint );
FT_LOCAL( void )
cf2_hint_lock( CF2_Hint hint );
FT_LOCAL( void )
cf2_hintmap_init( CF2_HintMap hintmap,
CF2_Font font,
CF2_HintMap initialMap,
CF2_ArrStack hintMoves,
CF2_Fixed scale );
FT_LOCAL( void )
cf2_hintmap_build( CF2_HintMap hintmap,
CF2_ArrStack hStemHintArray,
CF2_ArrStack vStemHintArray,
CF2_HintMask hintMask,
CF2_Fixed hintOrigin,
FT_Bool initialMap );
/*
* GlyphPath is a wrapper for drawing operations that scales the
* coordinates according to the render matrix and HintMap. It also tracks
* open paths to control ClosePath and to insert MoveTo for broken fonts.
*
*/
typedef struct CF2_GlyphPathRec_
{
/* TODO: gather some of these into a hinting context */
CF2_Font font; /* font instance */
CF2_OutlineCallbacks callbacks; /* outline consumer */
CF2_HintMapRec hintMap; /* current hint map */
CF2_HintMapRec firstHintMap; /* saved copy */
CF2_HintMapRec initialHintMap; /* based on all captured hints */
CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */
CF2_Fixed scaleX; /* matrix a */
CF2_Fixed scaleC; /* matrix c */
CF2_Fixed scaleY; /* matrix d */
FT_Vector fractionalTranslation; /* including deviceXScale */
#if 0
CF2_Fixed hShift; /* character space horizontal shift */
/* (for fauxing) */
#endif
FT_Bool pathIsOpen; /* true after MoveTo */
FT_Bool pathIsClosing; /* true when synthesizing closepath line */
FT_Bool darken; /* true if stem darkening */
FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */
/* references used to call `cf2_hintmap_build', if necessary */
CF2_ArrStack hStemHintArray;
CF2_ArrStack vStemHintArray;
CF2_HintMask hintMask; /* ptr to the current mask */
CF2_Fixed hintOriginY; /* copy of current origin */
const CF2_BluesRec* blues;
CF2_Fixed xOffset; /* character space offsets */
CF2_Fixed yOffset;
/* character space miter limit threshold */
CF2_Fixed miterLimit;
/* vertical/horizontal snap distance in character space */
CF2_Fixed snapThreshold;
FT_Vector offsetStart0; /* first and second points of first */
FT_Vector offsetStart1; /* element with offset applied */
/* current point, character space, before offset */
FT_Vector currentCS;
/* current point, device space */
FT_Vector currentDS;
/* start point of subpath, character space */
FT_Vector start;
/* the following members constitute the `queue' of one element */
FT_Bool elemIsQueued;
CF2_Int prevElemOp;
FT_Vector prevElemP0;
FT_Vector prevElemP1;
FT_Vector prevElemP2;
FT_Vector prevElemP3;
} CF2_GlyphPathRec, *CF2_GlyphPath;
FT_LOCAL( void )
cf2_glyphpath_init( CF2_GlyphPath glyphpath,
CF2_Font font,
CF2_OutlineCallbacks callbacks,
CF2_Fixed scaleY,
/* CF2_Fixed hShift, */
CF2_ArrStack hStemHintArray,
CF2_ArrStack vStemHintArray,
CF2_HintMask hintMask,
CF2_Fixed hintOrigin,
const CF2_Blues blues,
const FT_Vector* fractionalTranslation );
FT_LOCAL( void )
cf2_glyphpath_finalize( CF2_GlyphPath glyphpath );
FT_LOCAL( void )
cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath,
CF2_Fixed x,
CF2_Fixed y );
FT_LOCAL( void )
cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath,
CF2_Fixed x,
CF2_Fixed y );
FT_LOCAL( void )
cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath,
CF2_Fixed x1,
CF2_Fixed y1,
CF2_Fixed x2,
CF2_Fixed y2,
CF2_Fixed x3,
CF2_Fixed y3 );
FT_LOCAL( void )
cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath );
FT_END_HEADER
#endif /* PSHINT_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,83 @@
/****************************************************************************
*
* psintrp.h
*
* Adobe's CFF Interpreter (specification).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSINTRP_H_
#define PSINTRP_H_
#include "psft.h"
#include "pshints.h"
FT_BEGIN_HEADER
FT_LOCAL( void )
cf2_hintmask_init( CF2_HintMask hintmask,
FT_Error* error );
FT_LOCAL( FT_Bool )
cf2_hintmask_isValid( const CF2_HintMask hintmask );
FT_LOCAL( FT_Bool )
cf2_hintmask_isNew( const CF2_HintMask hintmask );
FT_LOCAL( void )
cf2_hintmask_setNew( CF2_HintMask hintmask,
FT_Bool val );
FT_LOCAL( FT_Byte* )
cf2_hintmask_getMaskPtr( CF2_HintMask hintmask );
FT_LOCAL( void )
cf2_hintmask_setAll( CF2_HintMask hintmask,
size_t bitCount );
FT_LOCAL( void )
cf2_interpT2CharString( CF2_Font font,
const CF2_Buffer buf,
CF2_OutlineCallbacks callbacks,
const FT_Vector* translation,
FT_Bool doingSeac,
CF2_Fixed curX,
CF2_Fixed curY,
CF2_Fixed* width );
FT_END_HEADER
#endif /* PSINTRP_H_ */
/* END */
File diff suppressed because it is too large Load Diff
+312
View File
@@ -0,0 +1,312 @@
/****************************************************************************
*
* psobjs.h
*
* Auxiliary functions for PostScript fonts (specification).
*
* Copyright (C) 1996-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef PSOBJS_H_
#define PSOBJS_H_
#include <freetype/internal/psaux.h>
#include <freetype/internal/cffotypes.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,
const void* object,
FT_UInt 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_ULong* 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 );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CFF BUILDER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
cff_builder_init( CFF_Builder* builder,
TT_Face face,
CFF_Size size,
CFF_GlyphSlot glyph,
FT_Bool hinting );
FT_LOCAL( void )
cff_builder_done( CFF_Builder* builder );
FT_LOCAL( FT_Error )
cff_check_points( CFF_Builder* builder,
FT_Int count );
FT_LOCAL( void )
cff_builder_add_point( CFF_Builder* builder,
FT_Pos x,
FT_Pos y,
FT_Byte flag );
FT_LOCAL( FT_Error )
cff_builder_add_point1( CFF_Builder* builder,
FT_Pos x,
FT_Pos y );
FT_LOCAL( FT_Error )
cff_builder_start_point( CFF_Builder* builder,
FT_Pos x,
FT_Pos y );
FT_LOCAL( void )
cff_builder_close_contour( CFF_Builder* builder );
FT_LOCAL( FT_Error )
cff_builder_add_contour( CFF_Builder* builder );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** PS BUILDER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
ps_builder_init( PS_Builder* ps_builder,
void* builder,
FT_Bool is_t1 );
FT_LOCAL( void )
ps_builder_done( PS_Builder* builder );
FT_LOCAL( FT_Error )
ps_builder_check_points( PS_Builder* builder,
FT_Int count );
FT_LOCAL( void )
ps_builder_add_point( PS_Builder* builder,
FT_Pos x,
FT_Pos y,
FT_Byte flag );
FT_LOCAL( FT_Error )
ps_builder_add_point1( PS_Builder* builder,
FT_Pos x,
FT_Pos y );
FT_LOCAL( FT_Error )
ps_builder_add_contour( PS_Builder* builder );
FT_LOCAL( FT_Error )
ps_builder_start_point( PS_Builder* builder,
FT_Pos x,
FT_Pos y );
FT_LOCAL( void )
ps_builder_close_contour( PS_Builder* builder );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** OTHER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
ps_decoder_init( PS_Decoder* ps_decoder,
void* decoder,
FT_Bool is_t1 );
FT_LOCAL( void )
t1_make_subfont( FT_Face face,
PS_Private priv,
CFF_SubFont subfont );
FT_LOCAL( void )
t1_decrypt( FT_Byte* buffer,
FT_Offset length,
FT_UShort seed );
FT_LOCAL( FT_UInt32 )
cff_random( FT_UInt32 r );
FT_END_HEADER
#endif /* PSOBJS_H_ */
/* END */
+112
View File
@@ -0,0 +1,112 @@
/****************************************************************************
*
* psread.c
*
* Adobe's code for stream handling (body).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include "psft.h"
#include <freetype/internal/ftdebug.h>
#include "psglue.h"
#include "pserror.h"
/* Define CF2_IO_FAIL as 1 to enable random errors and random */
/* value errors in I/O. */
#define CF2_IO_FAIL 0
#if CF2_IO_FAIL
/* set the .00 value to a nonzero probability */
static int
randomError2( void )
{
/* for region buffer ReadByte (interp) function */
return (double)rand() / RAND_MAX < .00;
}
/* set the .00 value to a nonzero probability */
static CF2_Int
randomValue()
{
return (double)rand() / RAND_MAX < .00 ? rand() : 0;
}
#endif /* CF2_IO_FAIL */
/* Region Buffer */
/* */
/* Can be constructed from a copied buffer managed by */
/* `FCM_getDatablock'. */
/* Reads bytes with check for end of buffer. */
/* reading past the end of the buffer sets error and returns zero */
FT_LOCAL_DEF( CF2_Int )
cf2_buf_readByte( CF2_Buffer buf )
{
if ( buf->ptr < buf->end )
{
#if CF2_IO_FAIL
if ( randomError2() )
{
CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
return 0;
}
return *(buf->ptr)++ + randomValue();
#else
return *(buf->ptr)++;
#endif
}
else
{
CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
return 0;
}
}
/* note: end condition can occur without error */
FT_LOCAL_DEF( FT_Bool )
cf2_buf_isEnd( CF2_Buffer buf )
{
return FT_BOOL( buf->ptr >= buf->end );
}
/* END */
@@ -0,0 +1,68 @@
/****************************************************************************
*
* psread.h
*
* Adobe's code for stream handling (specification).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSREAD_H_
#define PSREAD_H_
FT_BEGIN_HEADER
typedef struct CF2_BufferRec_
{
FT_Error* error;
const FT_Byte* start;
const FT_Byte* end;
const FT_Byte* ptr;
} CF2_BufferRec, *CF2_Buffer;
FT_LOCAL( CF2_Int )
cf2_buf_readByte( CF2_Buffer buf );
FT_LOCAL( FT_Bool )
cf2_buf_isEnd( CF2_Buffer buf );
FT_END_HEADER
#endif /* PSREAD_H_ */
/* END */
@@ -0,0 +1,329 @@
/****************************************************************************
*
* psstack.c
*
* Adobe's code for emulating a CFF stack (body).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#include "psft.h"
#include <freetype/internal/ftdebug.h>
#include "psglue.h"
#include "psfont.h"
#include "psstack.h"
#include "pserror.h"
/* Allocate and initialize an instance of CF2_Stack. */
/* Note: This function returns NULL on error (does not set */
/* `error'). */
FT_LOCAL_DEF( CF2_Stack )
cf2_stack_init( FT_Memory memory,
FT_Error* e,
FT_UInt stackSize )
{
FT_Error error; /* for FT_QNEW */
CF2_Stack stack = NULL;
if ( FT_QNEW( stack ) )
return NULL;
stack->memory = memory;
stack->error = e;
/* allocate the stack buffer */
if ( FT_QNEW_ARRAY( stack->buffer, stackSize ) )
{
FT_FREE( stack );
return NULL;
}
stack->stackSize = stackSize;
stack->top = stack->buffer; /* empty stack */
return stack;
}
FT_LOCAL_DEF( void )
cf2_stack_free( CF2_Stack stack )
{
if ( stack )
{
FT_Memory memory = stack->memory;
/* free the buffer */
FT_FREE( stack->buffer );
/* free the main structure */
FT_FREE( stack );
}
}
FT_LOCAL_DEF( CF2_UInt )
cf2_stack_count( CF2_Stack stack )
{
return (CF2_UInt)( stack->top - stack->buffer );
}
FT_LOCAL_DEF( void )
cf2_stack_pushInt( CF2_Stack stack,
CF2_Int val )
{
if ( stack->top == stack->buffer + stack->stackSize )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return; /* stack overflow */
}
stack->top->u.i = val;
stack->top->type = CF2_NumberInt;
stack->top++;
}
FT_LOCAL_DEF( void )
cf2_stack_pushFixed( CF2_Stack stack,
CF2_Fixed val )
{
if ( stack->top == stack->buffer + stack->stackSize )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return; /* stack overflow */
}
stack->top->u.r = val;
stack->top->type = CF2_NumberFixed;
stack->top++;
}
/* this function is only allowed to pop an integer type */
FT_LOCAL_DEF( CF2_Int )
cf2_stack_popInt( CF2_Stack stack )
{
if ( stack->top == stack->buffer )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return 0; /* underflow */
}
if ( stack->top[-1].type != CF2_NumberInt )
{
CF2_SET_ERROR( stack->error, Syntax_Error );
return 0; /* type mismatch */
}
stack->top--;
return stack->top->u.i;
}
/* Note: type mismatch is silently cast */
/* TODO: check this */
FT_LOCAL_DEF( CF2_Fixed )
cf2_stack_popFixed( CF2_Stack stack )
{
if ( stack->top == stack->buffer )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return cf2_intToFixed( 0 ); /* underflow */
}
stack->top--;
switch ( stack->top->type )
{
case CF2_NumberInt:
return cf2_intToFixed( stack->top->u.i );
case CF2_NumberFrac:
return cf2_fracToFixed( stack->top->u.f );
default:
return stack->top->u.r;
}
}
/* Note: type mismatch is silently cast */
/* TODO: check this */
FT_LOCAL_DEF( CF2_Fixed )
cf2_stack_getReal( CF2_Stack stack,
CF2_UInt idx )
{
FT_ASSERT( cf2_stack_count( stack ) <= stack->stackSize );
if ( idx >= cf2_stack_count( stack ) )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return cf2_intToFixed( 0 ); /* bounds error */
}
switch ( stack->buffer[idx].type )
{
case CF2_NumberInt:
return cf2_intToFixed( stack->buffer[idx].u.i );
case CF2_NumberFrac:
return cf2_fracToFixed( stack->buffer[idx].u.f );
default:
return stack->buffer[idx].u.r;
}
}
/* provide random access to stack */
FT_LOCAL_DEF( void )
cf2_stack_setReal( CF2_Stack stack,
CF2_UInt idx,
CF2_Fixed val )
{
if ( idx > cf2_stack_count( stack ) )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return;
}
stack->buffer[idx].u.r = val;
stack->buffer[idx].type = CF2_NumberFixed;
}
/* discard (pop) num values from stack */
FT_LOCAL_DEF( void )
cf2_stack_pop( CF2_Stack stack,
CF2_UInt num )
{
if ( num > cf2_stack_count( stack ) )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return;
}
stack->top -= num;
}
FT_LOCAL_DEF( void )
cf2_stack_roll( CF2_Stack stack,
CF2_Int count,
CF2_Int shift )
{
/* we initialize this variable to avoid compiler warnings */
CF2_StackNumber last = { { 0 }, CF2_NumberInt };
CF2_Int start_idx, idx, i;
if ( count < 2 )
return; /* nothing to do (values 0 and 1), or undefined value */
if ( (CF2_UInt)count > cf2_stack_count( stack ) )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return;
}
/* before C99 it is implementation-defined whether */
/* the result of `%' is negative if the first operand */
/* is negative */
if ( shift < 0 )
shift = -( ( -shift ) % count );
else
shift %= count;
if ( shift == 0 )
return; /* nothing to do */
/* We use the following algorithm to do the rolling, */
/* which needs two temporary variables only. */
/* */
/* Example: */
/* */
/* count = 8 */
/* shift = 2 */
/* */
/* stack indices before roll: 7 6 5 4 3 2 1 0 */
/* stack indices after roll: 1 0 7 6 5 4 3 2 */
/* */
/* The value of index 0 gets moved to index 2, while */
/* the old value of index 2 gets moved to index 4, */
/* and so on. We thus have the following copying */
/* chains for shift value 2. */
/* */
/* 0 -> 2 -> 4 -> 6 -> 0 */
/* 1 -> 3 -> 5 -> 7 -> 1 */
/* */
/* If `count' and `shift' are incommensurable, we */
/* have a single chain only. Otherwise, increase */
/* the start index by 1 after the first chain, then */
/* do the next chain until all elements in all */
/* chains are handled. */
start_idx = -1;
idx = -1;
for ( i = 0; i < count; i++ )
{
CF2_StackNumber tmp;
if ( start_idx == idx )
{
start_idx++;
idx = start_idx;
last = stack->buffer[idx];
}
idx += shift;
if ( idx >= count )
idx -= count;
else if ( idx < 0 )
idx += count;
tmp = stack->buffer[idx];
stack->buffer[idx] = last;
last = tmp;
}
}
FT_LOCAL_DEF( void )
cf2_stack_clear( CF2_Stack stack )
{
stack->top = stack->buffer;
}
/* END */
@@ -0,0 +1,122 @@
/****************************************************************************
*
* psstack.h
*
* Adobe's code for emulating a CFF stack (specification).
*
* Copyright 2007-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSSTACK_H_
#define PSSTACK_H_
#include <freetype/internal/compiler-macros.h>
FT_BEGIN_HEADER
/* CFF operand stack; specified maximum of 48 or 192 values */
typedef struct CF2_StackNumber_
{
union
{
CF2_Fixed r; /* 16.16 fixed-point */
CF2_Frac f; /* 2.30 fixed-point (for font matrix) */
CF2_Int i;
} u;
CF2_NumberType type;
} CF2_StackNumber;
typedef struct CF2_StackRec_
{
FT_Memory memory;
FT_Error* error;
CF2_StackNumber* buffer;
CF2_StackNumber* top;
FT_UInt stackSize;
} CF2_StackRec, *CF2_Stack;
FT_LOCAL( CF2_Stack )
cf2_stack_init( FT_Memory memory,
FT_Error* error,
FT_UInt stackSize );
FT_LOCAL( void )
cf2_stack_free( CF2_Stack stack );
FT_LOCAL( CF2_UInt )
cf2_stack_count( CF2_Stack stack );
FT_LOCAL( void )
cf2_stack_pushInt( CF2_Stack stack,
CF2_Int val );
FT_LOCAL( void )
cf2_stack_pushFixed( CF2_Stack stack,
CF2_Fixed val );
FT_LOCAL( CF2_Int )
cf2_stack_popInt( CF2_Stack stack );
FT_LOCAL( CF2_Fixed )
cf2_stack_popFixed( CF2_Stack stack );
FT_LOCAL( CF2_Fixed )
cf2_stack_getReal( CF2_Stack stack,
CF2_UInt idx );
FT_LOCAL( void )
cf2_stack_setReal( CF2_Stack stack,
CF2_UInt idx,
CF2_Fixed val );
FT_LOCAL( void )
cf2_stack_pop( CF2_Stack stack,
CF2_UInt num );
FT_LOCAL( void )
cf2_stack_roll( CF2_Stack stack,
CF2_Int count,
CF2_Int idx );
FT_LOCAL( void )
cf2_stack_clear( CF2_Stack stack );
FT_END_HEADER
#endif /* PSSTACK_H_ */
/* END */
@@ -0,0 +1,77 @@
/****************************************************************************
*
* pstypes.h
*
* Adobe's code for defining data types (specification only).
*
* Copyright 2011-2013 Adobe Systems Incorporated.
*
* This software, and all works of authorship, whether in source or
* object code form as indicated by the copyright notice(s) included
* herein (collectively, the "Work") is made available, and may only be
* used, modified, and distributed under the FreeType Project License,
* LICENSE.TXT. Additionally, subject to the terms and conditions of the
* FreeType Project License, each contributor to the Work hereby grants
* to any individual or legal entity exercising permissions granted by
* the FreeType Project License and this section (hereafter, "You" or
* "Your") a perpetual, worldwide, non-exclusive, no-charge,
* royalty-free, irrevocable (except as stated in this section) patent
* license to make, have made, use, offer to sell, sell, import, and
* otherwise transfer the Work, where such license applies only to those
* patent claims licensable by such contributor that are necessarily
* infringed by their contribution(s) alone or by combination of their
* contribution(s) with the Work to which such contribution(s) was
* submitted. If You institute patent litigation against any entity
* (including a cross-claim or counterclaim in a lawsuit) alleging that
* the Work or a contribution incorporated within the Work constitutes
* direct or contributory patent infringement, then any patent licenses
* granted to You under this License for that Work shall terminate as of
* the date such litigation is filed.
*
* By using, modifying, or distributing the Work you indicate that you
* have read and understood the terms and conditions of the
* FreeType Project License as well as those provided in this section,
* and you accept them fully.
*
*/
#ifndef PSTYPES_H_
#define PSTYPES_H_
#include <freetype/freetype.h>
FT_BEGIN_HEADER
/*
* The data models that we expect to support are as follows:
*
* name char short int long long-long pointer example
* -----------------------------------------------------
* ILP32 8 16 32 32 64* 32 32-bit MacOS, x86
* LLP64 8 16 32 32 64 64 x64
* LP64 8 16 32 64 64 64 64-bit MacOS
*
* *) type may be supported by emulation on a 32-bit architecture
*
*/
/* integers at least 32 bits wide */
#define CF2_UInt FT_UFast
#define CF2_Int FT_Fast
/* fixed-float numbers */
typedef FT_Int32 CF2_F16Dot16;
FT_END_HEADER
#endif /* PSTYPES_H_ */
/* END */
@@ -0,0 +1,89 @@
#
# FreeType 2 PSaux driver configuration rules
#
# Copyright (C) 1996-2024 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# PSAUX driver directory
#
PSAUX_DIR := $(SRC_DIR)/psaux
# compilation flags for the driver
#
PSAUX_COMPILE := $(CC) $(ANSIFLAGS) \
$I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) \
$(INCLUDE_FLAGS) \
$(FT_CFLAGS)
# PSAUX driver sources (i.e., C files)
#
PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \
$(PSAUX_DIR)/t1decode.c \
$(PSAUX_DIR)/t1cmap.c \
$(PSAUX_DIR)/afmparse.c \
$(PSAUX_DIR)/psconv.c \
$(PSAUX_DIR)/psauxmod.c \
$(PSAUX_DIR)/psarrst.c \
$(PSAUX_DIR)/psblues.c \
$(PSAUX_DIR)/pserror.c \
$(PSAUX_DIR)/psfont.c \
$(PSAUX_DIR)/psft.c \
$(PSAUX_DIR)/pshints.c \
$(PSAUX_DIR)/psintrp.c \
$(PSAUX_DIR)/psread.c \
$(PSAUX_DIR)/psstack.c \
$(PSAUX_DIR)/cffdecode.c
# PSAUX driver headers
#
PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \
$(PSAUX_DIR)/psauxerr.h \
$(PSAUX_DIR)/psfixed.h \
$(PSAUX_DIR)/psglue.h \
$(PSAUX_DIR)/pstypes.h
# PSAUX driver object(s)
#
# PSAUX_DRV_OBJ_M is used during `multi' builds.
# PSAUX_DRV_OBJ_S is used during `single' builds.
#
PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR)/%.c=$(OBJ_DIR)/%.$O)
PSAUX_DRV_OBJ_S := $(OBJ_DIR)/psaux.$O
# PSAUX driver source file for single build
#
PSAUX_DRV_SRC_S := $(PSAUX_DIR)/psaux.c
# PSAUX driver - single object
#
$(PSAUX_DRV_OBJ_S): $(PSAUX_DRV_SRC_S) $(PSAUX_DRV_SRC) \
$(FREETYPE_H) $(PSAUX_DRV_H)
$(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSAUX_DRV_SRC_S))
# PSAUX driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(PSAUX_DIR)/%.c $(FREETYPE_H) $(PSAUX_DRV_H)
$(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(PSAUX_DRV_OBJ_S)
DRV_OBJS_M += $(PSAUX_DRV_OBJ_M)
# EOF
+393
View File
@@ -0,0 +1,393 @@
/****************************************************************************
*
* t1cmap.c
*
* Type 1 character map support (body).
*
* Copyright (C) 2002-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include "t1cmap.h"
#include <freetype/internal/ftdebug.h>
#include "psauxerr.h"
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static void
t1_cmap_std_init( T1_CMapStd cmap,
FT_Int is_expert )
{
T1_Face face = (T1_Face)FT_CMAP_FACE( cmap );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
cmap->num_glyphs = (FT_UInt)face->type1.num_glyphs;
cmap->glyph_names = (const char* const*)face->type1.glyph_names;
cmap->sid_to_string = psnames->adobe_std_strings;
cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding
: psnames->adobe_std_encoding;
FT_ASSERT( cmap->code_to_sid );
}
FT_CALLBACK_DEF( void )
t1_cmap_std_done( FT_CMap cmap_ ) /* T1_CMapStd */
{
T1_CMapStd cmap = (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( FT_CMap cmap, /* T1_CMapStd */
FT_UInt32 char_code )
{
T1_CMapStd t1cmap = (T1_CMapStd)cmap;
FT_UInt result = 0;
if ( char_code < 256 )
{
FT_UInt code, n;
const char* glyph_name;
/* convert character code to Adobe SID string */
code = t1cmap->code_to_sid[char_code];
glyph_name = t1cmap->sid_to_string( code );
/* look for the corresponding glyph name */
for ( n = 0; n < t1cmap->num_glyphs; n++ )
{
const char* gname = t1cmap->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_UInt )
t1_cmap_std_char_next( FT_CMap 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( FT_CMap cmap, /* T1_CMapStd */
FT_Pointer pointer )
{
T1_CMapStd t1cmap = (T1_CMapStd)cmap;
FT_UNUSED( pointer );
t1_cmap_std_init( t1cmap, 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, /* init */
(FT_CMap_DoneFunc) t1_cmap_std_done, /* done */
(FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */
(FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
};
FT_CALLBACK_DEF( FT_Error )
t1_cmap_expert_init( FT_CMap cmap, /* T1_CMapStd */
FT_Pointer pointer )
{
T1_CMapStd t1cmap = (T1_CMapStd)cmap;
FT_UNUSED( pointer );
t1_cmap_std_init( t1cmap, 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, /* init */
(FT_CMap_DoneFunc) t1_cmap_std_done, /* done */
(FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */
(FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
};
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 CUSTOM ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
t1_cmap_custom_init( FT_CMap cmap, /* T1_CMapCustom */
FT_Pointer pointer )
{
T1_CMapCustom t1cmap = (T1_CMapCustom)cmap;
T1_Face face = (T1_Face)FT_CMAP_FACE( cmap );
T1_Encoding encoding = &face->type1.encoding;
FT_UNUSED( pointer );
t1cmap->first = (FT_UInt)encoding->code_first;
t1cmap->count = (FT_UInt)encoding->code_last - t1cmap->first;
t1cmap->indices = encoding->char_index;
FT_ASSERT( t1cmap->indices );
FT_ASSERT( encoding->code_first <= encoding->code_last );
return 0;
}
FT_CALLBACK_DEF( void )
t1_cmap_custom_done( FT_CMap cmap ) /* T1_CMapCustom */
{
T1_CMapCustom t1cmap = (T1_CMapCustom)cmap;
t1cmap->indices = NULL;
t1cmap->first = 0;
t1cmap->count = 0;
}
FT_CALLBACK_DEF( FT_UInt )
t1_cmap_custom_char_index( FT_CMap cmap, /* T1_CMapCustom */
FT_UInt32 char_code )
{
T1_CMapCustom t1cmap = (T1_CMapCustom)cmap;
FT_UInt result = 0;
if ( char_code >= t1cmap->first &&
char_code < ( t1cmap->first + t1cmap->count ) )
result = t1cmap->indices[char_code];
return result;
}
FT_CALLBACK_DEF( FT_UInt )
t1_cmap_custom_char_next( FT_CMap cmap, /* T1_CMapCustom */
FT_UInt32 *pchar_code )
{
T1_CMapCustom t1cmap = (T1_CMapCustom)cmap;
FT_UInt result = 0;
FT_UInt32 char_code = *pchar_code;
char_code++;
if ( char_code < t1cmap->first )
char_code = t1cmap->first;
for ( ; char_code < ( t1cmap->first + t1cmap->count ); char_code++ )
{
result = t1cmap->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, /* init */
(FT_CMap_DoneFunc) t1_cmap_custom_done, /* done */
(FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, /* char_index */
(FT_CMap_CharNextFunc) t1_cmap_custom_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
};
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( const char * )
psaux_get_glyph_name( void* face_,
FT_UInt idx )
{
T1_Face face = (T1_Face)face_;
return face->type1.glyph_names[idx];
}
FT_CALLBACK_DEF( FT_Error )
t1_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */
FT_Pointer pointer )
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
T1_Face face = (T1_Face)FT_CMAP_FACE( cmap );
FT_Memory memory = FT_FACE_MEMORY( face );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
FT_UNUSED( pointer );
if ( !psnames->unicodes_init )
return FT_THROW( Unimplemented_Feature );
return psnames->unicodes_init( memory,
unicodes,
(FT_UInt)face->type1.num_glyphs,
&psaux_get_glyph_name,
(PS_FreeGlyphNameFunc)NULL,
(FT_Pointer)face );
}
FT_CALLBACK_DEF( void )
t1_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
FT_Face face = FT_CMAP_FACE( cmap );
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( FT_CMap cmap, /* PS_Unicodes */
FT_UInt32 char_code )
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
T1_Face face = (T1_Face)FT_CMAP_FACE( cmap );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_index( unicodes, char_code );
}
FT_CALLBACK_DEF( FT_UInt )
t1_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */
FT_UInt32 *pchar_code )
{
PS_Unicodes unicodes = (PS_Unicodes)cmap;
T1_Face face = (T1_Face)FT_CMAP_FACE( cmap );
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, /* init */
(FT_CMap_DoneFunc) t1_cmap_unicode_done, /* done */
(FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, /* char_index */
(FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL /* variantchar_list */
};
/* END */
+104
View File
@@ -0,0 +1,104 @@
/****************************************************************************
*
* t1cmap.h
*
* Type 1 character map support (specification).
*
* Copyright (C) 2002-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef T1CMAP_H_
#define T1CMAP_H_
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/t1types.h>
FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* standard (and expert) encoding cmaps */
typedef struct T1_CMapStdRec_* T1_CMapStd;
typedef struct T1_CMapStdRec_
{
FT_CMapRec cmap;
const FT_UShort* code_to_sid;
PS_Adobe_Std_StringsFunc sid_to_string;
FT_UInt num_glyphs;
const char* const* glyph_names;
} T1_CMapStdRec;
FT_CALLBACK_TABLE const FT_CMap_ClassRec
t1_cmap_standard_class_rec;
FT_CALLBACK_TABLE const FT_CMap_ClassRec
t1_cmap_expert_class_rec;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 CUSTOM ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct T1_CMapCustomRec_* T1_CMapCustom;
typedef struct T1_CMapCustomRec_
{
FT_CMapRec cmap;
FT_UInt first;
FT_UInt count;
FT_UShort* indices;
} T1_CMapCustomRec;
FT_CALLBACK_TABLE const FT_CMap_ClassRec
t1_cmap_custom_class_rec;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* unicode (synthetic) cmaps */
FT_CALLBACK_TABLE const FT_CMap_ClassRec
t1_cmap_unicode_class_rec;
/* */
FT_END_HEADER
#endif /* T1CMAP_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,73 @@
/****************************************************************************
*
* t1decode.h
*
* PostScript Type 1 decoding routines (specification).
*
* Copyright (C) 2000-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef T1DECODE_H_
#define T1DECODE_H_
#include <freetype/internal/psaux.h>
#include <freetype/internal/t1types.h>
FT_BEGIN_HEADER
FT_CALLBACK_TABLE
const T1_Decoder_FuncsRec t1_decoder_funcs;
FT_LOCAL( FT_Int )
t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder,
FT_Int charcode );
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
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 );
#else
FT_LOCAL( FT_Error )
t1_decoder_parse_metrics( T1_Decoder decoder,
FT_Byte* charstring_base,
FT_UInt charstring_len );
#endif
FT_LOCAL( FT_Error )
t1_decoder_init( T1_Decoder decoder,
FT_Face face,
FT_Size size,
FT_GlyphSlot slot,
FT_Byte** glyph_names,
PS_Blend blend,
FT_Bool hinting,
FT_Render_Mode hint_mode,
T1_Decoder_Callback parse_glyph );
FT_LOCAL( void )
t1_decoder_done( T1_Decoder decoder );
FT_END_HEADER
#endif /* T1DECODE_H_ */
/* END */
@@ -0,0 +1,23 @@
#
# FreeType 2 PSHinter module definition
#
# Copyright (C) 1996-2024 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
FTMODULE_H_COMMANDS += PSHINTER_MODULE
define PSHINTER_MODULE
$(OPEN_DRIVER) FT_Module_Class, pshinter_module_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE)
endef
# EOF
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,233 @@
/****************************************************************************
*
* pshalgo.h
*
* PostScript hinting algorithm (specification).
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef PSHALGO_H_
#define PSHALGO_H_
#include "pshrec.h"
#include "pshglob.h"
FT_BEGIN_HEADER
/* handle to Hint structure */
typedef struct PSH_HintRec_* PSH_Hint;
/* hint bit-flags */
#define PSH_HINT_GHOST PS_HINT_FLAG_GHOST
#define PSH_HINT_BOTTOM PS_HINT_FLAG_BOTTOM
#define PSH_HINT_ACTIVE 4U
#define PSH_HINT_FITTED 8U
#define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 )
#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;
typedef enum PSH_Dir_
{
PSH_DIR_NONE = 0,
PSH_DIR_UP = 1,
PSH_DIR_DOWN = 2,
PSH_DIR_VERTICAL = 1 | 2,
PSH_DIR_LEFT = 4,
PSH_DIR_RIGHT = 8,
PSH_DIR_HORIZONTAL = 4 | 8
} PSH_Dir;
/* the following bit-flags are computed once by the glyph */
/* analyzer, for both dimensions */
#define PSH_POINT_OFF 1U /* point is off the curve */
#define PSH_POINT_SMOOTH 2U /* point is smooth */
#define PSH_POINT_INFLEX 4U /* point is inflection */
#define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH )
#define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF )
#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 */
#define PSH_POINT_STRONG 16U /* point is strong */
#define PSH_POINT_FITTED 32U /* point is already fitted */
#define PSH_POINT_EXTREMUM 64U /* point is local extremum */
#define PSH_POINT_POSITIVE 128U /* extremum has positive contour flow */
#define PSH_POINT_NEGATIVE 256U /* extremum has negative contour flow */
#define PSH_POINT_EDGE_MIN 512U /* point is aligned to left/bottom stem edge */
#define PSH_POINT_EDGE_MAX 1024U /* point is aligned to top/right stem edge */
#define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG )
#define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED )
#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;
PSH_Dir dir_in;
PSH_Dir dir_out;
PSH_Hint hint;
FT_Pos org_u;
FT_Pos org_v;
FT_Pos cur_u;
#ifdef DEBUG_HINTER
FT_Pos org_x;
FT_Pos cur_x;
FT_Pos org_y;
FT_Pos cur_y;
FT_UInt flags_x;
FT_UInt flags_y;
#endif
} PSH_PointRec;
typedef struct PSH_ContourRec_
{
PSH_Point start;
FT_UInt count;
} PSH_ContourRec;
typedef struct PSH_GlyphRec_
{
FT_UInt num_points;
FT_UInt num_contours;
PSH_Point points;
PSH_Contour contours;
FT_Memory memory;
FT_Outline* outline;
PSH_Globals globals;
PSH_Hint_TableRec hint_tables[2];
FT_Bool do_horz_hints;
FT_Bool do_vert_hints;
FT_Bool do_horz_snapping;
FT_Bool do_vert_snapping;
FT_Bool do_stem_adjust;
} PSH_GlyphRec, *PSH_Glyph;
#ifdef DEBUG_HINTER
extern PSH_Hint_Table ps_debug_hint_table;
typedef void
(*PSH_HintFunc)( PSH_Hint hint,
FT_Bool vertical );
extern PSH_HintFunc ps_debug_hint_func;
extern PSH_Glyph ps_debug_glyph;
#endif
extern FT_Error
ps_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
PSH_Globals globals,
FT_Render_Mode hint_mode );
FT_END_HEADER
#endif /* PSHALGO_H_ */
/* END */
@@ -0,0 +1,795 @@
/****************************************************************************
*
* pshglob.c
*
* PostScript hinter global hinting management (body).
* Inspired by the new auto-hinter module.
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include <freetype/freetype.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftcalc.h>
#include "pshglob.h"
#ifdef DEBUG_HINTER
PSH_Globals ps_debug_globals = NULL;
#endif
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** STANDARD WIDTHS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* scale the widths/heights table */
static void
psh_globals_scale_widths( PSH_Globals globals,
FT_UInt direction )
{
PSH_Dimension dim = &globals->dimension[direction];
PSH_Widths stdw = &dim->stdw;
FT_UInt count = stdw->count;
PSH_Width width = stdw->widths;
PSH_Width stand = width; /* standard width/height */
FT_Fixed scale = dim->scale_mult;
if ( count > 0 )
{
width->cur = FT_MulFix( width->org, scale );
width->fit = FT_PIX_ROUND( width->cur );
width++;
count--;
for ( ; count > 0; count--, width++ )
{
FT_Pos w, dist;
w = FT_MulFix( width->org, scale );
dist = w - stand->cur;
if ( dist < 0 )
dist = -dist;
if ( dist < 128 )
w = stand->cur;
width->cur = w;
width->fit = FT_PIX_ROUND( w );
}
}
}
#if 0
/* org_width is in font units, result in device pixels, 26.6 format */
FT_LOCAL_DEF( FT_Pos )
psh_dimension_snap_width( PSH_Dimension dimension,
FT_Int org_width )
{
FT_UInt n;
FT_Pos width = FT_MulFix( org_width, dimension->scale_mult );
FT_Pos best = 64 + 32 + 2;
FT_Pos reference = width;
for ( n = 0; n < dimension->stdw.count; n++ )
{
FT_Pos w;
FT_Pos dist;
w = dimension->stdw.widths[n].cur;
dist = width - w;
if ( dist < 0 )
dist = -dist;
if ( dist < best )
{
best = dist;
reference = w;
}
}
if ( width >= reference )
{
width -= 0x21;
if ( width < reference )
width = reference;
}
else
{
width += 0x21;
if ( width > reference )
width = reference;
}
return width;
}
#endif /* 0 */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** BLUE ZONES *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static void
psh_blues_set_zones_0( PSH_Blues target,
FT_Bool is_others,
FT_UInt read_count,
FT_Short* read,
PSH_Blue_Table top_table,
PSH_Blue_Table bot_table )
{
FT_UInt count_top = top_table->count;
FT_UInt count_bot = bot_table->count;
FT_Bool first = 1;
FT_UNUSED( target );
for ( ; read_count > 1; read_count -= 2 )
{
FT_Int reference, delta;
FT_UInt count;
PSH_Blue_Zone zones, zone;
FT_Bool top;
/* read blue zone entry, and select target top/bottom zone */
top = 0;
if ( first || is_others )
{
reference = read[1];
delta = read[0] - reference;
zones = bot_table->zones;
count = count_bot;
first = 0;
}
else
{
reference = read[0];
delta = read[1] - reference;
zones = top_table->zones;
count = count_top;
top = 1;
}
/* insert into sorted table */
zone = zones;
for ( ; count > 0; count--, zone++ )
{
if ( reference < zone->org_ref )
break;
if ( reference == zone->org_ref )
{
FT_Int delta0 = zone->org_delta;
/* we have two zones on the same reference position -- */
/* only keep the largest one */
if ( delta < 0 )
{
if ( delta < delta0 )
zone->org_delta = delta;
}
else
{
if ( delta > delta0 )
zone->org_delta = delta;
}
goto Skip;
}
}
for ( ; count > 0; count-- )
zone[count] = zone[count-1];
zone->org_ref = reference;
zone->org_delta = delta;
if ( top )
count_top++;
else
count_bot++;
Skip:
read += 2;
}
top_table->count = count_top;
bot_table->count = count_bot;
}
/* Re-read blue zones from the original fonts and store them into our */
/* 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_UInt 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 = NULL;
/* */
/* 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 = SUB_LONG( 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 = SUB_LONG( 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 = NULL;
#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_QNEW( 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( void )
psh_globals_set_scale( PSH_Globals globals,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Fixed x_delta,
FT_Fixed y_delta )
{
PSH_Dimension dim;
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 );
}
}
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 */
@@ -0,0 +1,196 @@
/****************************************************************************
*
* pshglob.h
*
* PostScript hinter global hinting management.
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef PSHGLOB_H_
#define PSHGLOB_H_
#include <freetype/freetype.h>
#include <freetype/internal/pshints.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( void )
psh_globals_set_scale( PSH_Globals globals,
FT_Fixed x_scale,
FT_Fixed y_scale,
FT_Fixed x_delta,
FT_Fixed y_delta );
/* snap a stem to one or two blue zones */
FT_LOCAL( void )
psh_blues_snap_stem( PSH_Blues blues,
FT_Int stem_top,
FT_Int stem_bot,
PSH_Alignment alignment );
/* */
#ifdef DEBUG_HINTER
extern PSH_Globals ps_debug_globals;
#endif
FT_END_HEADER
#endif /* PSHGLOB_H_ */
/* END */
@@ -0,0 +1,27 @@
/****************************************************************************
*
* pshinter.c
*
* FreeType PostScript Hinting module
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "pshalgo.c"
#include "pshglob.c"
#include "pshmod.c"
#include "pshrec.c"
/* END */
@@ -0,0 +1,125 @@
/****************************************************************************
*
* pshmod.c
*
* FreeType PostScript hinter module implementation (body).
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#include <freetype/internal/ftobjs.h>
#include "pshrec.h"
#include "pshalgo.h"
#include "pshmod.h"
/* the Postscript Hinter module structure */
typedef struct PS_Hinter_Module_Rec_
{
FT_ModuleRec root;
PS_HintsRec ps_hints;
PSH_Globals_FuncsRec globals_funcs;
T1_Hints_FuncsRec t1_funcs;
T2_Hints_FuncsRec t2_funcs;
} PS_Hinter_ModuleRec, *PS_Hinter_Module;
/* finalize module */
FT_CALLBACK_DEF( void )
ps_hinter_done( FT_Module module_ ) /* PS_Hinter_Module */
{
PS_Hinter_Module module = (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( FT_Module module_ ) /* PS_Hinter_Module */
{
PS_Hinter_Module module = (PS_Hinter_Module)module_;
FT_Memory memory = module->root.memory;
void* ph = &module->ps_hints;
ps_hints_init( &module->ps_hints, memory );
psh_globals_funcs_init( &module->globals_funcs );
t1_hints_funcs_init( &module->t1_funcs );
module->t1_funcs.hints = (T1_Hints)ph;
t2_hints_funcs_init( &module->t2_funcs );
module->t2_funcs.hints = (T2_Hints)ph;
return 0;
}
/* returns global hints interface */
FT_CALLBACK_DEF( PSH_Globals_Funcs )
pshinter_get_globals_funcs( FT_Module module )
{
return &((PS_Hinter_Module)module)->globals_funcs;
}
/* return Type 1 hints interface */
FT_CALLBACK_DEF( T1_Hints_Funcs )
pshinter_get_t1_funcs( FT_Module module )
{
return &((PS_Hinter_Module)module)->t1_funcs;
}
/* return Type 2 hints interface */
FT_CALLBACK_DEF( T2_Hints_Funcs )
pshinter_get_t2_funcs( FT_Module module )
{
return &((PS_Hinter_Module)module)->t2_funcs;
}
FT_DEFINE_PSHINTER_INTERFACE(
pshinter_interface,
pshinter_get_globals_funcs,
pshinter_get_t1_funcs,
pshinter_get_t2_funcs
)
FT_DEFINE_MODULE(
pshinter_module_class,
0,
sizeof ( PS_Hinter_ModuleRec ),
"pshinter",
0x10000L,
0x20000L,
&pshinter_interface, /* module-specific interface */
(FT_Module_Constructor)ps_hinter_init, /* module_init */
(FT_Module_Destructor) ps_hinter_done, /* module_done */
(FT_Module_Requester) NULL /* get_interface */
)
/* END */
@@ -0,0 +1,38 @@
/****************************************************************************
*
* pshmod.h
*
* PostScript hinter module interface (specification).
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef PSHMOD_H_
#define PSHMOD_H_
#include <freetype/ftmodapi.h>
FT_BEGIN_HEADER
FT_DECLARE_MODULE( pshinter_module_class )
FT_END_HEADER
#endif /* PSHMOD_H_ */
/* END */
@@ -0,0 +1,41 @@
/****************************************************************************
*
* pshnterr.h
*
* PS Hinter error codes (specification only).
*
* Copyright (C) 2003-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file is used to define the PSHinter error enumeration constants.
*
*/
#ifndef PSHNTERR_H_
#define PSHNTERR_H_
#include <freetype/ftmoderr.h>
#undef FTERRORS_H_
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX PSH_Err_
#define FT_ERR_BASE FT_Mod_Err_PShinter
#include <freetype/fterrors.h>
#endif /* PSHNTERR_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,171 @@
/****************************************************************************
*
* pshrec.h
*
* Postscript (Type1/Type2) hints recorder (specification).
*
* Copyright (C) 2001-2024 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/***************************************************************************
*
* The functions defined here are called from the Type 1, CID and CFF
* font drivers to record the hints of a given character/glyph.
*
* The hints are recorded in a unified format, and are later processed
* by the `optimizer' and `fitter' to adjust the outlines to the pixel
* grid.
*
*/
#ifndef PSHREC_H_
#define PSHREC_H_
#include <freetype/internal/pshints.h>
#include "pshglob.h"
FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GLYPH HINTS RECORDER INTERNALS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* handle to hint record */
typedef struct PS_HintRec_* PS_Hint;
/* hint types */
typedef enum PS_Hint_Type_
{
PS_HINT_TYPE_1 = 1,
PS_HINT_TYPE_2 = 2
} PS_Hint_Type;
/* hint flags */
#define PS_HINT_FLAG_GHOST 1U
#define PS_HINT_FLAG_BOTTOM 2U
/* 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( void )
ps_hints_init( PS_Hints hints,
FT_Memory memory );
/* finalize hints recorder */
FT_LOCAL( void )
ps_hints_done( PS_Hints hints );
/* initialize Type1 hints recorder interface */
FT_LOCAL( void )
t1_hints_funcs_init( T1_Hints_FuncsRec* funcs );
/* initialize Type2 hints recorder interface */
FT_LOCAL( void )
t2_hints_funcs_init( T2_Hints_FuncsRec* funcs );
#ifdef DEBUG_HINTER
extern PS_Hints ps_debug_hints;
extern int ps_debug_no_horz_hints;
extern int ps_debug_no_vert_hints;
#endif
/* */
FT_END_HEADER
#endif /* PSHREC_H_ */
/* END */
@@ -0,0 +1,75 @@
#
# FreeType 2 PSHinter driver configuration rules
#
# Copyright (C) 2001-2024 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# PSHINTER driver directory
#
PSHINTER_DIR := $(SRC_DIR)/pshinter
# compilation flags for the driver
#
PSHINTER_COMPILE := $(CC) $(ANSIFLAGS) \
$I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) \
$(INCLUDE_FLAGS) \
$(FT_CFLAGS)
# PSHINTER driver sources (i.e., C files)
#
PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshalgo.c \
$(PSHINTER_DIR)/pshglob.c \
$(PSHINTER_DIR)/pshmod.c \
$(PSHINTER_DIR)/pshrec.c
# PSHINTER driver headers
#
PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) \
$(PSHINTER_DIR)/pshnterr.h
# PSHINTER driver object(s)
#
# PSHINTER_DRV_OBJ_M is used during `multi' builds.
# PSHINTER_DRV_OBJ_S is used during `single' builds.
#
PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR)/%.c=$(OBJ_DIR)/%.$O)
PSHINTER_DRV_OBJ_S := $(OBJ_DIR)/pshinter.$O
# PSHINTER driver source file for single build
#
PSHINTER_DRV_SRC_S := $(PSHINTER_DIR)/pshinter.c
# PSHINTER driver - single object
#
$(PSHINTER_DRV_OBJ_S): $(PSHINTER_DRV_SRC_S) $(PSHINTER_DRV_SRC) \
$(FREETYPE_H) $(PSHINTER_DRV_H)
$(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSHINTER_DRV_SRC_S))
# PSHINTER driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(PSHINTER_DIR)/%.c $(FREETYPE_H) $(PSHINTER_DRV_H)
$(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(PSHINTER_DRV_OBJ_S)
DRV_OBJS_M += $(PSHINTER_DRV_OBJ_M)
# EOF
+4 -2
View File
@@ -3307,9 +3307,11 @@ int run_live_client(
{ {
// HiDPI text: rasterise glyph pages at the swapchain's pixels per UI pixel (before any font // HiDPI text: rasterise glyph pages at the swapchain's pixels per UI pixel (before any font
// exists). MT_FONT_OVERSAMPLE=1 keeps the 40250 bilevel 1x glyphs. // exists). Rounded up: a fractional density (Android 1760x800 UI on 2376x1080 = 1.35) then
// scales finer glyphs down instead of stretching 1x ones. MT_FONT_OVERSAMPLE=1 keeps the
// 40250 bilevel 1x glyphs.
const float density = float(renderer.width()) / float(std::max(1u, renderer.logical_width())); const float density = float(renderer.width()) / float(std::max(1u, renderer.logical_width()));
int oversample = std::clamp(int(std::lround(density)), 1, 4); int oversample = std::clamp(int(std::ceil(density - 0.05f)), 1, 4);
if (const char* env = std::getenv("MT_FONT_OVERSAMPLE")) oversample = std::max(1, std::atoi(env)); if (const char* env = std::getenv("MT_FONT_OVERSAMPLE")) oversample = std::max(1, std::atoi(env));
UISetFontOversample(oversample); UISetFontOversample(oversample);
} }