parent
4769e58bbd
commit
3926f77efd
18 changed files with 19742 additions and 0 deletions
@ -0,0 +1,23 @@ |
||||
#
|
||||
# FreeType 2 TrueType module definition
|
||||
#
|
||||
|
||||
|
||||
# Copyright (C) 1996-2023 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.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 += PRELOAD_DRIVER
|
||||
|
||||
define PRELOAD_DRIVER |
||||
$(OPEN_DRIVER) FT_Driver_ClassRec, preload_driver_class $(CLOSE_DRIVER) |
||||
$(ECHO_DRIVER)preload $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) |
||||
endef |
||||
|
||||
# EOF
|
@ -0,0 +1,29 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* truetype.c |
||||
* |
||||
* FreeType TrueType driver component (body only). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. 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 "ttdriver.c" /* driver interface */ |
||||
#include "ttgload.c" /* glyph loader */ |
||||
#include "ttgxvar.c" /* gx distortable font */ |
||||
#include "ttinterp.c" |
||||
#include "ttobjs.c" /* object manager */ |
||||
#include "ttpload.c" /* tables loader */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,75 @@ |
||||
#
|
||||
# FreeType 2 TrueType driver configuration rules
|
||||
#
|
||||
|
||||
|
||||
# Copyright (C) 1996-2023 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
|
||||
# TrueType driver directory
|
||||
#
|
||||
TT_DIR := $(SRC_DIR)/preload
|
||||
|
||||
|
||||
# compilation flags for the driver
|
||||
#
|
||||
TT_COMPILE := $(CC) $(ANSIFLAGS) \
|
||||
$I$(subst /,$(COMPILER_SEP),$(TT_DIR)) \
|
||||
$(INCLUDE_FLAGS) \
|
||||
$(FT_CFLAGS)
|
||||
|
||||
|
||||
# TrueType driver sources (i.e., C files)
|
||||
#
|
||||
TT_DRV_SRC := $(TT_DIR)/ttdriver.c \
|
||||
$(TT_DIR)/ttgload.c \
|
||||
$(TT_DIR)/ttgxvar.c \
|
||||
$(TT_DIR)/ttinterp.c \
|
||||
$(TT_DIR)/ttobjs.c \
|
||||
$(TT_DIR)/ttpload.c
|
||||
|
||||
# TrueType driver headers
|
||||
#
|
||||
TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \
|
||||
$(TT_DIR)/tterrors.h
|
||||
|
||||
|
||||
# TrueType driver object(s)
|
||||
#
|
||||
# TT_DRV_OBJ_M is used during `multi' builds
|
||||
# TT_DRV_OBJ_S is used during `single' builds
|
||||
#
|
||||
TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR)/%.c=$(OBJ_DIR)/%.$O)
|
||||
TT_DRV_OBJ_S := $(OBJ_DIR)/preload.$O
|
||||
|
||||
# TrueType driver source file for single build
|
||||
#
|
||||
TT_DRV_SRC_S := $(TT_DIR)/preload.c
|
||||
|
||||
|
||||
# TrueType driver - single object
|
||||
#
|
||||
$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) |
||||
$(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(TT_DRV_SRC_S))
|
||||
|
||||
|
||||
# driver - multiple objects
|
||||
#
|
||||
$(OBJ_DIR)/%.$O: $(TT_DIR)/%.c $(FREETYPE_H) $(TT_DRV_H) |
||||
$(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
|
||||
|
||||
|
||||
# update main driver object lists
|
||||
#
|
||||
DRV_OBJS_S += $(TT_DRV_OBJ_S)
|
||||
DRV_OBJS_M += $(TT_DRV_OBJ_M)
|
||||
|
||||
|
||||
# EOF
|
@ -0,0 +1,691 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttdriver.c |
||||
* |
||||
* TrueType font driver implementation (body). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.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/services/svfntfmt.h> |
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
#include <freetype/ftmm.h> |
||||
#include <freetype/internal/services/svmm.h> |
||||
#include <freetype/internal/services/svmetric.h> |
||||
#endif |
||||
|
||||
#include <freetype/internal/services/svtteng.h> |
||||
#include <freetype/internal/services/svttglyf.h> |
||||
#include <freetype/internal/services/svprop.h> |
||||
#include <freetype/ftdriver.h> |
||||
|
||||
#include "ttdriver.h" |
||||
#include "ttgload.h" |
||||
#include "ttpload.h" |
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
#include "ttgxvar.h" |
||||
#endif |
||||
|
||||
#include "tterrors.h" |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit |
||||
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
||||
* messages during execution. |
||||
*/ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT ttdriver |
||||
|
||||
|
||||
/*
|
||||
* PROPERTY SERVICE |
||||
* |
||||
*/ |
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_property_set( FT_Module module, /* TT_Driver */ |
||||
const char* property_name, |
||||
const void* value, |
||||
FT_Bool value_is_string ) |
||||
{ |
||||
FT_Error error = FT_Err_Ok; |
||||
TT_Driver driver = (TT_Driver)module; |
||||
|
||||
#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES |
||||
FT_UNUSED( value_is_string ); |
||||
#endif |
||||
|
||||
|
||||
if ( !ft_strcmp( property_name, "interpreter-version" ) ) |
||||
{ |
||||
FT_UInt interpreter_version; |
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES |
||||
if ( value_is_string ) |
||||
{ |
||||
const char* s = (const char*)value; |
||||
|
||||
|
||||
interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); |
||||
} |
||||
else |
||||
#endif |
||||
{ |
||||
FT_UInt* iv = (FT_UInt*)value; |
||||
|
||||
|
||||
interpreter_version = *iv; |
||||
} |
||||
|
||||
switch ( interpreter_version ) |
||||
{ |
||||
case TT_INTERPRETER_VERSION_35: |
||||
driver->interpreter_version = TT_INTERPRETER_VERSION_35; |
||||
break; |
||||
|
||||
case TT_INTERPRETER_VERSION_38: |
||||
case TT_INTERPRETER_VERSION_40: |
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL |
||||
driver->interpreter_version = TT_INTERPRETER_VERSION_40; |
||||
break; |
||||
#endif |
||||
|
||||
default: |
||||
error = FT_ERR( Unimplemented_Feature ); |
||||
} |
||||
|
||||
return error; |
||||
} |
||||
|
||||
FT_TRACE2(( "tt_property_set: missing property `%s'\n", |
||||
property_name )); |
||||
return FT_THROW( Missing_Property ); |
||||
} |
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_property_get( FT_Module module, /* TT_Driver */ |
||||
const char* property_name, |
||||
void* value ) |
||||
{ |
||||
FT_Error error = FT_Err_Ok; |
||||
TT_Driver driver = (TT_Driver)module; |
||||
|
||||
FT_UInt interpreter_version = driver->interpreter_version; |
||||
|
||||
|
||||
if ( !ft_strcmp( property_name, "interpreter-version" ) ) |
||||
{ |
||||
FT_UInt* val = (FT_UInt*)value; |
||||
|
||||
|
||||
*val = interpreter_version; |
||||
|
||||
return error; |
||||
} |
||||
|
||||
FT_TRACE2(( "tt_property_get: missing property `%s'\n", |
||||
property_name )); |
||||
return FT_THROW( Missing_Property ); |
||||
} |
||||
|
||||
|
||||
FT_DEFINE_SERVICE_PROPERTIESREC( |
||||
tt_service_properties, |
||||
|
||||
tt_property_set, /* FT_Properties_SetFunc set_property */ |
||||
tt_property_get /* FT_Properties_GetFunc get_property */ |
||||
) |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/**** F A C E S ****/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_get_kerning |
||||
* |
||||
* @Description: |
||||
* A driver method used to return the kerning vector between two |
||||
* glyphs of the same face. |
||||
* |
||||
* @Input: |
||||
* face :: |
||||
* A handle to the source face object. |
||||
* |
||||
* left_glyph :: |
||||
* The index of the left glyph in the kern pair. |
||||
* |
||||
* right_glyph :: |
||||
* The index of the right glyph in the kern pair. |
||||
* |
||||
* @Output: |
||||
* kerning :: |
||||
* The kerning vector. This is in font units for |
||||
* scalable formats, and in pixels for fixed-sizes |
||||
* formats. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
* |
||||
* @Note: |
||||
* Only horizontal layouts (left-to-right & right-to-left) are |
||||
* supported by this function. Other layouts, or more sophisticated |
||||
* kernings, are out of scope of this method (the basic driver |
||||
* interface is meant to be simple). |
||||
* |
||||
* They can be implemented by format-specific interfaces. |
||||
*/ |
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_get_kerning( FT_Face face, /* TT_Face */ |
||||
FT_UInt left_glyph, |
||||
FT_UInt right_glyph, |
||||
FT_Vector* kerning ) |
||||
{ |
||||
TT_Face ttface = (TT_Face)face; |
||||
SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; |
||||
|
||||
|
||||
kerning->x = 0; |
||||
kerning->y = 0; |
||||
|
||||
if ( sfnt ) |
||||
kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph ); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_get_advances( FT_Face face, /* TT_Face */ |
||||
FT_UInt start, |
||||
FT_UInt count, |
||||
FT_Int32 flags, |
||||
FT_Fixed *advances ) |
||||
{ |
||||
FT_UInt nn; |
||||
TT_Face ttface = (TT_Face)face; |
||||
|
||||
|
||||
/* XXX: TODO: check for sbits */ |
||||
|
||||
if ( flags & FT_LOAD_VERTICAL_LAYOUT ) |
||||
{ |
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
/* no fast retrieval for blended MM fonts without VVAR table */ |
||||
if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && |
||||
!( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) |
||||
return FT_THROW( Unimplemented_Feature ); |
||||
#endif |
||||
|
||||
for ( nn = 0; nn < count; nn++ ) |
||||
{ |
||||
FT_Short tsb; |
||||
FT_UShort ah; |
||||
|
||||
|
||||
/* since we don't need `tsb', we use zero for `yMax' parameter */ |
||||
TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah ); |
||||
advances[nn] = ah; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
/* no fast retrieval for blended MM fonts without HVAR table */ |
||||
if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && |
||||
!( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) |
||||
return FT_THROW( Unimplemented_Feature ); |
||||
#endif |
||||
|
||||
for ( nn = 0; nn < count; nn++ ) |
||||
{ |
||||
FT_Short lsb; |
||||
FT_UShort aw; |
||||
|
||||
|
||||
TT_Get_HMetrics( ttface, start + nn, &lsb, &aw ); |
||||
advances[nn] = aw; |
||||
} |
||||
} |
||||
|
||||
return FT_Err_Ok; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/**** S I Z E S ****/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
||||
|
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_size_select( FT_Size size, |
||||
FT_ULong strike_index ) |
||||
{ |
||||
TT_Face ttface = (TT_Face)size->face; |
||||
TT_Size ttsize = (TT_Size)size; |
||||
FT_Error error = FT_Err_Ok; |
||||
|
||||
|
||||
ttsize->strike_index = strike_index; |
||||
|
||||
if ( FT_IS_SCALABLE( size->face ) ) |
||||
{ |
||||
/* use the scaled metrics, even when tt_size_reset fails */ |
||||
FT_Select_Metrics( size->face, strike_index ); |
||||
|
||||
tt_size_reset( ttsize ); /* ignore return value */ |
||||
} |
||||
else |
||||
{ |
||||
SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; |
||||
FT_Size_Metrics* size_metrics = &size->metrics; |
||||
|
||||
|
||||
error = sfnt->load_strike_metrics( ttface, |
||||
strike_index, |
||||
size_metrics ); |
||||
if ( error ) |
||||
ttsize->strike_index = 0xFFFFFFFFUL; |
||||
} |
||||
|
||||
return error; |
||||
} |
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_size_request( FT_Size size, |
||||
FT_Size_Request req ) |
||||
{ |
||||
TT_Size ttsize = (TT_Size)size; |
||||
FT_Error error = FT_Err_Ok; |
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
||||
|
||||
if ( FT_HAS_FIXED_SIZES( size->face ) ) |
||||
{ |
||||
TT_Face ttface = (TT_Face)size->face; |
||||
SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; |
||||
FT_ULong strike_index; |
||||
|
||||
|
||||
error = sfnt->set_sbit_strike( ttface, req, &strike_index ); |
||||
|
||||
if ( error ) |
||||
ttsize->strike_index = 0xFFFFFFFFUL; |
||||
else |
||||
return tt_size_select( size, strike_index ); |
||||
} |
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
||||
|
||||
{ |
||||
FT_Error err = FT_Request_Metrics( size->face, req ); |
||||
|
||||
|
||||
if ( err ) |
||||
{ |
||||
error = err; |
||||
goto Exit; |
||||
} |
||||
} |
||||
|
||||
if ( FT_IS_SCALABLE( size->face ) ) |
||||
{ |
||||
error = tt_size_reset( ttsize ); |
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
/* for the `MPS' bytecode instruction we need the point size */ |
||||
if ( !error ) |
||||
{ |
||||
FT_UInt resolution = |
||||
ttsize->metrics->x_ppem > ttsize->metrics->y_ppem |
||||
? req->horiResolution |
||||
: req->vertResolution; |
||||
|
||||
|
||||
/* if we don't have a resolution value, assume 72dpi */ |
||||
if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES || |
||||
!resolution ) |
||||
resolution = 72; |
||||
|
||||
ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem, |
||||
64 * 72, |
||||
resolution ); |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_glyph_load |
||||
* |
||||
* @Description: |
||||
* A driver method used to load a glyph within a given glyph slot. |
||||
* |
||||
* @Input: |
||||
* slot :: |
||||
* A handle to the target slot object where the glyph |
||||
* will be loaded. |
||||
* |
||||
* size :: |
||||
* A handle to the source face size at which the glyph |
||||
* must be scaled, loaded, etc. |
||||
* |
||||
* glyph_index :: |
||||
* The index of the glyph in the font file. |
||||
* |
||||
* load_flags :: |
||||
* A flag indicating what to load for this glyph. The |
||||
* FT_LOAD_XXX constants can be used to control the |
||||
* glyph loading process (e.g., whether the outline |
||||
* should be scaled, whether to load bitmaps or not, |
||||
* whether to hint the outline, etc). |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
*/ |
||||
FT_CALLBACK_DEF( FT_Error ) |
||||
tt_glyph_load( FT_GlyphSlot slot, /* TT_GlyphSlot */ |
||||
FT_Size size, /* TT_Size */ |
||||
FT_UInt glyph_index, |
||||
FT_Int32 load_flags ) |
||||
{ |
||||
TT_GlyphSlot ttslot = (TT_GlyphSlot)slot; |
||||
TT_Size ttsize = (TT_Size)size; |
||||
FT_Face face = ttslot->face; |
||||
FT_Error error; |
||||
|
||||
|
||||
if ( !slot ) |
||||
return FT_THROW( Invalid_Slot_Handle ); |
||||
|
||||
if ( !size ) |
||||
return FT_THROW( Invalid_Size_Handle ); |
||||
|
||||
if ( !face ) |
||||
return FT_THROW( Invalid_Face_Handle ); |
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL |
||||
if ( glyph_index >= (FT_UInt)face->num_glyphs && |
||||
!face->internal->incremental_interface ) |
||||
#else |
||||
if ( glyph_index >= (FT_UInt)face->num_glyphs ) |
||||
#endif |
||||
return FT_THROW( Invalid_Argument ); |
||||
|
||||
if ( load_flags & FT_LOAD_NO_HINTING ) |
||||
{ |
||||
/* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ |
||||
/* are necessary to disable hinting for tricky fonts */ |
||||
|
||||
if ( FT_IS_TRICKY( face ) ) |
||||
load_flags &= ~FT_LOAD_NO_HINTING; |
||||
|
||||
if ( load_flags & FT_LOAD_NO_AUTOHINT ) |
||||
load_flags |= FT_LOAD_NO_HINTING; |
||||
} |
||||
|
||||
if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) |
||||
{ |
||||
load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; |
||||
|
||||
if ( !FT_IS_TRICKY( face ) ) |
||||
load_flags |= FT_LOAD_NO_HINTING; |
||||
} |
||||
|
||||
/* use hinted metrics only if we load a glyph with hinting */ |
||||
ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING ) |
||||
? &size->metrics |
||||
: &ttsize->hinted_metrics; |
||||
|
||||
/* now fill in the glyph slot with outline/bitmap/layered */ |
||||
error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags ); |
||||
|
||||
/* force drop-out mode to 2 - irrelevant now */ |
||||
/* slot->outline.dropout_mode = 2; */ |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/**** D R I V E R I N T E R F A C E ****/ |
||||
/**** ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
|
||||
FT_DEFINE_SERVICE_MULTIMASTERSREC( |
||||
tt_service_gx_multi_masters, |
||||
|
||||
NULL, /* FT_Get_MM_Func get_mm */ |
||||
NULL, /* FT_Set_MM_Design_Func set_mm_design */ |
||||
TT_Set_MM_Blend, /* FT_Set_MM_Blend_Func set_mm_blend */ |
||||
TT_Get_MM_Blend, /* FT_Get_MM_Blend_Func get_mm_blend */ |
||||
TT_Get_MM_Var, /* FT_Get_MM_Var_Func get_mm_var */ |
||||
TT_Set_Var_Design, /* FT_Set_Var_Design_Func set_var_design */ |
||||
TT_Get_Var_Design, /* FT_Get_Var_Design_Func get_var_design */ |
||||
TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func set_named_instance */ |
||||
TT_Get_Default_Named_Instance, |
||||
/* FT_Get_Default_Named_Instance_Func get_default_named_instance */ |
||||
NULL, /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ |
||||
NULL, /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ |
||||
|
||||
tt_construct_ps_name, /* FT_Construct_PS_Name_Func construct_ps_name */ |
||||
tt_var_load_delta_set_index_mapping, |
||||
/* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ |
||||
tt_var_load_item_variation_store, |
||||
/* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ |
||||
tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func get_item_delta */ |
||||
tt_var_done_item_variation_store, |
||||
/* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ |
||||
tt_var_done_delta_set_index_map, |
||||
/* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ |
||||
tt_get_var_blend, /* FT_Get_Var_Blend_Func get_var_blend */ |
||||
tt_done_blend /* FT_Done_Blend_Func done_blend */ |
||||
) |
||||
|
||||
FT_DEFINE_SERVICE_METRICSVARIATIONSREC( |
||||
tt_service_metrics_variations, |
||||
|
||||
tt_hadvance_adjust, /* FT_HAdvance_Adjust_Func hadvance_adjust */ |
||||
NULL, /* FT_LSB_Adjust_Func lsb_adjust */ |
||||
NULL, /* FT_RSB_Adjust_Func rsb_adjust */ |
||||
|
||||
tt_vadvance_adjust, /* FT_VAdvance_Adjust_Func vadvance_adjust */ |
||||
NULL, /* FT_TSB_Adjust_Func tsb_adjust */ |
||||
NULL, /* FT_BSB_Adjust_Func bsb_adjust */ |
||||
NULL, /* FT_VOrg_Adjust_Func vorg_adjust */ |
||||
|
||||
tt_apply_mvar, /* FT_Metrics_Adjust_Func metrics_adjust */ |
||||
tt_size_reset_height /* FT_Size_Reset_Func size_reset */ |
||||
) |
||||
|
||||
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
||||
|
||||
|
||||
static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = |
||||
{ |
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_TRUETYPE_ENGINE_TYPE_PATENTED |
||||
|
||||
#else /* !TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
FT_TRUETYPE_ENGINE_TYPE_NONE |
||||
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */ |
||||
}; |
||||
|
||||
|
||||
FT_DEFINE_SERVICE_TTGLYFREC( |
||||
tt_service_truetype_glyf, |
||||
|
||||
(TT_Glyf_GetLocationFunc)tt_face_get_location /* get_location */ |
||||
) |
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
FT_DEFINE_SERVICEDESCREC6( |
||||
tt_services, |
||||
|
||||
FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, |
||||
FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters, |
||||
FT_SERVICE_ID_METRICS_VARIATIONS, &tt_service_metrics_variations, |
||||
FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, |
||||
FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, |
||||
FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) |
||||
#else |
||||
FT_DEFINE_SERVICEDESCREC4( |
||||
tt_services, |
||||
|
||||
FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, |
||||
FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, |
||||
FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, |
||||
FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) |
||||
#endif |
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Module_Interface ) |
||||
tt_get_interface( FT_Module driver, /* TT_Driver */ |
||||
const char* tt_interface ) |
||||
{ |
||||
FT_Library library; |
||||
FT_Module_Interface result; |
||||
FT_Module sfntd; |
||||
SFNT_Service sfnt; |
||||
|
||||
|
||||
result = ft_service_list_lookup( tt_services, tt_interface ); |
||||
if ( result ) |
||||
return result; |
||||
|
||||
if ( !driver ) |
||||
return NULL; |
||||
library = driver->library; |
||||
if ( !library ) |
||||
return NULL; |
||||
|
||||
/* only return the default interface from the SFNT module */ |
||||
sfntd = FT_Get_Module( library, "sfnt" ); |
||||
if ( sfntd ) |
||||
{ |
||||
sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); |
||||
if ( sfnt ) |
||||
return sfnt->get_interface( driver, tt_interface ); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/* The FT_DriverInterface structure is defined in ftdriver.h. */ |
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER |
||||
#else |
||||
#define TT_HINTER_FLAG 0 |
||||
#endif |
||||
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
||||
#define TT_SIZE_SELECT tt_size_select |
||||
#else |
||||
#define TT_SIZE_SELECT 0 |
||||
#endif |
||||
|
||||
FT_DEFINE_DRIVER( |
||||
tt_driver_class, |
||||
|
||||
FT_MODULE_FONT_DRIVER | |
||||
FT_MODULE_DRIVER_SCALABLE | |
||||
TT_HINTER_FLAG, |
||||
|
||||
sizeof ( TT_DriverRec ), |
||||
|
||||
"truetype", /* driver name */ |
||||
0x10000L, /* driver version == 1.0 */ |
||||
0x20000L, /* driver requires FreeType 2.0 or above */ |
||||
|
||||
NULL, /* module-specific interface */ |
||||
|
||||
tt_driver_init, /* FT_Module_Constructor module_init */ |
||||
tt_driver_done, /* FT_Module_Destructor module_done */ |
||||
tt_get_interface, /* FT_Module_Requester get_interface */ |
||||
|
||||
sizeof ( TT_FaceRec ), |
||||
sizeof ( TT_SizeRec ), |
||||
sizeof ( FT_GlyphSlotRec ), |
||||
|
||||
tt_face_init, /* FT_Face_InitFunc init_face */ |
||||
tt_face_done, /* FT_Face_DoneFunc done_face */ |
||||
tt_size_init, /* FT_Size_InitFunc init_size */ |
||||
tt_size_done, /* FT_Size_DoneFunc done_size */ |
||||
tt_slot_init, /* FT_Slot_InitFunc init_slot */ |
||||
NULL, /* FT_Slot_DoneFunc done_slot */ |
||||
|
||||
tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ |
||||
|
||||
tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ |
||||
NULL, /* FT_Face_AttachFunc attach_file */ |
||||
tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ |
||||
|
||||
tt_size_request, /* FT_Size_RequestFunc request_size */ |
||||
TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ |
||||
) |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,35 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttdriver.h |
||||
* |
||||
* High-level TrueType driver interface (specification). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef TTDRIVER_H_ |
||||
#define TTDRIVER_H_ |
||||
|
||||
|
||||
#include <freetype/internal/ftdrv.h> |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
FT_DECLARE_DRIVER( tt_driver_class ) |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* TTDRIVER_H_ */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,42 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* tterrors.h |
||||
* |
||||
* TrueType error codes (specification only). |
||||
* |
||||
* Copyright (C) 2001-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* This file is used to define the TrueType error enumeration |
||||
* constants. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef TTERRORS_H_ |
||||
#define TTERRORS_H_ |
||||
|
||||
#include <freetype/ftmoderr.h> |
||||
|
||||
#undef FTERRORS_H_ |
||||
|
||||
#undef FT_ERR_PREFIX |
||||
#define FT_ERR_PREFIX TT_Err_ |
||||
#define FT_ERR_BASE FT_Mod_Err_TrueType |
||||
|
||||
#include <freetype/fterrors.h> |
||||
|
||||
#endif /* TTERRORS_H_ */ |
||||
|
||||
|
||||
/* END */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,61 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttgload.h |
||||
* |
||||
* TrueType Glyph Loader (specification). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef TTGLOAD_H_ |
||||
#define TTGLOAD_H_ |
||||
|
||||
|
||||
#include "ttobjs.h" |
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
#include "ttinterp.h" |
||||
#endif |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
FT_LOCAL( void ) |
||||
TT_Init_Glyph_Loading( TT_Face face ); |
||||
|
||||
FT_LOCAL( void ) |
||||
TT_Get_HMetrics( TT_Face face, |
||||
FT_UInt idx, |
||||
FT_Short* lsb, |
||||
FT_UShort* aw ); |
||||
|
||||
FT_LOCAL( void ) |
||||
TT_Get_VMetrics( TT_Face face, |
||||
FT_UInt idx, |
||||
FT_Pos yMax, |
||||
FT_Short* tsb, |
||||
FT_UShort* ah ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Load_Glyph( TT_Size size, |
||||
TT_GlyphSlot glyph, |
||||
FT_UInt glyph_index, |
||||
FT_Int32 load_flags ); |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* TTGLOAD_H_ */ |
||||
|
||||
|
||||
/* END */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,453 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttgxvar.h |
||||
* |
||||
* TrueType GX Font Variation loader (specification) |
||||
* |
||||
* Copyright (C) 2004-2023 by |
||||
* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef TTGXVAR_H_ |
||||
#define TTGXVAR_H_ |
||||
|
||||
|
||||
#include <freetype/internal/ftmmtypes.h> |
||||
#include "ttobjs.h" |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* GX_AVarCorrespondenceRec |
||||
* |
||||
* @Description: |
||||
* A data structure representing `shortFracCorrespondence' in `avar' |
||||
* table according to the specifications from Apple. |
||||
*/ |
||||
typedef struct GX_AVarCorrespondenceRec_ |
||||
{ |
||||
FT_Fixed fromCoord; |
||||
FT_Fixed toCoord; |
||||
|
||||
} GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* GX_AVarRec |
||||
* |
||||
* @Description: |
||||
* Data from the segment field of `avar' table. |
||||
* There is one of these for each axis. |
||||
*/ |
||||
typedef struct GX_AVarSegmentRec_ |
||||
{ |
||||
FT_UShort pairCount; |
||||
GX_AVarCorrespondence correspondence; /* array with pairCount entries */ |
||||
|
||||
} GX_AVarSegmentRec, *GX_AVarSegment; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* GX_AVarTableRec |
||||
* |
||||
* @Description: |
||||
* Data from the `avar' table. |
||||
*/ |
||||
typedef struct GX_AVarTableRec_ |
||||
{ |
||||
GX_AVarSegment avar_segment; /* avar_segment[num_axis] */ |
||||
GX_ItemVarStoreRec itemStore; /* Item Variation Store */ |
||||
GX_DeltaSetIdxMapRec axisMap; /* Axis Mapping */ |
||||
|
||||
} GX_AVarTableRec, *GX_AVarTable; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* GX_HVVarTableRec |
||||
* |
||||
* @Description: |
||||
* Data from either the `HVAR' or `VVAR' table. |
||||
*/ |
||||
typedef struct GX_HVVarTableRec_ |
||||
{ |
||||
GX_ItemVarStoreRec itemStore; /* Item Variation Store */ |
||||
GX_DeltaSetIdxMapRec widthMap; /* Advance Width Mapping */ |
||||
|
||||
#if 0 |
||||
GX_DeltaSetIdxMapRec lsbMap; /* not implemented */ |
||||
GX_DeltaSetIdxMapRec rsbMap; /* not implemented */ |
||||
|
||||
GX_DeltaSetIdxMapRec tsbMap; /* not implemented */ |
||||
GX_DeltaSetIdxMapRec bsbMap; /* not implemented */ |
||||
GX_DeltaSetIdxMapRec vorgMap; /* not implemented */ |
||||
#endif |
||||
|
||||
} GX_HVVarTableRec, *GX_HVVarTable; |
||||
|
||||
|
||||
#define MVAR_TAG_GASP_0 FT_MAKE_TAG( 'g', 's', 'p', '0' ) |
||||
#define MVAR_TAG_GASP_1 FT_MAKE_TAG( 'g', 's', 'p', '1' ) |
||||
#define MVAR_TAG_GASP_2 FT_MAKE_TAG( 'g', 's', 'p', '2' ) |
||||
#define MVAR_TAG_GASP_3 FT_MAKE_TAG( 'g', 's', 'p', '3' ) |
||||
#define MVAR_TAG_GASP_4 FT_MAKE_TAG( 'g', 's', 'p', '4' ) |
||||
#define MVAR_TAG_GASP_5 FT_MAKE_TAG( 'g', 's', 'p', '5' ) |
||||
#define MVAR_TAG_GASP_6 FT_MAKE_TAG( 'g', 's', 'p', '6' ) |
||||
#define MVAR_TAG_GASP_7 FT_MAKE_TAG( 'g', 's', 'p', '7' ) |
||||
#define MVAR_TAG_GASP_8 FT_MAKE_TAG( 'g', 's', 'p', '8' ) |
||||
#define MVAR_TAG_GASP_9 FT_MAKE_TAG( 'g', 's', 'p', '9' ) |
||||
|
||||
#define MVAR_TAG_CPHT FT_MAKE_TAG( 'c', 'p', 'h', 't' ) |
||||
#define MVAR_TAG_HASC FT_MAKE_TAG( 'h', 'a', 's', 'c' ) |
||||
#define MVAR_TAG_HCLA FT_MAKE_TAG( 'h', 'c', 'l', 'a' ) |
||||
#define MVAR_TAG_HCLD FT_MAKE_TAG( 'h', 'c', 'l', 'd' ) |
||||
#define MVAR_TAG_HCOF FT_MAKE_TAG( 'h', 'c', 'o', 'f' ) |
||||
#define MVAR_TAG_HCRN FT_MAKE_TAG( 'h', 'c', 'r', 'n' ) |
||||
#define MVAR_TAG_HCRS FT_MAKE_TAG( 'h', 'c', 'r', 's' ) |
||||
#define MVAR_TAG_HDSC FT_MAKE_TAG( 'h', 'd', 's', 'c' ) |
||||
#define MVAR_TAG_HLGP FT_MAKE_TAG( 'h', 'l', 'g', 'p' ) |
||||
#define MVAR_TAG_SBXO FT_MAKE_TAG( 's', 'b', 'x', 'o' ) |
||||
#define MVAR_TAG_SBXS FT_MAKE_TAG( 's', 'b', 'x', 's' ) |
||||
#define MVAR_TAG_SBYO FT_MAKE_TAG( 's', 'b', 'y', 'o' ) |
||||
#define MVAR_TAG_SBYS FT_MAKE_TAG( 's', 'b', 'y', 's' ) |
||||
#define MVAR_TAG_SPXO FT_MAKE_TAG( 's', 'p', 'x', 'o' ) |
||||
#define MVAR_TAG_SPXS FT_MAKE_TAG( 's', 'p', 'x', 's' ) |
||||
#define MVAR_TAG_SPYO FT_MAKE_TAG( 's', 'p', 'y', 'o' ) |
||||
#define MVAR_TAG_SPYS FT_MAKE_TAG( 's', 'p', 'y', 's' ) |
||||
#define MVAR_TAG_STRO FT_MAKE_TAG( 's', 't', 'r', 'o' ) |
||||
#define MVAR_TAG_STRS FT_MAKE_TAG( 's', 't', 'r', 's' ) |
||||
#define MVAR_TAG_UNDO FT_MAKE_TAG( 'u', 'n', 'd', 'o' ) |
||||
#define MVAR_TAG_UNDS FT_MAKE_TAG( 'u', 'n', 'd', 's' ) |
||||
#define MVAR_TAG_VASC FT_MAKE_TAG( 'v', 'a', 's', 'c' ) |
||||
#define MVAR_TAG_VCOF FT_MAKE_TAG( 'v', 'c', 'o', 'f' ) |
||||
#define MVAR_TAG_VCRN FT_MAKE_TAG( 'v', 'c', 'r', 'n' ) |
||||
#define MVAR_TAG_VCRS FT_MAKE_TAG( 'v', 'c', 'r', 's' ) |
||||
#define MVAR_TAG_VDSC FT_MAKE_TAG( 'v', 'd', 's', 'c' ) |
||||
#define MVAR_TAG_VLGP FT_MAKE_TAG( 'v', 'l', 'g', 'p' ) |
||||
#define MVAR_TAG_XHGT FT_MAKE_TAG( 'x', 'h', 'g', 't' ) |
||||
|
||||
|
||||
typedef struct GX_ValueRec_ |
||||
{ |
||||
FT_ULong tag; |
||||
FT_UShort outerIndex; |
||||
FT_UShort innerIndex; |
||||
|
||||
FT_Short unmodified; /* values are either FT_Short or FT_UShort */ |
||||
|
||||
} GX_ValueRec, *GX_Value; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* GX_MVarTableRec |
||||
* |
||||
* @Description: |
||||
* Data from the `MVAR' table. |
||||
*/ |
||||
typedef struct GX_MVarTableRec_ |
||||
{ |
||||
FT_UShort valueCount; |
||||
|
||||
GX_ItemVarStoreRec itemStore; /* Item Variation Store */ |
||||
GX_Value values; /* Value Records */ |
||||
|
||||
} GX_MVarTableRec, *GX_MVarTable; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* GX_BlendRec |
||||
* |
||||
* @Description: |
||||
* Data for interpolating a font from a distortable font specified |
||||
* by the GX *var tables ([fgcahvm]var). |
||||
* |
||||
* @Fields: |
||||
* num_axis :: |
||||
* The number of axes along which interpolation may happen. |
||||
* |
||||
* coords :: |
||||
* An array of design coordinates (in user space) indicating the |
||||
* contribution along each axis to the final interpolated font. |
||||
* `normalizedcoords' holds the same values. |
||||
* |
||||
* normalizedcoords :: |
||||
* An array of normalized values (between [-1,1]) indicating the |
||||
* contribution along each axis to the final interpolated font. |
||||
* `coords' holds the same values. |
||||
* |
||||
* mmvar :: |
||||
* Data from the `fvar' table. |
||||
* |
||||
* mmvar_len :: |
||||
* The length of the `mmvar' structure. |
||||
* |
||||
* normalized_stylecoords :: |
||||
* A two-dimensional array that holds the named instance data from |
||||
* `mmvar' as normalized values. |
||||
* |
||||
* avar_loaded :: |
||||
* A Boolean; if set, FreeType tried to load (and parse) the `avar' |
||||
* table. |
||||
* |
||||
* avar_table :: |
||||
* Data from the `avar' table. |
||||
* |
||||
* hvar_loaded :: |
||||
* A Boolean; if set, FreeType tried to load (and parse) the `hvar' |
||||
* table. |
||||
* |
||||
* hvar_checked :: |
||||
* A Boolean; if set, FreeType successfully loaded and parsed the |
||||
* `hvar' table. |
||||
* |
||||
* hvar_error :: |
||||
* If loading and parsing of the `hvar' table failed, this field |
||||
* holds the corresponding error code. |
||||
* |
||||
* hvar_table :: |
||||
* Data from the `hvar' table. |
||||
* |
||||
* vvar_loaded :: |
||||
* A Boolean; if set, FreeType tried to load (and parse) the `vvar' |
||||
* table. |
||||
* |
||||
* vvar_checked :: |
||||
* A Boolean; if set, FreeType successfully loaded and parsed the |
||||
* `vvar' table. |
||||
* |
||||
* vvar_error :: |
||||
* If loading and parsing of the `vvar' table failed, this field |
||||
* holds the corresponding error code. |
||||
* |
||||
* vvar_table :: |
||||
* Data from the `vvar' table. |
||||
* |
||||
* mvar_table :: |
||||
* Data from the `mvar' table. |
||||
* |
||||
* tuplecount :: |
||||
* The number of shared tuples in the `gvar' table. |
||||
* |
||||
* tuplecoords :: |
||||
* A two-dimensional array that holds the shared tuple coordinates |
||||
* in the `gvar' table. |
||||
* |
||||
* gv_glyphcnt :: |
||||
* The number of glyphs handled in the `gvar' table. |
||||
* |
||||
* glyphoffsets :: |
||||
* Offsets into the glyph variation data array. |
||||
* |
||||
* gvar_size :: |
||||
* The size of the `gvar' table. |
||||
*/ |
||||
typedef struct GX_BlendRec_ |
||||
{ |
||||
FT_UInt num_axis; |
||||
FT_Fixed* coords; |
||||
FT_Fixed* normalizedcoords; |
||||
|
||||
FT_MM_Var* mmvar; |
||||
FT_Offset mmvar_len; |
||||
|
||||
FT_Fixed* normalized_stylecoords; |
||||
/* normalized_stylecoords[num_namedstyles][num_axis] */ |
||||
|
||||
FT_Bool avar_loaded; |
||||
GX_AVarTable avar_table; |
||||
|
||||
FT_Bool hvar_loaded; |
||||
FT_Bool hvar_checked; |
||||
FT_Error hvar_error; |
||||
GX_HVVarTable hvar_table; |
||||
|
||||
FT_Bool vvar_loaded; |
||||
FT_Bool vvar_checked; |
||||
FT_Error vvar_error; |
||||
GX_HVVarTable vvar_table; |
||||
|
||||
GX_MVarTable mvar_table; |
||||
|
||||
FT_UInt tuplecount; |
||||
FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ |
||||
|
||||
FT_UInt gv_glyphcnt; |
||||
FT_ULong* glyphoffsets; /* glyphoffsets[gv_glyphcnt + 1] */ |
||||
|
||||
FT_ULong gvar_size; |
||||
|
||||
} GX_BlendRec; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @enum: |
||||
* GX_TupleCountFlags |
||||
* |
||||
* @Description: |
||||
* Flags used within the `TupleCount' field of the `gvar' table. |
||||
*/ |
||||
typedef enum GX_TupleCountFlags_ |
||||
{ |
||||
GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, |
||||
GX_TC_RESERVED_TUPLE_FLAGS = 0x7000, |
||||
GX_TC_TUPLE_COUNT_MASK = 0x0FFF |
||||
|
||||
} GX_TupleCountFlags; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @enum: |
||||
* GX_TupleIndexFlags |
||||
* |
||||
* @Description: |
||||
* Flags used within the `TupleIndex' field of the `gvar' and `cvar' |
||||
* tables. |
||||
*/ |
||||
typedef enum GX_TupleIndexFlags_ |
||||
{ |
||||
GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, |
||||
GX_TI_INTERMEDIATE_TUPLE = 0x4000, |
||||
GX_TI_PRIVATE_POINT_NUMBERS = 0x2000, |
||||
GX_TI_RESERVED_TUPLE_FLAG = 0x1000, |
||||
GX_TI_TUPLE_INDEX_MASK = 0x0FFF |
||||
|
||||
} GX_TupleIndexFlags; |
||||
|
||||
|
||||
#define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' ) |
||||
#define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) |
||||
#define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) |
||||
#define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) |
||||
#define TTAG_ital FT_MAKE_TAG( 'i', 't', 'a', 'l' ) |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Set_MM_Blend( FT_Face face, |
||||
FT_UInt num_coords, |
||||
FT_Fixed* coords ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Get_MM_Blend( FT_Face face, |
||||
FT_UInt num_coords, |
||||
FT_Fixed* coords ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Set_Var_Design( FT_Face face, |
||||
FT_UInt num_coords, |
||||
FT_Fixed* coords ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Get_MM_Var( FT_Face face, |
||||
FT_MM_Var* *master ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Get_Var_Design( FT_Face face, |
||||
FT_UInt num_coords, |
||||
FT_Fixed* coords ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Set_Named_Instance( FT_Face face, |
||||
FT_UInt instance_index ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Get_Default_Named_Instance( FT_Face face, |
||||
FT_UInt *instance_index ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_construct_ps_name( FT_Face face ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_vary_cvt( TT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Vary_Apply_Glyph_Deltas( TT_Loader loader, |
||||
FT_Outline* outline, |
||||
FT_Vector* unrounded ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_hadvance_adjust( FT_Face face, |
||||
FT_UInt gindex, |
||||
FT_Int *adelta ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_vadvance_adjust( FT_Face face, |
||||
FT_UInt gindex, |
||||
FT_Int *adelta ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_apply_mvar( FT_Face face ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_var_load_item_variation_store( FT_Face face, |
||||
FT_ULong offset, |
||||
GX_ItemVarStore itemStore ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_var_load_delta_set_index_mapping( FT_Face face, |
||||
FT_ULong offset, |
||||
GX_DeltaSetIdxMap map, |
||||
GX_ItemVarStore itemStore, |
||||
FT_ULong table_len ); |
||||
|
||||
FT_LOCAL( FT_ItemVarDelta ) |
||||
tt_var_get_item_delta( FT_Face face, |
||||
GX_ItemVarStore itemStore, |
||||
FT_UInt outerIndex, |
||||
FT_UInt innerIndex ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_var_done_item_variation_store( FT_Face face, |
||||
GX_ItemVarStore itemStore ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_var_done_delta_set_index_map( FT_Face face, |
||||
GX_DeltaSetIdxMap deltaSetIdxMap ); |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_get_var_blend( FT_Face face, |
||||
FT_UInt *num_coords, |
||||
FT_Fixed* *coords, |
||||
FT_Fixed* *normalizedcoords, |
||||
FT_MM_Var* *mm_var ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_done_blend( FT_Face face ); |
||||
|
||||
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
|
||||
#endif /* TTGXVAR_H_ */ |
||||
|
||||
|
||||
/* END */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,465 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttinterp.h |
||||
* |
||||
* TrueType bytecode interpreter (specification). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef TTINTERP_H_ |
||||
#define TTINTERP_H_ |
||||
|
||||
#include "ttobjs.h" |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Rounding mode constants. |
||||
*/ |
||||
#define TT_Round_Off 5 |
||||
#define TT_Round_To_Half_Grid 0 |
||||
#define TT_Round_To_Grid 1 |
||||
#define TT_Round_To_Double_Grid 2 |
||||
#define TT_Round_Up_To_Grid 4 |
||||
#define TT_Round_Down_To_Grid 3 |
||||
#define TT_Round_Super 6 |
||||
#define TT_Round_Super_45 7 |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Function types used by the interpreter, depending on various modes |
||||
* (e.g. the rounding mode, whether to render a vertical or horizontal |
||||
* line etc). |
||||
* |
||||
*/ |
||||
|
||||
/* Rounding function */ |
||||
typedef FT_F26Dot6 |
||||
(*TT_Round_Func)( TT_ExecContext exc, |
||||
FT_F26Dot6 distance, |
||||
FT_Int color ); |
||||
|
||||
/* Point displacement along the freedom vector routine */ |
||||
typedef void |
||||
(*TT_Move_Func)( TT_ExecContext exc, |
||||
TT_GlyphZone zone, |
||||
FT_UShort point, |
||||
FT_F26Dot6 distance ); |
||||
|
||||
/* Distance projection along one of the projection vectors */ |
||||
typedef FT_F26Dot6 |
||||
(*TT_Project_Func)( TT_ExecContext exc, |
||||
FT_Pos dx, |
||||
FT_Pos dy ); |
||||
|
||||
/* getting current ppem. Take care of non-square pixels if necessary */ |
||||
typedef FT_Long |
||||
(*TT_Cur_Ppem_Func)( TT_ExecContext exc ); |
||||
|
||||
/* reading a cvt value. Take care of non-square pixels if necessary */ |
||||
typedef FT_F26Dot6 |
||||
(*TT_Get_CVT_Func)( TT_ExecContext exc, |
||||
FT_ULong idx ); |
||||
|
||||
/* setting or moving a cvt value. Take care of non-square pixels */ |
||||
/* if necessary */ |
||||
typedef void |
||||
(*TT_Set_CVT_Func)( TT_ExecContext exc, |
||||
FT_ULong idx, |
||||
FT_F26Dot6 value ); |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* This structure defines a call record, used to manage function calls. |
||||
*/ |
||||
typedef struct TT_CallRec_ |
||||
{ |
||||
FT_Int Caller_Range; |
||||
FT_Long Caller_IP; |
||||
FT_Long Cur_Count; |
||||
|
||||
TT_DefRecord *Def; /* either FDEF or IDEF */ |
||||
|
||||
} TT_CallRec, *TT_CallStack; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* The main structure for the interpreter which collects all necessary |
||||
* variables and states. |
||||
* |
||||
* Members that are initialized by `TT_Load_Context` are marked with '!'. |
||||
* Members that are initialized by `TT_Run_Context` are marked with '@'. |
||||
*/ |
||||
typedef struct TT_ExecContextRec_ |
||||
{ |
||||
TT_Face face; /* ! */ |
||||
TT_Size size; /* ! */ |
||||
FT_Memory memory; |
||||
|
||||
/* instructions state */ |
||||
|
||||
FT_Error error; /* last execution error */ |
||||
|
||||
FT_Long top; /* @ top of exec. stack */ |
||||
|
||||
FT_Long stackSize; /* ! size of exec. stack */ |
||||
FT_Long* stack; /* ! current exec. stack */ |
||||
|
||||
FT_Long args; |
||||
FT_Long new_top; /* new top after exec. */ |
||||
|
||||
TT_GlyphZoneRec zp0, /* @! zone records */ |
||||
zp1, /* @! */ |
||||
zp2, /* @! */ |
||||
pts, /* ! */ |
||||
twilight; /* ! */ |
||||
|
||||
FT_Long pointSize; /* ! in 26.6 format */ |
||||
FT_Size_Metrics metrics; /* ! */ |
||||
TT_Size_Metrics tt_metrics; /* ! size metrics */ |
||||
|
||||
TT_GraphicsState GS; /* !@ current graphics state */ |
||||
|
||||
FT_Int iniRange; /* initial code range number */ |
||||
FT_Int curRange; /* current code range number */ |
||||
FT_Byte* code; /* current code range */ |
||||
FT_Long IP; /* current instruction pointer */ |
||||
FT_Long codeSize; /* size of current range */ |
||||
|
||||
FT_Byte opcode; /* current opcode */ |
||||
FT_Int length; /* length of current opcode */ |
||||
|
||||
FT_Bool step_ins; /* true if the interpreter must */ |
||||
/* increment IP after ins. exec */ |
||||
FT_ULong cvtSize; /* ! */ |
||||
FT_Long* cvt; /* ! */ |
||||
FT_ULong glyfCvtSize; |
||||
FT_Long* glyfCvt; /* cvt working copy for glyph */ |
||||
|
||||
FT_UInt glyphSize; /* ! glyph instructions buffer size */ |
||||
FT_Byte* glyphIns; /* ! glyph instructions buffer */ |
||||
|
||||
FT_UInt numFDefs; /* ! number of function defs */ |
||||
FT_UInt maxFDefs; /* ! maximum number of function defs */ |
||||
TT_DefArray FDefs; /* table of FDefs entries */ |
||||
|
||||
FT_UInt numIDefs; /* ! number of instruction defs */ |
||||
FT_UInt maxIDefs; /* ! maximum number of ins defs */ |
||||
TT_DefArray IDefs; /* table of IDefs entries */ |
||||
|
||||
FT_UInt maxFunc; /* ! maximum function index */ |
||||
FT_UInt maxIns; /* ! maximum instruction index */ |
||||
|
||||
FT_Int callTop, /* @ top of call stack during execution */ |
||||
callSize; /* size of call stack */ |
||||
TT_CallStack callStack; /* call stack */ |
||||
|
||||
FT_UShort maxPoints; /* capacity of this context's `pts' */ |
||||
FT_Short maxContours; /* record, expressed in points and */ |
||||
/* contours. */ |
||||
|
||||
TT_CodeRangeTable codeRangeTable; /* ! table of valid code ranges */ |
||||
/* useful for the debugger */ |
||||
|
||||
FT_UShort storeSize; /* ! size of current storage */ |
||||
FT_Long* storage; /* ! storage area */ |
||||
FT_UShort glyfStoreSize; |
||||
FT_Long* glyfStorage; /* storage working copy for glyph */ |
||||
|
||||
FT_F26Dot6 period; /* values used for the */ |
||||
FT_F26Dot6 phase; /* `SuperRounding' */ |
||||
FT_F26Dot6 threshold; |
||||
|
||||
FT_Bool instruction_trap; /* ! If `True', the interpreter */ |
||||
/* exits after each instruction */ |
||||
|
||||
TT_GraphicsState default_GS; /* graphics state resulting from */ |
||||
/* the prep program */ |
||||
FT_Bool is_composite; /* true if the glyph is composite */ |
||||
FT_Bool pedantic_hinting; /* true if pedantic interpretation */ |
||||
|
||||
/* latest interpreter additions */ |
||||
|
||||
FT_Long F_dot_P; /* dot product of freedom and projection */ |
||||
/* vectors */ |
||||
TT_Round_Func func_round; /* current rounding function */ |
||||
|
||||
TT_Project_Func func_project, /* current projection function */ |
||||
func_dualproj, /* current dual proj. function */ |
||||
func_freeProj; /* current freedom proj. func */ |
||||
|
||||
TT_Move_Func func_move; /* current point move function */ |
||||
TT_Move_Func func_move_orig; /* move original position function */ |
||||
|
||||
TT_Cur_Ppem_Func func_cur_ppem; /* get current proj. ppem value */ |
||||
|
||||
TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ |
||||
TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ |
||||
TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ |
||||
|
||||
FT_Bool grayscale; /* bi-level hinting and */ |
||||
/* grayscale rendering */ |
||||
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL |
||||
/*
|
||||
* FreeType supports ClearType-like hinting of TrueType fonts through |
||||
* the version 40 interpreter. This is achieved through several hacks |
||||
* in the base (v35) interpreter, as detailed below. |
||||
* |
||||
* ClearType is an umbrella term for several rendering techniques |
||||
* employed by Microsoft's various GUI and rendering toolkit |
||||
* implementations, most importantly: subpixel rendering for using the |
||||
* RGB subpixels of LCDs to approximately triple the perceived |
||||
* resolution on the x-axis and subpixel hinting for positioning stems |
||||
* on subpixel borders. TrueType programming is explicit, i.e., fonts |
||||
* must be programmed to take advantage of ClearType's possibilities. |
||||
* |
||||
* When ClearType was introduced, it seemed unlikely that all fonts |
||||
* would be reprogrammed, so Microsoft decided to implement a backward |
||||
* compatibility mode. It employs several simple to complicated |
||||
* assumptions and tricks, many of them font-dependent, that modify the |
||||
* interpretation of the bytecode contained in these fonts to retrofit |
||||
* them into a ClearType-y look. The quality of the results varies. |
||||
* Most (web)fonts that were released since then have come to rely on |
||||
* these hacks to render correctly, even some of Microsoft's flagship |
||||
* fonts (e.g., Calibri, Cambria, Segoe UI). |
||||
* |
||||
* FreeType's minimal subpixel hinting code (interpreter version 40) |
||||
* employs a small list of font-agnostic hacks loosely based on the |
||||
* public information available on Microsoft's compatibility mode[2]. |
||||
* The focus is on modern (web)fonts rather than legacy fonts that were |
||||
* made for monochrome rendering. It will not match ClearType rendering |
||||
* exactly. Unlike the `Infinality' code (interpreter version 38) that |
||||
* came before, it will not try to toggle hacks for specific fonts for |
||||
* performance and complexity reasons. It will fall back to version 35 |
||||
* behavior for tricky fonts[1] or when monochrome rendering is |
||||
* requested. |
||||
* |
||||
* Major hacks |
||||
* |
||||
* - Any point movement on the x axis is ignored (cf. `Direct_Move' and |
||||
* `Direct_Move_X'). This has the smallest code footprint and single |
||||
* biggest effect. The ClearType way to increase resolution is |
||||
* supersampling the x axis, the FreeType way is ignoring instructions |
||||
* on the x axis, which gives the same result in the majority of |
||||
* cases. |
||||
* |
||||
* - Points are not moved post-IUP (neither on the x nor on the y axis), |
||||
* except the x component of diagonal moves post-IUP (cf. |
||||
* `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP |
||||
* changes are commonly used to `fix' pixel patterns which has little |
||||
* use outside monochrome rendering. |
||||
* |
||||
* - SHPIX and DELTAP don't execute unless moving a composite on the |
||||
* y axis or moving a previously y touched point. SHPIX additionally |
||||
* denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP'). |
||||
* Both instructions are commonly used to `fix' pixel patterns for |
||||
* monochrome or Windows's GDI rendering but make little sense for |
||||
* FreeType rendering. Both can distort the outline. See [2] for |
||||
* details. |
||||
* |
||||
* - The hdmx table and modifications to phantom points are ignored. |
||||
* Bearings and advance widths remain unchanged (except rounding them |
||||
* outside the interpreter!), cf. `compute_glyph_metrics' and |
||||
* `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing |
||||
* might mess up spacing. |
||||
* |
||||
* Minor hacks |
||||
* |
||||
* - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This |
||||
* prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at |
||||
* various sizes. |
||||
* |
||||
* (Post-IUP is the state after both IUP[x] and IUP[y] have been |
||||
* executed.) |
||||
* |
||||
* The best results are achieved for fonts that were from the outset |
||||
* designed with ClearType in mind, meaning they leave the x axis mostly |
||||
* alone and don't mess with the `final' outline to produce more |
||||
* pleasing pixel patterns. The harder the designer tried to produce |
||||
* very specific patterns (`superhinting') for pre-ClearType-displays, |
||||
* the worse the results. |
||||
* |
||||
* Microsoft defines a way to turn off backward compatibility and |
||||
* interpret instructions as before (called `native ClearType')[2][3]. |
||||
* The font designer then regains full control and is responsible for |
||||
* making the font work correctly with ClearType without any |
||||
* hand-holding by the interpreter or rasterizer[4]. The v40 |
||||
* interpreter assumes backward compatibility by default, which can be |
||||
* turned off the same way by executing the following in the control |
||||
* program (cf. `Ins_INSTCTRL'). |
||||
* |
||||
* #PUSH 4,3 |
||||
* INSTCTRL[] |
||||
* |
||||
* [1] Tricky fonts as FreeType defines them rely on the bytecode |
||||
* interpreter to display correctly. Hacks can interfere with them, |
||||
* so they get treated like native ClearType fonts (v40 with |
||||
* backward compatibility turned off). Cf. `TT_RunIns'. |
||||
* |
||||
* [2] Proposed by Microsoft's Greg Hitchcock in |
||||
* https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
|
||||
* |
||||
* [3] Beat Stamm describes it in more detail: |
||||
* http://rastertragedy.com/RTRCh4.htm#Sec12.
|
||||
* |
||||
* [4] The list of `native ClearType' fonts is small at the time of this |
||||
* writing; I found the following on a Windows 10 Update 1511 |
||||
* installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft |
||||
* JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold), |
||||
* SimSun, NSimSun, and Yu Gothic. |
||||
* |
||||
*/ |
||||
|
||||
/* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been
|
||||
* requested. Used to detect interpreter */ |
||||
/* version switches. `_lean' to differentiate from the Infinality */ |
||||
/* `subpixel_hinting', which is managed differently. */ |
||||
FT_Bool subpixel_hinting_lean; |
||||
|
||||
/* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */ |
||||
/* `_lean' to differentiate from the Infinality `vertical_lcd', which */ |
||||
/* is managed differently. */ |
||||
FT_Bool vertical_lcd_lean; |
||||
|
||||
/* Default to backward compatibility mode in v40 interpreter. If */ |
||||
/* this is false, it implies the interpreter is in v35 or in native */ |
||||
/* ClearType mode. */ |
||||
FT_Bool backward_compatibility; |
||||
|
||||
/* Useful for detecting and denying post-IUP trickery that is usually */ |
||||
/* used to fix pixel patterns (`superhinting'). */ |
||||
FT_Bool iupx_called; |
||||
FT_Bool iupy_called; |
||||
|
||||
/* ClearType hinting and grayscale rendering, as used by Universal */ |
||||
/* Windows Platform apps (Windows 8 and above). Like the standard */ |
||||
/* colorful ClearType mode, it utilizes a vastly increased virtual */ |
||||
/* resolution on the x axis. Different from bi-level hinting and */ |
||||
/* grayscale rendering, the old mode from Win9x days that roughly */ |
||||
/* adheres to the physical pixel grid on both axes. */ |
||||
FT_Bool grayscale_cleartype; |
||||
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ |
||||
|
||||
/* We maintain two counters (in addition to the instruction counter) */ |
||||
/* that act as loop detectors for LOOPCALL and jump opcodes with */ |
||||
/* negative arguments. */ |
||||
FT_ULong loopcall_counter; |
||||
FT_ULong loopcall_counter_max; |
||||
FT_ULong neg_jump_counter; |
||||
FT_ULong neg_jump_counter_max; |
||||
|
||||
} TT_ExecContextRec; |
||||
|
||||
|
||||
extern const TT_GraphicsState tt_default_graphics_state; |
||||
|
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
FT_LOCAL( void ) |
||||
TT_Goto_CodeRange( TT_ExecContext exec, |
||||
FT_Int range, |
||||
FT_Long IP ); |
||||
|
||||
FT_LOCAL( void ) |
||||
TT_Set_CodeRange( TT_ExecContext exec, |
||||
FT_Int range, |
||||
void* base, |
||||
FT_Long length ); |
||||
|
||||
FT_LOCAL( void ) |
||||
TT_Clear_CodeRange( TT_ExecContext exec, |
||||
FT_Int range ); |
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* TT_New_Context |
||||
* |
||||
* @Description: |
||||
* Create a `TT_ExecContext`. Note that there is now an execution |
||||
* context per `TT_Size` that is not shared among faces. |
||||
* |
||||
* @Input: |
||||
* driver :: |
||||
* A handle to the driver, used for memory allocation. |
||||
* |
||||
* @Return: |
||||
* A handle to a new empty execution context. |
||||
* |
||||
* @Note: |
||||
* Only the glyph loader and debugger should call this function. |
||||
* (And right now only the glyph loader uses it.) |
||||
*/ |
||||
FT_EXPORT( TT_ExecContext ) |
||||
TT_New_Context( TT_Driver driver ); |
||||
|
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
FT_LOCAL( void ) |
||||
TT_Done_Context( TT_ExecContext exec ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Load_Context( TT_ExecContext exec, |
||||
TT_Face face, |
||||
TT_Size size ); |
||||
|
||||
FT_LOCAL( void ) |
||||
TT_Save_Context( TT_ExecContext exec, |
||||
TT_Size ins ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
TT_Run_Context( TT_ExecContext exec ); |
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* TT_RunIns |
||||
* |
||||
* @Description: |
||||
* Executes one or more instruction in the execution context. This |
||||
* is the main function of the TrueType opcode interpreter. |
||||
* |
||||
* @Input: |
||||
* exec :: |
||||
* A handle to the target execution context. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
* |
||||
* @Note: |
||||
* Only the object manager and debugger should call this function. |
||||
* |
||||
* This function is publicly exported because it is directly |
||||
* invoked by the TrueType debugger. |
||||
*/ |
||||
FT_EXPORT( FT_Error ) |
||||
TT_RunIns( void* exec ); |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* TTINTERP_H_ */ |
||||
|
||||
|
||||
/* END */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,426 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttobjs.h |
||||
* |
||||
* Objects manager (specification). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef TTOBJS_H_ |
||||
#define TTOBJS_H_ |
||||
|
||||
|
||||
#include <freetype/internal/ftobjs.h> |
||||
#include <freetype/internal/tttypes.h> |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Type: |
||||
* TT_Driver |
||||
* |
||||
* @Description: |
||||
* A handle to a TrueType driver object. |
||||
*/ |
||||
typedef struct TT_DriverRec_* TT_Driver; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Type: |
||||
* TT_GlyphSlot |
||||
* |
||||
* @Description: |
||||
* A handle to a TrueType glyph slot object. |
||||
* |
||||
* @Note: |
||||
* This is a direct typedef of FT_GlyphSlot, as there is nothing |
||||
* specific about the TrueType glyph slot. |
||||
*/ |
||||
typedef FT_GlyphSlot TT_GlyphSlot; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Struct: |
||||
* TT_GraphicsState |
||||
* |
||||
* @Description: |
||||
* The TrueType graphics state used during bytecode interpretation. |
||||
*/ |
||||
typedef struct TT_GraphicsState_ |
||||
{ |
||||
FT_UShort rp0; |
||||
FT_UShort rp1; |
||||
FT_UShort rp2; |
||||
|
||||
FT_UnitVector dualVector; |
||||
FT_UnitVector projVector; |
||||
FT_UnitVector freeVector; |
||||
|
||||
FT_Long loop; |
||||
FT_F26Dot6 minimum_distance; |
||||
FT_Int round_state; |
||||
|
||||
FT_Bool auto_flip; |
||||
FT_F26Dot6 control_value_cutin; |
||||
FT_F26Dot6 single_width_cutin; |
||||
FT_F26Dot6 single_width_value; |
||||
FT_UShort delta_base; |
||||
FT_UShort delta_shift; |
||||
|
||||
FT_Byte instruct_control; |
||||
/* According to Greg Hitchcock from Microsoft, the `scan_control' */ |
||||
/* variable as documented in the TrueType specification is a 32-bit */ |
||||
/* integer; the high-word part holds the SCANTYPE value, the low-word */ |
||||
/* part the SCANCTRL value. We separate it into two fields. */ |
||||
FT_Bool scan_control; |
||||
FT_Int scan_type; |
||||
|
||||
FT_UShort gep0; |
||||
FT_UShort gep1; |
||||
FT_UShort gep2; |
||||
|
||||
} TT_GraphicsState; |
||||
|
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_glyphzone_done( TT_GlyphZone zone ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_glyphzone_new( FT_Memory memory, |
||||
FT_UShort maxPoints, |
||||
FT_Short maxContours, |
||||
TT_GlyphZone zone ); |
||||
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* EXECUTION SUBTABLES |
||||
* |
||||
* These sub-tables relate to instruction execution. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#define TT_MAX_CODE_RANGES 3 |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* There can only be 3 active code ranges at once: |
||||
* - the Font Program |
||||
* - the CVT Program |
||||
* - a glyph's instructions set |
||||
*/ |
||||
typedef enum TT_CodeRange_Tag_ |
||||
{ |
||||
tt_coderange_none = 0, |
||||
tt_coderange_font, |
||||
tt_coderange_cvt, |
||||
tt_coderange_glyph |
||||
|
||||
} TT_CodeRange_Tag; |
||||
|
||||
|
||||
typedef struct TT_CodeRange_ |
||||
{ |
||||
FT_Byte* base; |
||||
FT_Long size; |
||||
|
||||
} TT_CodeRange; |
||||
|
||||
typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Defines a function/instruction definition record. |
||||
*/ |
||||
typedef struct TT_DefRecord_ |
||||
{ |
||||
FT_Int range; /* in which code range is it located? */ |
||||
FT_Long start; /* where does it start? */ |
||||
FT_Long end; /* where does it end? */ |
||||
FT_UInt opc; /* function #, or instruction code */ |
||||
FT_Bool active; /* is it active? */ |
||||
|
||||
} TT_DefRecord, *TT_DefArray; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Subglyph transformation record. |
||||
*/ |
||||
typedef struct TT_Transform_ |
||||
{ |
||||
FT_Fixed xx, xy; /* transformation matrix coefficients */ |
||||
FT_Fixed yx, yy; |
||||
FT_F26Dot6 ox, oy; /* offsets */ |
||||
|
||||
} TT_Transform; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* A note regarding non-squared pixels: |
||||
* |
||||
* (This text will probably go into some docs at some time; for now, it |
||||
* is kept here to explain some definitions in the TT_Size_Metrics |
||||
* record). |
||||
* |
||||
* The CVT is a one-dimensional array containing values that control |
||||
* certain important characteristics in a font, like the height of all |
||||
* capitals, all lowercase letter, default spacing or stem width/height. |
||||
* |
||||
* These values are found in FUnits in the font file, and must be scaled |
||||
* to pixel coordinates before being used by the CVT and glyph programs. |
||||
* Unfortunately, when using distinct x and y resolutions (or distinct x |
||||
* and y pointsizes), there are two possible scalings. |
||||
* |
||||
* A first try was to implement a `lazy' scheme where all values were |
||||
* scaled when first used. However, while some values are always used |
||||
* in the same direction, some others are used under many different |
||||
* circumstances and orientations. |
||||
* |
||||
* I have found a simpler way to do the same, and it even seems to work |
||||
* in most of the cases: |
||||
* |
||||
* - All CVT values are scaled to the maximum ppem size. |
||||
* |
||||
* - When performing a read or write in the CVT, a ratio factor is used |
||||
* to perform adequate scaling. Example: |
||||
* |
||||
* x_ppem = 14 |
||||
* y_ppem = 10 |
||||
* |
||||
* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt |
||||
* entries are scaled to it. |
||||
* |
||||
* x_ratio = 1.0 |
||||
* y_ratio = y_ppem/ppem (< 1.0) |
||||
* |
||||
* We compute the current ratio like: |
||||
* |
||||
* - If projVector is horizontal, |
||||
* ratio = x_ratio = 1.0 |
||||
* |
||||
* - if projVector is vertical, |
||||
* ratio = y_ratio |
||||
* |
||||
* - else, |
||||
* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) |
||||
* |
||||
* Reading a cvt value returns |
||||
* ratio * cvt[index] |
||||
* |
||||
* Writing a cvt value in pixels: |
||||
* cvt[index] / ratio |
||||
* |
||||
* The current ppem is simply |
||||
* ratio * ppem |
||||
* |
||||
*/ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Metrics used by the TrueType size and context objects. |
||||
*/ |
||||
typedef struct TT_Size_Metrics_ |
||||
{ |
||||
/* for non-square pixels */ |
||||
FT_Long x_ratio; |
||||
FT_Long y_ratio; |
||||
|
||||
FT_UShort ppem; /* maximum ppem size */ |
||||
FT_Long ratio; /* current ratio */ |
||||
FT_Fixed scale; |
||||
|
||||
FT_F26Dot6 compensations[4]; /* device-specific compensations */ |
||||
|
||||
FT_Bool valid; |
||||
|
||||
FT_Bool rotated; /* `is the glyph rotated?'-flag */ |
||||
FT_Bool stretched; /* `is the glyph stretched?'-flag */ |
||||
|
||||
} TT_Size_Metrics; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* TrueType size class. |
||||
*/ |
||||
typedef struct TT_SizeRec_ |
||||
{ |
||||
FT_SizeRec root; |
||||
|
||||
/* we have our own copy of metrics so that we can modify */ |
||||
/* it without affecting auto-hinting (when used) */ |
||||
FT_Size_Metrics* metrics; /* for the current rendering mode */ |
||||
FT_Size_Metrics hinted_metrics; /* for the hinted rendering mode */ |
||||
|
||||
TT_Size_Metrics ttmetrics; |
||||
|
||||
FT_Byte* widthp; /* glyph widths from the hdmx table */ |
||||
|
||||
FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ |
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_Long point_size; /* for the `MPS' bytecode instruction */ |
||||
|
||||
FT_UInt num_function_defs; /* number of function definitions */ |
||||
FT_UInt max_function_defs; |
||||
TT_DefArray function_defs; /* table of function definitions */ |
||||
|
||||
FT_UInt num_instruction_defs; /* number of ins. definitions */ |
||||
FT_UInt max_instruction_defs; |
||||
TT_DefArray instruction_defs; /* table of ins. definitions */ |
||||
|
||||
FT_UInt max_func; |
||||
FT_UInt max_ins; |
||||
|
||||
TT_CodeRangeTable codeRangeTable; |
||||
|
||||
TT_GraphicsState GS; |
||||
|
||||
FT_ULong cvt_size; /* the scaled control value table */ |
||||
FT_Long* cvt; |
||||
|
||||
FT_UShort storage_size; /* The storage area is now part of */ |
||||
FT_Long* storage; /* the instance */ |
||||
|
||||
TT_GlyphZoneRec twilight; /* The instance's twilight zone */ |
||||
|
||||
TT_ExecContext context; |
||||
|
||||
/* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */ |
||||
/* otherwise it is the returned error code */ |
||||
FT_Error bytecode_ready; |
||||
FT_Error cvt_ready; |
||||
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
} TT_SizeRec; |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* TrueType driver class. |
||||
*/ |
||||
typedef struct TT_DriverRec_ |
||||
{ |
||||
FT_DriverRec root; |
||||
|
||||
TT_GlyphZoneRec zone; /* glyph loader points zone */ |
||||
|
||||
FT_UInt interpreter_version; |
||||
|
||||
} TT_DriverRec; |
||||
|
||||
|
||||
/* Note: All of the functions below (except tt_size_reset()) are used */ |
||||
/* as function pointers in a FT_Driver_ClassRec. Therefore their */ |
||||
/* parameters are of types FT_Face, FT_Size, etc., rather than TT_Face, */ |
||||
/* TT_Size, etc., so that the compiler can confirm that the types and */ |
||||
/* number of parameters are correct. In all cases the FT_xxx types are */ |
||||
/* cast to their TT_xxx counterparts inside the functions since FreeType */ |
||||
/* will always use the TT driver to create them. */ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Face functions |
||||
*/ |
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_init( FT_Stream stream, |
||||
FT_Face ttface, /* TT_Face */ |
||||
FT_Int face_index, |
||||
FT_Int num_params, |
||||
FT_Parameter* params ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_face_done( FT_Face ttface ); /* TT_Face */ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Size functions |
||||
*/ |
||||
FT_LOCAL( FT_Error ) |
||||
tt_size_init( FT_Size ttsize ); /* TT_Size */ |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_size_done( FT_Size ttsize ); /* TT_Size */ |
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_size_run_fpgm( TT_Size size, |
||||
FT_Bool pedantic ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_size_run_prep( TT_Size size, |
||||
FT_Bool pedantic ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_size_ready_bytecode( TT_Size size, |
||||
FT_Bool pedantic ); |
||||
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_size_reset_height( FT_Size size ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_size_reset( TT_Size size ); |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Driver functions |
||||
*/ |
||||
FT_LOCAL( FT_Error ) |
||||
tt_driver_init( FT_Module ttdriver ); /* TT_Driver */ |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_driver_done( FT_Module ttdriver ); /* TT_Driver */ |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Slot functions |
||||
*/ |
||||
FT_LOCAL( FT_Error ) |
||||
tt_slot_init( FT_GlyphSlot slot ); |
||||
|
||||
|
||||
/* auxiliary */ |
||||
#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* TTOBJS_H_ */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,665 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttpload.c |
||||
* |
||||
* TrueType-specific tables loader (body). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.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/ftobjs.h> |
||||
#include <freetype/internal/ftstream.h> |
||||
#include <freetype/tttags.h> |
||||
|
||||
#include "ttpload.h" |
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
#include "ttgxvar.h" |
||||
#endif |
||||
|
||||
#include "tterrors.h" |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit |
||||
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
||||
* messages during execution. |
||||
*/ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT ttpload |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_face_load_loca |
||||
* |
||||
* @Description: |
||||
* Load the locations table. |
||||
* |
||||
* @InOut: |
||||
* face :: |
||||
* A handle to the target face object. |
||||
* |
||||
* @Input: |
||||
* stream :: |
||||
* The input stream. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
*/ |
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_load_loca( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
FT_Error error; |
||||
FT_ULong table_len; |
||||
FT_Int shift; |
||||
|
||||
|
||||
/* we need the size of the `glyf' table for malformed `loca' tables */ |
||||
error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); |
||||
|
||||
/* it is possible that a font doesn't have a glyf table at all */ |
||||
/* or its size is zero */ |
||||
if ( FT_ERR_EQ( error, Table_Missing ) ) |
||||
{ |
||||
face->glyf_len = 0; |
||||
face->glyf_offset = 0; |
||||
} |
||||
else if ( error ) |
||||
goto Exit; |
||||
else |
||||
{ |
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL |
||||
if ( face->root.internal->incremental_interface ) |
||||
face->glyf_offset = 0; |
||||
else |
||||
#endif |
||||
face->glyf_offset = FT_STREAM_POS(); |
||||
} |
||||
|
||||
FT_TRACE2(( "Locations " )); |
||||
error = face->goto_table( face, TTAG_loca, stream, &table_len ); |
||||
if ( error ) |
||||
{ |
||||
error = FT_THROW( Locations_Missing ); |
||||
goto Exit; |
||||
} |
||||
|
||||
shift = face->header.Index_To_Loc_Format != 0 ? 2 : 1; |
||||
|
||||
if ( table_len > 0x10000UL << shift ) |
||||
{ |
||||
FT_TRACE2(( "table too large\n" )); |
||||
table_len = 0x10000UL << shift; |
||||
} |
||||
|
||||
face->num_locations = table_len >> shift; |
||||
|
||||
if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 ) |
||||
{ |
||||
FT_TRACE2(( "glyph count mismatch! loca: %ld, maxp: %ld\n", |
||||
face->num_locations - 1, face->root.num_glyphs )); |
||||
|
||||
/* we only handle the case where `maxp' gives a larger value */ |
||||
if ( face->num_locations < (FT_ULong)face->root.num_glyphs + 1 ) |
||||
{ |
||||
FT_ULong new_loca_len = |
||||
( (FT_ULong)face->root.num_glyphs + 1 ) << shift; |
||||
|
||||
TT_Table entry = face->dir_tables; |
||||
TT_Table limit = entry + face->num_tables; |
||||
|
||||
FT_Long pos = (FT_Long)FT_STREAM_POS(); |
||||
FT_Long dist = 0x7FFFFFFFL; |
||||
FT_Bool found = 0; |
||||
|
||||
|
||||
/* compute the distance to next table in font file */ |
||||
for ( ; entry < limit; entry++ ) |
||||
{ |
||||
FT_Long diff = (FT_Long)entry->Offset - pos; |
||||
|
||||
|
||||
if ( diff > 0 && diff < dist ) |
||||
{ |
||||
dist = diff; |
||||
found = 1; |
||||
} |
||||
} |
||||
|
||||
if ( !found ) |
||||
{ |
||||
/* `loca' is the last table */ |
||||
dist = (FT_Long)stream->size - pos; |
||||
} |
||||
|
||||
if ( new_loca_len <= (FT_ULong)dist ) |
||||
{ |
||||
face->num_locations = (FT_ULong)face->root.num_glyphs + 1; |
||||
table_len = new_loca_len; |
||||
|
||||
FT_TRACE2(( "adjusting num_locations to %ld\n", |
||||
face->num_locations )); |
||||
} |
||||
else |
||||
{ |
||||
face->root.num_glyphs = face->num_locations |
||||
? (FT_Long)face->num_locations - 1 : 0; |
||||
|
||||
FT_TRACE2(( "adjusting num_glyphs to %ld\n", |
||||
face->root.num_glyphs )); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* Extract the frame. We don't need to decompress it since |
||||
* we are able to parse it directly. |
||||
*/ |
||||
if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) |
||||
goto Exit; |
||||
|
||||
FT_TRACE2(( "loaded\n" )); |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_ULong ) |
||||
tt_face_get_location( FT_Face face, /* TT_Face */ |
||||
FT_UInt gindex, |
||||
FT_ULong *asize ) |
||||
{ |
||||
TT_Face ttface = (TT_Face)face; |
||||
FT_ULong pos1, pos2; |
||||
FT_Byte* p; |
||||
FT_Byte* p_limit; |
||||
|
||||
|
||||
pos1 = pos2 = 0; |
||||
|
||||
if ( gindex < ttface->num_locations ) |
||||
{ |
||||
if ( ttface->header.Index_To_Loc_Format != 0 ) |
||||
{ |
||||
p = ttface->glyph_locations + gindex * 4; |
||||
p_limit = ttface->glyph_locations + ttface->num_locations * 4; |
||||
|
||||
pos1 = FT_NEXT_ULONG( p ); |
||||
pos2 = pos1; |
||||
|
||||
if ( p + 4 <= p_limit ) |
||||
pos2 = FT_NEXT_ULONG( p ); |
||||
} |
||||
else |
||||
{ |
||||
p = ttface->glyph_locations + gindex * 2; |
||||
p_limit = ttface->glyph_locations + ttface->num_locations * 2; |
||||
|
||||
pos1 = FT_NEXT_USHORT( p ); |
||||
pos2 = pos1; |
||||
|
||||
if ( p + 2 <= p_limit ) |
||||
pos2 = FT_NEXT_USHORT( p ); |
||||
|
||||
pos1 <<= 1; |
||||
pos2 <<= 1; |
||||
} |
||||
} |
||||
|
||||
/* Check broken location data. */ |
||||
if ( pos1 > ttface->glyf_len ) |
||||
{ |
||||
FT_TRACE1(( "tt_face_get_location:" |
||||
" too large offset (0x%08lx) found for glyph index %d,\n", |
||||
pos1, gindex )); |
||||
FT_TRACE1(( " " |
||||
" exceeding the end of `glyf' table (0x%08lx)\n", |
||||
ttface->glyf_len )); |
||||
*asize = 0; |
||||
return 0; |
||||
} |
||||
|
||||
if ( pos2 > ttface->glyf_len ) |
||||
{ |
||||
/* We try to sanitize the last `loca' entry. */ |
||||
if ( gindex == ttface->num_locations - 2 ) |
||||
{ |
||||
FT_TRACE1(( "tt_face_get_location:" |
||||
" too large size (%ld bytes) found for glyph index %d,\n", |
||||
pos2 - pos1, gindex )); |
||||
FT_TRACE1(( " " |
||||
" truncating at the end of `glyf' table to %ld bytes\n", |
||||
ttface->glyf_len - pos1 )); |
||||
pos2 = ttface->glyf_len; |
||||
} |
||||
else |
||||
{ |
||||
FT_TRACE1(( "tt_face_get_location:" |
||||
" too large offset (0x%08lx) found for glyph index %d,\n", |
||||
pos2, gindex + 1 )); |
||||
FT_TRACE1(( " " |
||||
" exceeding the end of `glyf' table (0x%08lx)\n", |
||||
ttface->glyf_len )); |
||||
*asize = 0; |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
/* The `loca' table must be ordered; it refers to the length of */ |
||||
/* an entry as the difference between the current and the next */ |
||||
/* position. However, there do exist (malformed) fonts which */ |
||||
/* don't obey this rule, so we are only able to provide an */ |
||||
/* upper bound for the size. */ |
||||
/* */ |
||||
/* We get (intentionally) a wrong, non-zero result in case the */ |
||||
/* `glyf' table is missing. */ |
||||
if ( pos2 >= pos1 ) |
||||
*asize = (FT_ULong)( pos2 - pos1 ); |
||||
else |
||||
*asize = (FT_ULong)( ttface->glyf_len - pos1 ); |
||||
|
||||
return pos1; |
||||
} |
||||
|
||||
|
||||
FT_LOCAL_DEF( void ) |
||||
tt_face_done_loca( TT_Face face ) |
||||
{ |
||||
FT_Stream stream = face->root.stream; |
||||
|
||||
|
||||
FT_FRAME_RELEASE( face->glyph_locations ); |
||||
face->num_locations = 0; |
||||
} |
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_face_load_cvt |
||||
* |
||||
* @Description: |
||||
* Load the control value table into a face object. |
||||
* |
||||
* @InOut: |
||||
* face :: |
||||
* A handle to the target face object. |
||||
* |
||||
* @Input: |
||||
* stream :: |
||||
* A handle to the input stream. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
*/ |
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_load_cvt( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_Error error; |
||||
FT_Memory memory = stream->memory; |
||||
FT_ULong table_len; |
||||
|
||||
|
||||
FT_TRACE2(( "CVT " )); |
||||
|
||||
error = face->goto_table( face, TTAG_cvt, stream, &table_len ); |
||||
if ( error ) |
||||
{ |
||||
FT_TRACE2(( "is missing\n" )); |
||||
|
||||
face->cvt_size = 0; |
||||
face->cvt = NULL; |
||||
error = FT_Err_Ok; |
||||
|
||||
goto Exit; |
||||
} |
||||
|
||||
face->cvt_size = table_len / 2; |
||||
|
||||
if ( FT_QNEW_ARRAY( face->cvt, face->cvt_size ) ) |
||||
goto Exit; |
||||
|
||||
if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) |
||||
goto Exit; |
||||
|
||||
{ |
||||
FT_Int32* cur = face->cvt; |
||||
FT_Int32* limit = cur + face->cvt_size; |
||||
|
||||
|
||||
for ( ; cur < limit; cur++ ) |
||||
*cur = FT_GET_SHORT() * 64; |
||||
} |
||||
|
||||
FT_FRAME_EXIT(); |
||||
FT_TRACE2(( "loaded\n" )); |
||||
|
||||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||||
if ( face->doblend ) |
||||
error = tt_face_vary_cvt( face, stream ); |
||||
#endif |
||||
|
||||
Exit: |
||||
return error; |
||||
|
||||
#else /* !TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
FT_UNUSED( face ); |
||||
FT_UNUSED( stream ); |
||||
|
||||
return FT_Err_Ok; |
||||
|
||||
#endif |
||||
} |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_face_load_fpgm |
||||
* |
||||
* @Description: |
||||
* Load the font program. |
||||
* |
||||
* @InOut: |
||||
* face :: |
||||
* A handle to the target face object. |
||||
* |
||||
* @Input: |
||||
* stream :: |
||||
* A handle to the input stream. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
*/ |
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_load_fpgm( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_Error error; |
||||
FT_ULong table_len; |
||||
|
||||
|
||||
FT_TRACE2(( "Font program " )); |
||||
|
||||
/* The font program is optional */ |
||||
error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); |
||||
if ( error ) |
||||
{ |
||||
face->font_program = NULL; |
||||
face->font_program_size = 0; |
||||
error = FT_Err_Ok; |
||||
|
||||
FT_TRACE2(( "is missing\n" )); |
||||
} |
||||
else |
||||
{ |
||||
face->font_program_size = table_len; |
||||
if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) |
||||
goto Exit; |
||||
|
||||
FT_TRACE2(( "loaded, %12ld bytes\n", face->font_program_size )); |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
|
||||
#else /* !TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
FT_UNUSED( face ); |
||||
FT_UNUSED( stream ); |
||||
|
||||
return FT_Err_Ok; |
||||
|
||||
#endif |
||||
} |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_face_load_prep |
||||
* |
||||
* @Description: |
||||
* Load the cvt program. |
||||
* |
||||
* @InOut: |
||||
* face :: |
||||
* A handle to the target face object. |
||||
* |
||||
* @Input: |
||||
* stream :: |
||||
* A handle to the input stream. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
*/ |
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_load_prep( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
#ifdef TT_USE_BYTECODE_INTERPRETER |
||||
|
||||
FT_Error error; |
||||
FT_ULong table_len; |
||||
|
||||
|
||||
FT_TRACE2(( "Prep program " )); |
||||
|
||||
error = face->goto_table( face, TTAG_prep, stream, &table_len ); |
||||
if ( error ) |
||||
{ |
||||
face->cvt_program = NULL; |
||||
face->cvt_program_size = 0; |
||||
error = FT_Err_Ok; |
||||
|
||||
FT_TRACE2(( "is missing\n" )); |
||||
} |
||||
else |
||||
{ |
||||
face->cvt_program_size = table_len; |
||||
if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) |
||||
goto Exit; |
||||
|
||||
FT_TRACE2(( "loaded, %12ld bytes\n", face->cvt_program_size )); |
||||
} |
||||
|
||||
Exit: |
||||
return error; |
||||
|
||||
#else /* !TT_USE_BYTECODE_INTERPRETER */ |
||||
|
||||
FT_UNUSED( face ); |
||||
FT_UNUSED( stream ); |
||||
|
||||
return FT_Err_Ok; |
||||
|
||||
#endif |
||||
} |
||||
|
||||
|
||||
FT_COMPARE_DEF( int ) |
||||
compare_ppem( const void* a, |
||||
const void* b ) |
||||
{ |
||||
return **(FT_Byte**)a - **(FT_Byte**)b; |
||||
} |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* @Function: |
||||
* tt_face_load_hdmx |
||||
* |
||||
* @Description: |
||||
* Load the `hdmx' table into the face object. |
||||
* |
||||
* @Input: |
||||
* face :: |
||||
* A handle to the target face object. |
||||
* |
||||
* stream :: |
||||
* A handle to the input stream. |
||||
* |
||||
* @Return: |
||||
* FreeType error code. 0 means success. |
||||
*/ |
||||
|
||||
FT_LOCAL_DEF( FT_Error ) |
||||
tt_face_load_hdmx( TT_Face face, |
||||
FT_Stream stream ) |
||||
{ |
||||
FT_Error error; |
||||
FT_Memory memory = stream->memory; |
||||
FT_UInt nn, num_records; |
||||
FT_ULong table_size, record_size; |
||||
FT_Byte* p; |
||||
FT_Byte* limit; |
||||
|
||||
|
||||
/* this table is optional */ |
||||
error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); |
||||
if ( error || table_size < 8 ) |
||||
return FT_Err_Ok; |
||||
|
||||
if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) |
||||
goto Exit; |
||||
|
||||
p = face->hdmx_table; |
||||
limit = p + table_size; |
||||
|
||||
/* Given that `hdmx' tables are losing its importance (for example, */ |
||||
/* variation fonts introduced in OpenType 1.8 must not have this */ |
||||
/* table) we no longer test for a correct `version' field. */ |
||||
p += 2; |
||||
num_records = FT_NEXT_USHORT( p ); |
||||
record_size = FT_NEXT_ULONG( p ); |
||||
|
||||
/* There are at least two fonts, HANNOM-A and HANNOM-B version */ |
||||
/* 2.0 (2005), which get this wrong: The upper two bytes of */ |
||||
/* the size value are set to 0xFF instead of 0x00. We catch */ |
||||
/* and fix this. */ |
||||
|
||||
if ( record_size >= 0xFFFF0000UL ) |
||||
record_size &= 0xFFFFU; |
||||
|
||||
FT_TRACE2(( "Hdmx " )); |
||||
|
||||
/* The limit for `num_records' is a heuristic value. */ |
||||
if ( num_records > 255 || num_records == 0 ) |
||||
{ |
||||
FT_TRACE2(( "with unreasonable %u records rejected\n", num_records )); |
||||
goto Fail; |
||||
} |
||||
|
||||
/* Out-of-spec tables are rejected. The record size must be */ |
||||
/* equal to the number of glyphs + 2 + 32-bit padding. */ |
||||
if ( (FT_Long)record_size != ( ( face->root.num_glyphs + 2 + 3 ) & ~3 ) ) |
||||
{ |
||||
FT_TRACE2(( "with record size off by %ld bytes rejected\n", |
||||
(FT_Long)record_size - |
||||
( ( face->root.num_glyphs + 2 + 3 ) & ~3 ) )); |
||||
goto Fail; |
||||
} |
||||
|
||||
if ( FT_QNEW_ARRAY( face->hdmx_records, num_records ) ) |
||||
goto Fail; |
||||
|
||||
for ( nn = 0; nn < num_records; nn++ ) |
||||
{ |
||||
if ( p + record_size > limit ) |
||||
break; |
||||
face->hdmx_records[nn] = p; |
||||
p += record_size; |
||||
} |
||||
|
||||
/* The records must be already sorted by ppem but it does not */ |
||||
/* hurt to make sure so that the binary search works later. */ |
||||
ft_qsort( face->hdmx_records, nn, sizeof ( FT_Byte* ), compare_ppem ); |
||||
|
||||
face->hdmx_record_count = nn; |
||||
face->hdmx_table_size = table_size; |
||||
face->hdmx_record_size = record_size; |
||||
|
||||
FT_TRACE2(( "%ux%lu loaded\n", num_records, record_size )); |
||||
|
||||
Exit: |
||||
return error; |
||||
|
||||
Fail: |
||||
FT_FRAME_RELEASE( face->hdmx_table ); |
||||
face->hdmx_table_size = 0; |
||||
goto Exit; |
||||
} |
||||
|
||||
|
||||
FT_LOCAL_DEF( void ) |
||||
tt_face_free_hdmx( TT_Face face ) |
||||
{ |
||||
FT_Stream stream = face->root.stream; |
||||
FT_Memory memory = stream->memory; |
||||
|
||||
|
||||
FT_FREE( face->hdmx_records ); |
||||
FT_FRAME_RELEASE( face->hdmx_table ); |
||||
} |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* Return the advance width table for a given pixel size if it is found |
||||
* in the font's `hdmx' table (if any). The records must be sorted for |
||||
* the binary search to work properly. |
||||
*/ |
||||
FT_LOCAL_DEF( FT_Byte* ) |
||||
tt_face_get_device_metrics( TT_Face face, |
||||
FT_UInt ppem, |
||||
FT_UInt gindex ) |
||||
{ |
||||
FT_UInt min = 0; |
||||
FT_UInt max = face->hdmx_record_count; |
||||
FT_UInt mid; |
||||
FT_Byte* result = NULL; |
||||
|
||||
|
||||
while ( min < max ) |
||||
{ |
||||
mid = ( min + max ) >> 1; |
||||
|
||||
if ( face->hdmx_records[mid][0] > ppem ) |
||||
max = mid; |
||||
else if ( face->hdmx_records[mid][0] < ppem ) |
||||
min = mid + 1; |
||||
else |
||||
{ |
||||
result = face->hdmx_records[mid] + 2 + gindex; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,74 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* ttpload.h |
||||
* |
||||
* TrueType-specific tables loader (specification). |
||||
* |
||||
* Copyright (C) 1996-2023 by |
||||
* David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* This file is part of the FreeType project, and may only be used, |
||||
* modified, and distributed under the terms of the FreeType project |
||||
* license, LICENSE.TXT. By continuing to use, modify, or distribute |
||||
* this file you indicate that you have read the license and |
||||
* understand and accept it fully. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef TTPLOAD_H_ |
||||
#define TTPLOAD_H_ |
||||
|
||||
|
||||
#include <freetype/internal/tttypes.h> |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_load_loca( TT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
FT_LOCAL( FT_ULong ) |
||||
tt_face_get_location( FT_Face face, |
||||
FT_UInt gindex, |
||||
FT_ULong *asize ); |
||||
|
||||
FT_LOCAL( void ) |
||||
tt_face_done_loca( TT_Face face ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_load_cvt( TT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_load_fpgm( TT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_load_prep( TT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
tt_face_load_hdmx( TT_Face face, |
||||
FT_Stream stream ); |
||||
|
||||
|
||||
FT_LOCAL( void ) |
||||
tt_face_free_hdmx( TT_Face face ); |
||||
|
||||
|
||||
FT_LOCAL( FT_Byte* ) |
||||
tt_face_get_device_metrics( TT_Face face, |
||||
FT_UInt ppem, |
||||
FT_UInt gindex ); |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* TTPLOAD_H_ */ |
||||
|
||||
|
||||
/* END */ |
Loading…
Reference in new issue