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/* */ 7ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki/* Copyright 2003-2015 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 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 27aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Initialize glyph loader. */ 28aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 29ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_LOCAL_DEF( void ) 30ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki af_loader_init( AF_Loader loader, 31ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki AF_GlyphHints hints ) 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ZERO( loader ); 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 35ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki loader->hints = hints; 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 39aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Reset glyph loader and compute globals if necessary. */ 40aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 42ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki af_loader_reset( AF_Loader loader, 43ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki AF_Module module, 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Face face ) 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 46ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Error error = FT_Err_Ok; 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->face = face; 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->globals = (AF_FaceGlobals)face->autohint.data; 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->globals == NULL ) 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 54727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = af_face_globals_new( face, &loader->globals, module ); 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !error ) 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->autohint.data = 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_Pointer)loader->globals; 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->autohint.finalizer = 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_Generic_Finalizer)af_face_globals_free; 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 68aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Finalize glyph loader. */ 69aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 71ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki af_loader_done( AF_Loader loader ) 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->face = NULL; 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->globals = NULL; 75ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki loader->hints = NULL; 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 79ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* Do the main work of `af_loader_load_glyph'. Note that we never */ 80ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* have to deal with composite glyphs as those get loaded into */ 81ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */ 82ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */ 83ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */ 84aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_loader_load_g( AF_Loader loader, 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Scaler scaler, 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt glyph_index, 89ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Int32 load_flags ) 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Face face = loader->face; 939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleMetrics metrics = loader->metrics; 94ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki AF_GlyphHints hints = loader->hints; 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_GlyphSlot slot = face->glyph; 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Slot_Internal internal = slot->internal; 97ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_GlyphLoader gloader = internal->loader; 98727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int32 flags; 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease flags = load_flags | FT_LOAD_LINEAR_DESIGN; 102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Load_Glyph( face, glyph_index, flags ); 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->transformed = internal->glyph_transformed; 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->transformed ) 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Matrix inverse; 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_matrix = internal->glyph_matrix; 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_delta = internal->glyph_delta; 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project inverse = loader->trans_matrix; 116ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( !FT_Matrix_Invert( &inverse ) ) 117ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Vector_Transform( &loader->trans_delta, &inverse ); 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( slot->format ) 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_GLYPH_FORMAT_OUTLINE: 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* translate the loaded glyph when an internal transform is needed */ 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->transformed ) 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Translate( &slot->outline, 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_delta.x, 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->trans_delta.y ); 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* compute original horizontal phantom points (and ignore */ 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* vertical ones) */ 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = hints->x_delta; 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.y = hints->y_delta; 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_scale ) + hints->x_delta; 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.y = hints->y_delta; 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* be sure to check for spacing glyphs */ 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( slot->outline.n_points == 0 ) 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Hint_Metrics; 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now load the slot image into the auto-outline and run the */ 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* automatic hinting process */ 143ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 144ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef FT_CONFIG_OPTION_PIC 1459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_FaceGlobals globals = loader->globals; 146ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif 1479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleClass style_class = metrics->style_class; 148ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_WritingSystemClass writing_system_class = 1499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; 150ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 151ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 1529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( writing_system_class->style_hints_apply ) 1539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod writing_system_class->style_hints_apply( hints, 154ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki &gloader->base.outline, 1559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod metrics ); 156ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 158aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* we now need to adjust the metrics according to the change in */ 159aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* width/positioning that occurred during the hinting process */ 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos old_rsb, old_lsb, new_lsb; 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos pp1x_uh, pp2x_uh; 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge1 = axis->edges; /* leftmost edge */ 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge2 = edge1 + 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->num_edges - 1; /* rightmost edge */ 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 172aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich old_rsb = loader->pp2.x - edge2->opos; 173aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich old_lsb = edge1->opos; 174aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich new_lsb = edge1->pos; 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* remember unhinted values to later account */ 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* for rounding errors */ 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp1x_uh = new_lsb - old_lsb; 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp2x_uh = edge2->pos + old_rsb; 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* prefer too much space over too little space */ 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* for very small sizes */ 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_lsb < 24 ) 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp1x_uh -= 8; 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_rsb < 24 ) 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pp2x_uh += 8; 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x -= 64; 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x += 64; 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = loader->pp1.x - pp1x_uh; 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = loader->pp2.x - pp2x_uh; 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 205aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp1x = loader->pp1.x; 206aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp2x = loader->pp2.x; 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 208295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = FT_PIX_ROUND( pp1x ); 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_PIX_ROUND( pp2x ); 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = loader->pp1.x - pp1x; 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = loader->pp2.x - pp2x; 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 218aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp1x = loader->pp1.x; 219aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos pp2x = loader->pp2.x; 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 221295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = loader->pp1.x - pp1x; 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = loader->pp2.x - pp2x; 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we don't support other formats (yet?) */ 233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Unimplemented_Feature ); 234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Hint_Metrics: 237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_BBox bbox; 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector vvector; 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* transform the hinted outline if needed */ 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->transformed ) 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Transform( &vvector, &loader->trans_matrix ); 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we must translate our final outline by -pp1.x and compute */ 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the new metrics */ 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( loader->pp1.x ) 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.xMax = FT_PIX_CEIL( bbox.xMax ); 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bbox.yMax = FT_PIX_CEIL( bbox.yMax ); 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.width = bbox.xMax - bbox.xMin; 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.height = bbox.yMax - bbox.yMin; 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiBearingX = bbox.xMin; 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiBearingY = bbox.yMax; 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* for mono-width fonts (like Andale, Courier, etc.) we need */ 275295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* to keep the original rounded advance width; ditto for */ 276295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* digits if all have the same advance width */ 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !FT_IS_FIXED_WIDTH( slot->face ) ) 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x_scale ); 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else 28441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && 28541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier ( FT_IS_FIXED_WIDTH( slot->face ) || 28641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier ( af_face_globals_is_digit( loader->globals, glyph_index ) && 28741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier metrics->digits_have_same_width ) ) ) 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->scaler.x_scale ); 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Set delta values to 0. Otherwise code that uses them is */ 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* going to ruin the fixed advance width. */ 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->lsb_delta = 0; 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->rsb_delta = 0; 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 297295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 298295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 299295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* non-spacing glyphs must stay as-is */ 300295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( slot->metrics.horiAdvance ) 301295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; 302295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, 306aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner metrics->scaler.y_scale ); 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 311ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki#if 0 31241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier /* reassign all outline fields except flags to protect them */ 31341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier slot->outline.n_contours = internal->loader->base.outline.n_contours; 31441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier slot->outline.n_points = internal->loader->base.outline.n_points; 31541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier slot->outline.points = internal->loader->base.outline.points; 31641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier slot->outline.tags = internal->loader->base.outline.tags; 31741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier slot->outline.contours = internal->loader->base.outline.contours; 318ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki#endif 31941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slot->format = FT_GLYPH_FORMAT_OUTLINE; 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 328aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Load a glyph. */ 329aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 331ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki af_loader_load_glyph( AF_Loader loader, 332ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki AF_Module module, 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Face face, 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex, 33541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier FT_Int32 load_flags ) 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 338727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Size size = face->size; 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_ScalerRec scaler; 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !size ) 343ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return FT_THROW( Invalid_Size_Handle ); 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ZERO( &scaler ); 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.face = face; 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.x_scale = size->metrics.x_scale; 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.y_scale = size->metrics.y_scale; 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project scaler.flags = 0; /* XXX: fix this */ 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 356ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki error = af_loader_reset( loader, module, face ); 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !error ) 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleMetrics metrics; 3609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UInt options = AF_STYLE_NONE_DFLT; 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_OPTION_AUTOFIT2 364ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* XXX: undocumented hook to activate the latin2 writing system */ 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( load_flags & ( 1UL << 20 ) ) 3669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod options = AF_STYLE_LTN2_DFLT; 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = af_face_globals_get_metrics( loader->globals, gindex, 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project options, &metrics ); 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !error ) 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 373ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef FT_CONFIG_OPTION_PIC 3749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_FaceGlobals globals = loader->globals; 375ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif 3769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleClass style_class = metrics->style_class; 377ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_WritingSystemClass writing_system_class = 3789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; 379ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 380ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project loader->metrics = metrics; 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3839c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( writing_system_class->style_metrics_scale ) 3849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod writing_system_class->style_metrics_scale( metrics, &scaler ); 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project metrics->scaler = scaler; 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project load_flags &= ~FT_LOAD_RENDER; 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( writing_system_class->style_hints_init ) 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 393ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki error = writing_system_class->style_hints_init( loader->hints, 3949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod metrics ); 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 399ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki error = af_loader_load_g( loader, &scaler, gindex, load_flags ); 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 408