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:
co-authored by
Claude Opus 5.5
parent
3c52ced02e
commit
53d06c3c26
@@ -15,9 +15,13 @@ import org.libsdl.app.SDLActivity;
|
||||
* 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 \
|
||||
* --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 {
|
||||
private static final String DEFAULT_ARGS = "--live-server 192.168.21.203:11000:13000 --login-screen";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -70,7 +74,7 @@ public class MainActivity extends SDLActivity {
|
||||
String args = intent != null ? intent.getStringExtra("args") : null;
|
||||
Log.i("Metin2Args", "native args: " + args);
|
||||
if (args == null || args.trim().isEmpty())
|
||||
return new String[0];
|
||||
args = DEFAULT_ARGS;
|
||||
return args.trim().split("\\s+");
|
||||
}
|
||||
|
||||
|
||||
@@ -45,18 +45,23 @@ if [ ! -f "$SDL_SRC/CMakeLists.txt" ]; then
|
||||
echo "$SDL_SHA256 $tarball" | shasum -a 256 -c -
|
||||
tar xzf "$tarball" -C "$OUT/_deps"
|
||||
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" \
|
||||
-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 \
|
||||
-DSDL_TESTS=OFF -DSDL_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX="$OUT/sdl3"
|
||||
cmake --build "$OUT/sdl3-build" -j "$JOBS"
|
||||
cmake --install "$OUT/sdl3-build"
|
||||
touch "$OUT/sdl3/.page16k"
|
||||
fi
|
||||
|
||||
# --- libmain.so (native_render + port_platform + embedded Python) and its assets ---
|
||||
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 \
|
||||
-DMT_BUILD_NATIVE_RENDER=ON -DSDL3_DIR="$OUT/sdl3/lib/cmake/SDL3" \
|
||||
-DCMAKE_FIND_ROOT_PATH="$OUT/sdl3" -DGLSLC="$GLSLC" >/dev/null
|
||||
|
||||
+6
-2
@@ -1,8 +1,9 @@
|
||||
# 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
|
||||
# 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.
|
||||
set(dir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
add_library(freetype STATIC
|
||||
@@ -17,6 +18,9 @@ add_library(freetype STATIC
|
||||
${dir}/src/base/ftmm.c
|
||||
${dir}/src/sfnt/sfnt.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/raster/raster.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):
|
||||
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, sfnt_module_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_smooth_renderer_class )
|
||||
/* EOF */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
+2570
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
+1175
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -3307,9 +3307,11 @@ int run_live_client(
|
||||
|
||||
{
|
||||
// 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()));
|
||||
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));
|
||||
UISetFontOversample(oversample);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user