1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* cffobjs.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* OpenType objects manager (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftcalc.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/fterrors.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ttnameid.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/tttags.h" 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/sfnt.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftcffdrv.h" 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffobjs.h" 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffload.h" 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffcmap.h" 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffpic.h" 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfferrs.h" 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_cffobjs 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SIZE FUNCTIONS */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that we store the global hints in the size's `internal' root */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* field. */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static PSH_Globals_Funcs 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_size_get_globals_funcs( CFF_Size size ) 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)size->root.face; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font font = (CFF_Font)face->extra.data; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSHinter_Service pshinter = font->pshinter; 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module; 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module = FT_Get_Module( size->root.face->driver->root.library, 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "pshinter" ); 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ( module && pshinter && pshinter->get_globals_funcs ) 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ? pshinter->get_globals_funcs( module ) 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : 0; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_size_done( FT_Size cffsize ) /* CFF_Size */ 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Size size = (CFF_Size)cffsize; 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)size->root.face; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font font = (CFF_Font)face->extra.data; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Internal internal = (CFF_Internal)cffsize->internal; 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( internal ) 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSH_Globals_Funcs funcs; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs = cff_size_get_globals_funcs( size ); 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( funcs ) 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs->destroy( internal->topfont ); 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = font->num_subfonts; i > 0; i-- ) 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs->destroy( internal->subfonts[i - 1] ); 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `internal' is freed by destroy_size (in ftobjs.c) */ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* CFF and Type 1 private dictionaries have slightly different */ 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* structures; we need to synthesize a Type 1 dictionary on the fly */ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_make_private_dict( CFF_SubFont subfont, 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PS_Private priv ) 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Private cpriv = &subfont->private_dict; 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n, count; 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( priv, sizeof ( *priv ) ); 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = priv->num_blue_values = cpriv->num_blue_values; 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++ ) 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = priv->num_other_blues = cpriv->num_other_blues; 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++ ) 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = priv->num_family_blues = cpriv->num_family_blues; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++ ) 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = priv->num_family_other_blues = cpriv->num_family_other_blues; 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++ ) 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->blue_scale = cpriv->blue_scale; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->blue_shift = (FT_Int)cpriv->blue_shift; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->standard_width[0] = (FT_UShort)cpriv->standard_width; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->standard_height[0] = (FT_UShort)cpriv->standard_height; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = priv->num_snap_widths = cpriv->num_snap_widths; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++ ) 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = priv->num_snap_heights = cpriv->num_snap_heights; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++ ) 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->force_bold = cpriv->force_bold; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->language_group = cpriv->language_group; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov priv->lenIV = cpriv->lenIV; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_size_init( FT_Size cffsize ) /* CFF_Size */ 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Size size = (CFF_Size)cffsize; 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( funcs ) 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)cffsize->face; 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font font = (CFF_Font)face->extra.data; 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Internal internal = NULL; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PS_PrivateRec priv; 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = cffsize->face->memory; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( internal ) ) 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_make_private_dict( &font->top_font, &priv ); 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = funcs->create( cffsize->face->memory, &priv, 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &internal->topfont ); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = font->num_subfonts; i > 0; i-- ) 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_SubFont sub = font->subfonts[i - 1]; 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_make_private_dict( sub, &priv ); 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = funcs->create( cffsize->face->memory, &priv, 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &internal->subfonts[i - 1] ); 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffsize->internal = (FT_Size_Internal)(void*)internal; 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size->strike_index = 0xFFFFFFFFUL; 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_size_select( FT_Size size, 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index ) 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Size cffsize = (CFF_Size)size; 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSH_Globals_Funcs funcs; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffsize->strike_index = strike_index; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Select_Metrics( size->face, strike_index ); 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs = cff_size_get_globals_funcs( cffsize ); 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( funcs ) 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)size->face; 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font font = (CFF_Font)face->extra.data; 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Internal internal = (CFF_Internal)size->internal; 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong top_upm = font->top_font.font_dict.units_per_em; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs->set_scale( internal->topfont, 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size->metrics.x_scale, size->metrics.y_scale, 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0 ); 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = font->num_subfonts; i > 0; i-- ) 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_SubFont sub = font->subfonts[i - 1]; 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong sub_upm = sub->font_dict.units_per_em; 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos x_scale, y_scale; 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( top_upm != sub_upm ) 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_scale = size->metrics.x_scale; 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_scale = size->metrics.y_scale; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs->set_scale( internal->subfonts[i - 1], 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_scale, y_scale, 0, 0 ); 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_size_request( FT_Size size, 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Size_Request req ) 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Size cffsize = (CFF_Size)size; 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSH_Globals_Funcs funcs; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_HAS_FIXED_SIZES( size->face ) ) 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face cffface = (CFF_Face)size->face; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong strike_index; 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) ) 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffsize->strike_index = 0xFFFFFFFFUL; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cff_size_select( size, strike_index ); 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Request_Metrics( size->face, req ); 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs = cff_size_get_globals_funcs( cffsize ); 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( funcs ) 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face cffface = (CFF_Face)size->face; 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font font = (CFF_Font)cffface->extra.data; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Internal internal = (CFF_Internal)size->internal; 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong top_upm = font->top_font.font_dict.units_per_em; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs->set_scale( internal->topfont, 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size->metrics.x_scale, size->metrics.y_scale, 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 0 ); 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = font->num_subfonts; i > 0; i-- ) 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_SubFont sub = font->subfonts[i - 1]; 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong sub_upm = sub->font_dict.units_per_em; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pos x_scale, y_scale; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( top_upm != sub_upm ) 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_scale = size->metrics.x_scale; 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_scale = size->metrics.y_scale; 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs->set_scale( internal->subfonts[i - 1], 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x_scale, y_scale, 0, 0 ); 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SLOT FUNCTIONS */ 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_slot_done( FT_GlyphSlot slot ) 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->internal->glyph_hints = 0; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_slot_init( FT_GlyphSlot slot ) 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)slot->face; 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font font = (CFF_Font)face->extra.data; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSHinter_Service pshinter = font->pshinter; 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pshinter ) 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Module module; 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov module = FT_Get_Module( slot->face->driver->root.library, 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "pshinter" ); 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( module ) 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T2_Hints_Funcs funcs; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov funcs = pshinter->get_t2_funcs( module ); 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov slot->internal->glyph_hints = (void*)funcs; 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FACE FUNCTIONS */ 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_String* 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_strcpy( FT_Memory memory, 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* source ) 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_String* result; 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (void)FT_STRDUP( result, source ); 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( error ); 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */ 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */ 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* have been seen in the wild. */ 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov remove_subset_prefix( FT_String* name ) 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 idx = 0; 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 length = (FT_Int32)strlen( name ) + 1; 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool continue_search = 1; 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( continue_search ) 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length >= 7 && name[6] == '+' ) 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( idx = 0; idx < 6; idx++ ) 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ASCII uppercase letters */ 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) ) 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue_search = 0; 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( continue_search ) 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( idx = 7; idx < length; idx++ ) 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov name[idx - 7] = name[idx]; 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length -= 7; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue_search = 0; 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Remove the style part from the family name (if present). */ 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov remove_style( FT_String* family_name, 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_String* style_name ) 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 family_name_length, style_name_length; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family_name_length = (FT_Int32)strlen( family_name ); 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov style_name_length = (FT_Int32)strlen( style_name ); 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( family_name_length > style_name_length ) 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int idx; 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( idx = 1; idx <= style_name_length; ++idx ) 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( family_name[family_name_length - idx] != 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov style_name[style_name_length - idx] ) 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx > style_name_length ) 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* family_name ends with style_name; remove it */ 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = family_name_length - style_name_length - 1; 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* also remove special characters */ 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* between real family name and style */ 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( idx > 0 && 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( family_name[idx] == '-' || 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family_name[idx] == ' ' || 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family_name[idx] == '_' || 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family_name[idx] == '+' ) ) 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov --idx; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx > 0 ) 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family_name[idx + 1] = '\0'; 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_face_init( FT_Stream stream, 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face cffface, /* CFF_Face */ 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int face_index, 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int num_params, 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Parameter* params ) 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)cffface; 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SFNT_Service sfnt; 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Service_PsCMaps psnames; 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSHinter_Service pshinter; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool pure_cff = 1; 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool sfnt_format = 0; 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = cffface->driver->root.library; 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt = (SFNT_Service)FT_Get_Module_Interface( 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library, "sfnt" ); 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !sfnt ) 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" )); 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Missing_Module ); 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pshinter = (PSHinter_Service)FT_Get_Module_Interface( 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov library, "pshinter" ); 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( "CFF driver\n" )); 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create input stream from resource */ 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( 0 ) ) 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether we have a valid OpenType file */ 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = sfnt->init_face( stream, face, face_index, num_params, params ); 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->format_tag != TTAG_OTTO && 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->format_tag != 0x00010000UL ) /* `OTTO'; OpenType/CFF font */ 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( " not an OpenType/CFF font\n" )); 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Unknown_File_Format ); 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if we are performing a simple font format check, exit immediately */ 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index < 0 ) 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt_format = 1; 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* font; in the latter case it doesn't have a `head' table */ 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_head, stream, 0 ); 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pure_cff = 0; 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* load font directory */ 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = sfnt->load_face( stream, face, face_index, 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_params, params ); 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* load the `cmap' table explicitly */ 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = sfnt->load_cmap( face, stream ); 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now load the CFF part of the file */ 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = face->goto_table( face, TTAG_CFF, stream, 0 ); 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rewind to start of file; we are going to load a pure-CFF font */ 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( 0 ) ) 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now load and parse the CFF table in the file */ 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font cff = NULL; 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict dict; 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = cffface->memory; 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 flags; 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( cff ) ) 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->extra.data = cff; 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = cff_font_load( library, stream, face_index, cff, pure_cff ); 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff->pshinter = pshinter; 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff->psnames = psnames; 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->face_index = face_index; 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Complement the root flags with some interesting information. */ 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that this is only necessary for pure CFF and CEF fonts; */ 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SFNT based fonts use the `name' table instead. */ 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->num_glyphs = cff->num_glyphs; 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict = &cff->top_font.font_dict; 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need the `PSNames' module for CFF and CEF formats */ 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* which aren't CID-keyed */ 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->cid_registry == 0xFFFFU && !psnames ) 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "cff_face_init:" 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " cannot open CFF & CEF fonts\n" 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " " 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " without the `PSNames' module\n" )); 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Missing_Module ); 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx; 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_String* s; 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4(( "SIDs\n" )); 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dump string index, including default strings for convenience */ 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( idx = 0; idx < cff->num_strings + 390; idx++ ) 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov s = cff_index_get_sid_string( cff, idx ); 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( s ) 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE4((" %5d %s\n", idx, s )); 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !dict->has_font_matrix ) 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Normalize the font matrix so that `matrix->xx' is 1; the */ 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* scaling is done with `units_per_em' then (at this point, */ 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it already contains the scaling factor, but without */ 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* normalization of the matrix). */ 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that the offsets must be expressed in integer font */ 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* units. */ 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix* matrix = &dict->font_matrix; 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* offset = &dict->font_offset; 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* upm = &dict->units_per_em; 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed temp = FT_ABS( matrix->yy ); 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( temp != 0x10000L ) 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *upm = FT_DivFix( *upm, temp ); 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xx = FT_DivFix( matrix->xx, temp ); 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yx = FT_DivFix( matrix->yx, temp ); 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xy = FT_DivFix( matrix->xy, temp ); 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yy = FT_DivFix( matrix->yy, temp ); 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x = FT_DivFix( offset->x, temp ); 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y = FT_DivFix( offset->y, temp ); 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x >>= 16; 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y >>= 16; 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = cff->num_subfonts; i > 0; i-- ) 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_FontRecDict top = &cff->top_font.font_dict; 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix* matrix; 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* offset; 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* upm; 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed temp; 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sub->has_font_matrix ) 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long scaling; 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if we have a top-level matrix, */ 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* concatenate the subfont matrix */ 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( top->has_font_matrix ) 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( top->units_per_em > 1 && sub->units_per_em > 1 ) 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaling = FT_MIN( top->units_per_em, sub->units_per_em ); 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaling = 1; 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix_Multiply_Scaled( &top->font_matrix, 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &sub->font_matrix, 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaling ); 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector_Transform_Scaled( &sub->font_offset, 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &top->font_matrix, 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaling ); 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub->units_per_em = FT_MulDiv( sub->units_per_em, 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top->units_per_em, 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scaling ); 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub->font_matrix = top->font_matrix; 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub->font_offset = top->font_offset; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub->units_per_em = top->units_per_em; 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix = &sub->font_matrix; 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = &sub->font_offset; 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upm = &sub->units_per_em; 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp = FT_ABS( matrix->yy ); 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( temp != 0x10000L ) 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *upm = FT_DivFix( *upm, temp ); 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xx = FT_DivFix( matrix->xx, temp ); 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yx = FT_DivFix( matrix->yx, temp ); 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xy = FT_DivFix( matrix->xy, temp ); 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yy = FT_DivFix( matrix->yy, temp ); 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x = FT_DivFix( offset->x, temp ); 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y = FT_DivFix( offset->y, temp ); 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x >>= 16; 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y >>= 16; 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pure_cff ) 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* style_name = NULL; 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set up num_faces */ 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->num_faces = cff->num_faces; 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute number of glyphs */ 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->cid_registry != 0xFFFFU ) 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->num_glyphs = cff->charset.max_cid + 1; 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->num_glyphs = cff->charstrings_index.count; 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set global bbox, as well as EM size */ 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->bbox.xMin = dict->font_bbox.xMin >> 16; 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->bbox.yMin = dict->font_bbox.yMin >> 16; 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no `U' suffix here to 0xFFFF! */ 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->ascender = (FT_Short)( cffface->bbox.yMax ); 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->descender = (FT_Short)( cffface->bbox.yMin ); 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 ); 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cffface->height < cffface->ascender - cffface->descender ) 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->height = (FT_Short)( cffface->ascender - cffface->descender ); 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->underline_position = 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Short)( dict->underline_position >> 16 ); 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->underline_thickness = 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Short)( dict->underline_thickness >> 16 ); 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* retrieve font family & style name */ 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->family_name = cff_index_get_name( cff, face_index ); 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cffface->family_name ) 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* full = cff_index_get_sid_string( cff, 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->full_name ); 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* fullp = full; 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* family = cffface->family_name; 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* family_name = NULL; 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov remove_subset_prefix( cffface->family_name ); 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->family_name ) 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family_name = cff_index_get_sid_string( cff, 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->family_name ); 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( family_name ) 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family = family_name; 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We try to extract the style name from the full name. */ 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We need to ignore spaces and dashes during the search. */ 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( full && family ) 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( *fullp ) 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* skip common characters at the start of both strings */ 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *fullp == *family ) 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family++; 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fullp++; 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ignore spaces and dashes in full name during comparison */ 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *fullp == ' ' || *fullp == '-' ) 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fullp++; 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ignore spaces and dashes in family name during comparison */ 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *family == ' ' || *family == '-' ) 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov family++; 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !*family && *fullp ) 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The full name begins with the same characters as the */ 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* family name, with spaces and dashes removed. In this */ 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* case, the remaining string in `fullp' will be used as */ 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the style name. */ 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov style_name = cff_strcpy( memory, fullp ); 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* remove the style part from the family name (if present) */ 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov remove_style( cffface->family_name, style_name ); 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char *cid_font_name = 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_index_get_sid_string( cff, 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->cid_font_name ); 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* do we have a `/FontName' for a CID-keyed font? */ 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cid_font_name ) 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->family_name = cff_strcpy( memory, cid_font_name ); 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( style_name ) 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->style_name = style_name; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* assume "Regular" style if we don't know better */ 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*******************************************************************/ 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute face flags. */ 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FACE_FLAG_HINTER; /* has native hinter */ 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sfnt_format ) 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_FACE_FLAG_SFNT; 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* fixed width font? */ 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->is_fixed_pitch ) 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_FACE_FLAG_FIXED_WIDTH; 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* kerning available? */ 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->kern_pairs ) 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_FACE_FLAG_KERNING; 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->face_flags = flags; 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*******************************************************************/ 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute style flags. */ 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags = 0; 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->italic_angle ) 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_STYLE_FLAG_ITALIC; 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char *weight = cff_index_get_sid_string( cff, 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->weight ); 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( weight ) 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ft_strcmp( weight, "Bold" ) || 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !ft_strcmp( weight, "Black" ) ) 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_STYLE_FLAG_BOLD; 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* double check */ 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name ) 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) || 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !ft_strncmp( cffface->style_name, "Black", 5 ) ) 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_STYLE_FLAG_BOLD; 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !(flags & FT_STYLE_FLAG_ITALIC) && cffface->style_name ) 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ft_strncmp( cffface->style_name, "Italic", 6 ) ) 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= FT_STYLE_FLAG_ITALIC; 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->style_flags = flags; 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* has unset this flag because of the 3.0 `post' table. */ 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->cid_registry == 0xFFFFU ) 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dict->cid_registry != 0xFFFFU && pure_cff ) 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*******************************************************************/ 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute char maps. */ 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Try to synthesize a Unicode charmap if there is none available */ 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* already. If an OpenType font contains a Unicode "cmap", we */ 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* will use it, whatever be in the CFF part of the file. */ 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMapRec cmaprec; 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMap cmap; 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt nn; 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Encoding encoding = &cff->encoding; 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap = cffface->charmaps[nn]; 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Windows Unicode? */ 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->platform_id == TT_PLATFORM_MICROSOFT && 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->encoding_id == TT_MS_ID_UNICODE_CS ) 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Skip_Unicode; 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Apple Unicode platform id? */ 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE ) 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Skip_Unicode; /* Apple Unicode */ 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* since CID-keyed fonts don't contain glyph names, we can't */ 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* construct a cmap */ 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE ) 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "cff_face_init: no Unicode cmap is found, " 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "and too many subtables (%d) to add synthesized cmap\n", 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nn )); 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we didn't find a Unicode charmap -- synthesize one */ 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.face = cffface; 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.platform_id = TT_PLATFORM_MICROSOFT; 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding_id = TT_MS_ID_UNICODE_CS; 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding = FT_ENCODING_UNICODE; 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nn = (FT_UInt)cffface->num_charmaps; 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &cmaprec, NULL ); 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error && 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if no Unicode charmap was previously selected, select this one */ 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cffface->charmap = cffface->charmaps[nn]; 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Skip_Unicode: 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_MAX_CHARMAP_CACHEABLE 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nn > FT_MAX_CHARMAP_CACHEABLE ) 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "cff_face_init: Unicode cmap is found, " 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov "but too many preceding subtables (%d) to access\n", 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nn - 1 )); 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( encoding->count > 0 ) 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap_Class clazz; 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.face = cffface; 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.platform_id = TT_PLATFORM_ADOBE; /* Adobe platform id */ 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( encoding->offset == 0 ) 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( encoding->offset == 1 ) 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = &CFF_CMAP_ENCODING_CLASS_REC_GET; 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_CMap_New( clazz, NULL, &cmaprec, NULL ); 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_face_done( FT_Face cffface ) /* CFF_Face */ 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Face face = (CFF_Face)cffface; 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SFNT_Service sfnt; 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory = cffface->memory; 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt = (SFNT_Service)face->sfnt; 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sfnt ) 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sfnt->done_face( face ); 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Font cff = (CFF_Font)face->extra.data; 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cff ) 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_font_done( cff ); 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face->extra.data ); 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_driver_init( FT_Module module ) /* CFF_Driver */ 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFF_Driver driver = (CFF_Driver)module; 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set default property values */ 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CFF_CONFIG_OPTION_OLD_ENGINE 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver->hinting_engine = FT_CFF_HINTING_FREETYPE; 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver->hinting_engine = FT_CFF_HINTING_ADOBE; 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov driver->no_stem_darkening = FALSE; 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cff_driver_done( FT_Module module ) /* CFF_Driver */ 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( module ); 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 1083