1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* afloader.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* Auto-fitter glyph loading routines (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 7a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin/* Copyright 2003-2017 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 19727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "afglobal.h" 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "afloader.h" 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "afhints.h" 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "aferrors.h" 23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "afmodule.h" 24ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#include "afpic.h" 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 26055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#include FT_INTERNAL_CALC_H 27055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 29aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Initialize glyph loader. */ 30aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 31fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_LOCAL_DEF( void ) 32fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_loader_init( AF_Loader loader, 33fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_GlyphHints hints ) 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ZERO( loader ); 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 37fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki loader->hints = hints; 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 41aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Reset glyph loader and compute globals if necessary. */ 42aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 44fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_loader_reset( AF_Loader loader, 45fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_Module module, 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Face face ) 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 48fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Error error = FT_Err_Ok; 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->face = face; 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->globals = (AF_FaceGlobals)face->autohint.data; 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 54a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !loader->globals ) 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 56727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = af_face_globals_new( face, &loader->globals, module ); 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !error ) 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->autohint.data = 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_Pointer)loader->globals; 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->autohint.finalizer = 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_Generic_Finalizer)af_face_globals_free; 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 70aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Finalize glyph loader. */ 71aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 73fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_loader_done( AF_Loader loader ) 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->face = NULL; 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->globals = NULL; 77fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki loader->hints = NULL; 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 81055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define af_intToFixed( i ) \ 82055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) ) 83055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define af_fixedToInt( x ) \ 84055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) 85055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define af_floatToFixed( f ) \ 86055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) ) 87055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 88055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 90a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin af_loader_embolden_glyph_in_slot( AF_Loader loader, 91a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Face face, 92a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_StyleMetrics style_metrics ) 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 94a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error = FT_Err_Ok; 95055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 96a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_GlyphSlot slot = face->glyph; 97a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_FaceGlobals globals = loader->globals; 98a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_WritingSystemClass writing_system_class; 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Pos stdVW = 0; 101a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Pos stdHW = 0; 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 103a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Bool size_changed = face->size->metrics.x_ppem 104a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin != globals->stem_darkening_for_ppem; 105a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 106a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed em_size = af_intToFixed( face->units_per_EM ); 107a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); 108a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 109a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; 110a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 111a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 112a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Skip stem darkening for broken fonts. */ 113a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->units_per_EM ) 114a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 115a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_ERR( Corrupted_Font_Header ); 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 117a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 119055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* 120a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * We depend on the writing system (script analyzers) to supply 121a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * standard widths for the script of the glyph we are looking at. If 122a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * it can't deliver, stem darkening is disabled. 123055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin */ 124a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin writing_system_class = 125a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_WRITING_SYSTEM_CLASSES_GET[style_metrics->style_class->writing_system]; 126a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 127a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( writing_system_class->style_metrics_getstdw ) 128a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin writing_system_class->style_metrics_getstdw( style_metrics, 129a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &stdHW, 130a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &stdVW ); 131a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 132a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 133a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_ERR( Unimplemented_Feature ); 134a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 135a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 136a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 137a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( size_changed || 138a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ( stdVW > 0 && stdVW != globals->standard_vertical_width ) ) 139055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 140a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed darken_by_font_units_x, darken_x; 141055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 142055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 143a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin darken_by_font_units_x = 144a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin af_intToFixed( af_loader_compute_darkening( loader, 145a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face, 146a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin stdVW ) ); 147a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, 148a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->size->metrics.x_scale ), 149a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin em_ratio ); 150055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 151a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->standard_vertical_width = stdVW; 152a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; 153a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->darken_x = af_fixedToInt( darken_x ); 154a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 155055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 156a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( size_changed || 157a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) ) 158a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 159a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed darken_by_font_units_y, darken_y; 160055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 161055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 162a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin darken_by_font_units_y = 163a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin af_intToFixed( af_loader_compute_darkening( loader, 164a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face, 165a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin stdHW ) ); 166a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, 167a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->size->metrics.y_scale ), 168a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin em_ratio ); 169a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 170a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->standard_horizontal_width = stdHW; 171a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->stem_darkening_for_ppem = face->size->metrics.x_ppem; 172a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->darken_y = af_fixedToInt( darken_y ); 173055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 174055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* 175a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Scale outlines down on the Y-axis to keep them inside their blue 176a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * zones. The stronger the emboldening, the stronger the downscaling 177a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * (plus heuristical padding to prevent outlines still falling out 178a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * their zones due to rounding). 179a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * 180a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Reason: `FT_Outline_Embolden' works by shifting the rightmost 181a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * points of stems farther to the right, and topmost points farther 182a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * up. This positions points on the Y-axis outside their 183a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * pre-computed blue zones and leads to distortion when applying the 184a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * hints in the code further below. Code outside this emboldening 185a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * block doesn't know we are presenting it with modified outlines the 186a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * analyzer didn't see! 187a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * 188a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * An unfortunate side effect of downscaling is that the emboldening 189a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * effect is slightly decreased. The loss becomes more pronounced 190a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. 191055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin */ 192a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->scale_down_factor = 193a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), 194a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin em_size ); 195a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 196055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 197a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Outline_EmboldenXY( &slot->outline, 198a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->darken_x, 199a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin globals->darken_y ); 200055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 201a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scale_down_matrix.yy = globals->scale_down_factor; 202a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Outline_Transform( &slot->outline, &scale_down_matrix ); 203055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 204a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin Exit: 205a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 206a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 207055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 208055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 209a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Load the glyph at index into the current slot of a face and hint it. */ 210055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 211a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( FT_Error ) 212a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin af_loader_load_glyph( AF_Loader loader, 213a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_Module module, 214a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Face face, 215a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt glyph_index, 216a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Int32 load_flags ) 217a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 218a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error; 219a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 220a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Size size = face->size; 221a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_GlyphSlot slot = face->glyph; 222a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Slot_Internal internal = slot->internal; 223a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_GlyphLoader gloader = internal->loader; 224a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 225a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_GlyphHints hints = loader->hints; 226a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_ScalerRec scaler; 227a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_StyleMetrics style_metrics; 228a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt style_options = AF_STYLE_NONE_DFLT; 229a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_StyleClass style_class; 230a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_WritingSystemClass writing_system_class; 231a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 232a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#ifdef FT_CONFIG_OPTION_PIC 233a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_FaceGlobals globals = loader->globals; 234a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#endif 235055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 236055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 237a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !size ) 238a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return FT_THROW( Invalid_Size_Handle ); 239055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 240a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ZERO( &scaler ); 241a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 242a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* 243a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * TODO: This code currently doesn't support fractional advance widths, 244a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * i.e., placing hinted glyphs at anything other than integer 245a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * x-positions. This is only relevant for the warper code, which 246a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * scales and shifts glyphs to optimize blackness of stems (hinting on 247a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * the x-axis by nature places things on pixel integers, hinting on the 248a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * y-axis only, i.e., LIGHT mode, doesn't touch the x-axis). The delta 249a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * values of the scaler would need to be adjusted. 250a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin */ 251a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.face = face; 252a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.x_scale = size->metrics.x_scale; 253a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.x_delta = 0; 254a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.y_scale = size->metrics.y_scale; 255a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.y_delta = 0; 256a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 257a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); 258a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaler.flags = 0; 259a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 260a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* note that the fallback style can't be changed anymore */ 261a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* after the first call of `ta_loader_load_glyph' */ 262a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = af_loader_reset( loader, module, face ); 263a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 264a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 265a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 266a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#ifdef FT_OPTION_AUTOFIT2 267a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* XXX: undocumented hook to activate the latin2 writing system. */ 268a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( load_flags & ( 1UL << 20 ) ) 269a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_options = AF_STYLE_LTN2_DFLT; 270a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#endif 271a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 272a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* 273a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Glyphs (really code points) are assigned to scripts. Script 274a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * analysis is done lazily: For each glyph that passes through here, 275a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * the corresponding script analyzer is called, but returns immediately 276a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * if it has been run already. 277a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin */ 278a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = af_face_globals_get_metrics( loader->globals, glyph_index, 279a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_options, &style_metrics ); 280a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 281a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 282a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 283a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_class = style_metrics->style_class; 284a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin writing_system_class = 285a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; 286a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 287a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin loader->metrics = style_metrics; 288a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 289a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( writing_system_class->style_metrics_scale ) 290a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin writing_system_class->style_metrics_scale( style_metrics, &scaler ); 291a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 292a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_metrics->scaler = scaler; 293a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 294a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( writing_system_class->style_hints_init ) 295a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 296a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = writing_system_class->style_hints_init( hints, 297a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_metrics ); 298a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 299a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 300055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 301055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 302a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* 303a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Do the main work of `af_loader_load_glyph'. Note that we never have 304a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * to deal with composite glyphs as those get loaded into 305a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. 306a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * In the rare cases where FT_LOAD_NO_RECURSE is set, it implies 307a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * FT_LOAD_NO_SCALE and as such the auto-hinter is never called. 308a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin */ 309a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin load_flags |= FT_LOAD_NO_SCALE | 310a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOAD_IGNORE_TRANSFORM | 311a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOAD_LINEAR_DESIGN; 312a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin load_flags &= ~FT_LOAD_RENDER; 313a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 314a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_Load_Glyph( face, glyph_index, load_flags ); 315a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 316a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 317a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 318a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* 319a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Apply stem darkening (emboldening) here before hints are applied to 320a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * the outline. Glyphs are scaled down proportionally to the 321a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * emboldening so that curve points don't fall outside their 322a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * precomputed blue zones. 323a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * 324a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Any emboldening done by the font driver (e.g., the CFF driver) 325a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * doesn't reach here because the autohinter loads the unprocessed 326a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * glyphs in font units for analysis (functions `af_*_metrics_init_*') 327a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * and then above to prepare it for the rasterizers by itself, 328a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * independently of the font driver. So emboldening must be done here, 329a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * within the autohinter. 330a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * 331a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * All glyphs to be autohinted pass through here one by one. The 332a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * standard widths can therefore change from one glyph to the next, 333a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * depending on what script a glyph is assigned to (each script has its 334a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * own set of standard widths and other metrics). The darkening amount 335a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * must therefore be recomputed for each size and 336a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * `standard_{vertical,horizontal}_width' change. 337a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * 338a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin * Ignore errors and carry on without emboldening. 339a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin */ 340a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !module->no_stem_darkening ) 341a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin af_loader_embolden_glyph_in_slot( loader, face, style_metrics ); 342a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->transformed = internal->glyph_transformed; 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->transformed ) 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Matrix inverse; 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_matrix = internal->glyph_matrix; 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_delta = internal->glyph_delta; 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project inverse = loader->trans_matrix; 353fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( !FT_Matrix_Invert( &inverse ) ) 354fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector_Transform( &loader->trans_delta, &inverse ); 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( slot->format ) 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_GLYPH_FORMAT_OUTLINE: 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* translate the loaded glyph when an internal transform is needed */ 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->transformed ) 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Translate( &slot->outline, 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_delta.x, 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_delta.y ); 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 366a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* compute original horizontal phantom points */ 367a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* (and ignore vertical ones) */ 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = hints->x_delta; 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.y = hints->y_delta; 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_scale ) + hints->x_delta; 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.y = hints->y_delta; 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* be sure to check for spacing glyphs */ 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( slot->outline.n_points == 0 ) 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Hint_Metrics; 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 378a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* now load the slot image into the auto-outline */ 379a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* and run the automatic hinting process */ 380a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( writing_system_class->style_hints_apply ) 381a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin writing_system_class->style_hints_apply( glyph_index, 382a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin hints, 383a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &gloader->base.outline, 384a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_metrics ); 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 386aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* we now need to adjust the metrics according to the change in */ 387aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* width/positioning that occurred during the hinting process */ 388a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( scaler.render_mode != FT_RENDER_MODE_LIGHT ) 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 390a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Pos old_rsb, old_lsb, new_lsb; 391a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Pos pp1x_uh, pp2x_uh; 392a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge1 = axis->edges; /* leftmost edge */ 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge2 = edge1 + 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->num_edges - 1; /* rightmost edge */ 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 401aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich old_rsb = loader->pp2.x - edge2->opos; 402a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* loader->pp1.x is always zero at this point of time */ 403a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin old_lsb = edge1->opos /* - loader->pp1.x */; 404aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich new_lsb = edge1->pos; 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* remember unhinted values to later account */ 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* for rounding errors */ 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp1x_uh = new_lsb - old_lsb; 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp2x_uh = edge2->pos + old_rsb; 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* prefer too much space over too little space */ 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* for very small sizes */ 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_lsb < 24 ) 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp1x_uh -= 8; 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_rsb < 24 ) 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp2x_uh += 8; 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x -= 64; 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x += 64; 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = loader->pp1.x - pp1x_uh; 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = loader->pp2.x - pp2x_uh; 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 434aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp1x = loader->pp1.x; 435aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp2x = loader->pp2.x; 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 437295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = FT_PIX_ROUND( pp1x ); 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_PIX_ROUND( pp2x ); 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = loader->pp1.x - pp1x; 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = loader->pp2.x - pp2x; 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 447aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp1x = loader->pp1.x; 448aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp2x = loader->pp2.x; 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 450295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = loader->pp1.x - pp1x; 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = loader->pp2.x - pp2x; 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we don't support other formats (yet?) */ 462727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Unimplemented_Feature ); 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Hint_Metrics: 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_BBox bbox; 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector vvector; 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; 473a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin vvector.x = FT_MulFix( vvector.x, style_metrics->scaler.x_scale ); 474a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin vvector.y = FT_MulFix( vvector.y, style_metrics->scaler.y_scale ); 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* transform the hinted outline if needed */ 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->transformed ) 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Transform( &vvector, &loader->trans_matrix ); 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 482a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we must translate our final outline by -pp1.x and compute */ 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the new metrics */ 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->pp1.x ) 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); 487a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.xMax = FT_PIX_CEIL( bbox.xMax ); 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.yMax = FT_PIX_CEIL( bbox.yMax ); 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.width = bbox.xMax - bbox.xMin; 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.height = bbox.yMax - bbox.yMin; 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiBearingX = bbox.xMin; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiBearingY = bbox.yMax; 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* for mono-width fonts (like Andale, Courier, etc.) we need */ 504295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* to keep the original rounded advance width; ditto for */ 505295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* digits if all have the same advance width */ 506a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( scaler.render_mode != FT_RENDER_MODE_LIGHT && 50741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier ( FT_IS_FIXED_WIDTH( slot->face ) || 50841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier ( af_face_globals_is_digit( loader->globals, glyph_index ) && 509a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_metrics->digits_have_same_width ) ) ) 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 511a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin slot->metrics.horiAdvance = 512a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_MulFix( slot->metrics.horiAdvance, 513a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_metrics->scaler.x_scale ); 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Set delta values to 0. Otherwise code that uses them is */ 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* going to ruin the fixed advance width. */ 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = 0; 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = 0; 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 520295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 521295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 522295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* non-spacing glyphs must stay as-is */ 523295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( slot->metrics.horiAdvance ) 524295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; 525295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, 528a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin style_metrics->scaler.y_scale ); 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->format = FT_GLYPH_FORMAT_OUTLINE; 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 541055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* 542055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * Compute amount of font units the face should be emboldened by, in 543055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * analogy to the CFF driver's `cf2_computeDarkening' function. See there 544055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * for details of the algorithm. 545055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * 546055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * XXX: Currently a crude adaption of the original algorithm. Do better? 547055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin */ 548055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_LOCAL_DEF( FT_Int32 ) 549055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_loader_compute_darkening( AF_Loader loader, 550055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Face face, 551055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Pos standard_width ) 552055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 553055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Module module = loader->globals->module; 554055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 555055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UShort units_per_EM; 556055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Fixed ppem, em_ratio; 557055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Fixed stem_width, stem_width_per_1000, scaled_stem, darken_amount; 558055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int log_base_2; 559055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int x1, y1, x2, y2, x3, y3, x4, y4; 560055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 561055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 562055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ppem = FT_MAX( af_intToFixed( 4 ), 563055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_intToFixed( face->size->metrics.x_ppem ) ); 564055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin units_per_EM = face->units_per_EM; 565055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 566055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin em_ratio = FT_DivFix( af_intToFixed( 1000 ), 567055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_intToFixed ( units_per_EM ) ); 568055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( em_ratio < af_floatToFixed( .01 ) ) 569055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 570055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* If something goes wrong, don't embolden. */ 571055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 572055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 573055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 574055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin x1 = module->darken_params[0]; 575055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin y1 = module->darken_params[1]; 576055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin x2 = module->darken_params[2]; 577055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin y2 = module->darken_params[3]; 578055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin x3 = module->darken_params[4]; 579055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin y3 = module->darken_params[5]; 580055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin x4 = module->darken_params[6]; 581055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin y4 = module->darken_params[7]; 582055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 583055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( standard_width <= 0 ) 584055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 585055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin stem_width = af_intToFixed( 75 ); /* taken from cf2font.c */ 586055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin stem_width_per_1000 = stem_width; 587055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 588055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 589055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 590055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin stem_width = af_intToFixed( standard_width ); 591055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin stem_width_per_1000 = FT_MulFix( stem_width, em_ratio ); 592055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 593055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 594055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) + 595055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_MSB( (FT_UInt32)ppem ); 596055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 597055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( log_base_2 >= 46 ) 598055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 599055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* possible overflow */ 600055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin scaled_stem = af_intToFixed( x4 ); 601055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 602055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 603055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin scaled_stem = FT_MulFix( stem_width_per_1000, ppem ); 604055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 605055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* now apply the darkening parameters */ 606055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( scaled_stem < af_intToFixed( x1 ) ) 607055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem ); 608055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 609055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( scaled_stem < af_intToFixed( x2 ) ) 610055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 611055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int xdelta = x2 - x1; 612055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int ydelta = y2 - y1; 613055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int x = stem_width_per_1000 - 614055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_DivFix( af_intToFixed( x1 ), ppem ); 615055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 616055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 617055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( !xdelta ) 618055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Try_x3; 619055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 620055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin darken_amount = FT_MulDiv( x, ydelta, xdelta ) + 621055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_DivFix( af_intToFixed( y1 ), ppem ); 622055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 623055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 624055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( scaled_stem < af_intToFixed( x3 ) ) 625055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 626055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Try_x3: 627055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 628055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int xdelta = x3 - x2; 629055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int ydelta = y3 - y2; 630055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int x = stem_width_per_1000 - 631055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_DivFix( af_intToFixed( x2 ), ppem ); 632055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 633055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 634055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( !xdelta ) 635055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Try_x4; 636055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 637055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin darken_amount = FT_MulDiv( x, ydelta, xdelta ) + 638055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_DivFix( af_intToFixed( y2 ), ppem ); 639055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 640055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 641055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 642055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( scaled_stem < af_intToFixed( x4 ) ) 643055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 644055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Try_x4: 645055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 646055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int xdelta = x4 - x3; 647055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int ydelta = y4 - y3; 648055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int x = stem_width_per_1000 - 649055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_DivFix( af_intToFixed( x3 ), ppem ); 650055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 651055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 652055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( !xdelta ) 653055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Use_y4; 654055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 655055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin darken_amount = FT_MulDiv( x, ydelta, xdelta ) + 656055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_DivFix( af_intToFixed( y3 ), ppem ); 657055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 658055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 659055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 660055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 661055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 662055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Use_y4: 663055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem ); 664055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 665055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 666055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* Convert darken_amount from per 1000 em to true character space. */ 667055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) ); 668055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 669055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 670055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 672