afhints.c revision fb6b5b10aaa74b8c8974714b41bac35bdd1c772d
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* afhints.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* Auto-fitter hinting routines (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 7fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto 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 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "afhints.h" 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "aferrors.h" 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_CALC_H 22727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_DEBUG_H 23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 24727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 25727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /*************************************************************************/ 26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* */ 27727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 28727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 29727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* messages during execution. */ 30727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* */ 31727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef FT_COMPONENT 32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_COMPONENT trace_afhints 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 35aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Get new segment for given axis. */ 36aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_axis_hints_new_segment( AF_AxisHints axis, 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment *asegment ) 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 42727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segment = NULL; 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 46fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->num_segments < AF_SEGMENTS_EMBEDDED ) 47fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 48fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->segments == NULL ) 49fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 50fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki axis->segments = axis->embedded.segments; 51fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki axis->max_segments = AF_SEGMENTS_EMBEDDED; 52fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 53fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 54fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( axis->num_segments >= axis->max_segments ) 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int old_max = axis->max_segments; 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int new_max = old_max; 58295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_max >= big_max ) 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max += ( new_max >> 2 ) + 4; 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max < old_max || new_max > big_max ) 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = big_max; 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 71fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->segments == axis->embedded.segments ) 72fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 73fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_NEW_ARRAY( axis->segments, new_max ) ) 74fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 75fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ft_memcpy( axis->segments, axis->embedded.segments, 76fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki sizeof ( axis->embedded.segments ) ); 77fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 78fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 79fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 80fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) 81fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 82fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->max_segments = new_max; 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project segment = axis->segments + axis->num_segments++; 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asegment = segment; 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 95fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Get new edge for given axis, direction, and position, */ 96fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* without initializing the edge itself. */ 97aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL( FT_Error ) 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_axis_hints_new_edge( AF_AxisHints axis, 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int fpos, 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Direction dir, 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Edge *anedge ) 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = NULL; 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges; 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 110fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->num_edges < AF_EDGES_EMBEDDED ) 111fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 112fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->edges == NULL ) 113fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 114fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki axis->edges = axis->embedded.edges; 115fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki axis->max_edges = AF_EDGES_EMBEDDED; 116fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 117fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 118fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( axis->num_edges >= axis->max_edges ) 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int old_max = axis->max_edges; 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int new_max = old_max; 122295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_max >= big_max ) 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 127727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max += ( new_max >> 2 ) + 4; 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max < old_max || new_max > big_max ) 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = big_max; 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 135fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->edges == axis->embedded.edges ) 136fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 137fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_NEW_ARRAY( axis->edges, new_max ) ) 138fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 139fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ft_memcpy( axis->edges, axis->embedded.edges, 140fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki sizeof ( axis->embedded.edges ) ); 141fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 142fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 143fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 144fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) 145fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 146fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->max_edges = new_max; 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edges = axis->edges; 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges + axis->num_edges; 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( edge > edges ) 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge[-1].fpos < fpos ) 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we want the edge with same position and minor direction */ 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to appear before those in the major one in the list */ 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge[-1].fpos == fpos && dir == axis->major_dir ) 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge[0] = edge[-1]; 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge--; 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->num_edges++; 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 171727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *anedge = edge; 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 176aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef FT_DEBUG_AUTOFIT 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include FT_CONFIG_STANDARD_LIBRARY_H 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 180ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* The dump functions are used in the `ftgrid' demo program, too. */ 181ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#define AF_DUMP( varformat ) \ 182ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease do \ 183ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { \ 184ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( to_stdout ) \ 185ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease printf varformat; \ 186ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease else \ 187ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_TRACE7( varformat ); \ 188ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } while ( 0 ) 189ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 190ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const char* 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_dir_str( AF_Direction dir ) 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const char* result; 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( dir ) 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_UP: 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "up"; 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_DOWN: 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "down"; 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_LEFT: 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "left"; 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_RIGHT: 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "right"; 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "none"; 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 219fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 ) 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 222aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 223aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 224aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 226ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_points( AF_GlyphHints hints, 227ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point limit = points + hints->num_points; 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 234fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_DUMP(( "Table of points:\n" )); 235fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 236fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->num_points ) 237fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_DUMP(( " [ index | xorg | yorg | xscale | yscale" 238fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " | xfit | yfit | flags ]\n" )); 239fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 240fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_DUMP(( " (none)\n" )); 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < limit; point++ ) 243ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ %5d | %5d | %5d | %6.2f | %6.2f" 244fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " | %5.2f | %5.2f | %c ]\n", 245fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_INDEX_NUM( point, points ), 246ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->fx, 247ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->fy, 248ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->ox / 64.0, 249ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->oy / 64.0, 250ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->x / 64.0, 251ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->y / 64.0, 252fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ')); 253ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 255aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 256aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 257aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const char* 261fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_edge_flags_to_string( FT_UInt flags ) 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static char temp[32]; 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int pos = 0; 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( flags & AF_EDGE_ROUND ) 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project ft_memcpy( temp + pos, "round", 5 ); 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos += 5; 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( flags & AF_EDGE_SERIF ) 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos > 0 ) 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project temp[pos++] = ' '; 2760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project ft_memcpy( temp + pos, "serif", 5 ); 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos += 5; 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos == 0 ) 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return "normal"; 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease temp[pos] = '\0'; 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return temp; 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 288aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Dump the array of linked segments. */ 289aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 290aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 291aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 292aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 294ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_segments( AF_GlyphHints hints, 295ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int dimension; 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( dimension = 1; dimension >= 0; dimension-- ) 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dimension]; 303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Point points = hints->points; 304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Edge edges = axis->edges; 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segments = axis->segments; 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment limit = segments + axis->num_segments; 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment seg; 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 310ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "Table of %s segments:\n", 311ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ ? "vertical" 312ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : "horizontal" )); 313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( axis->num_segments ) 314ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ index | pos | dir | from" 315ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | to | link | serif | edge" 316ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | height | extra | flags ]\n" )); 317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 318ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " (none)\n" )); 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < limit; seg++ ) 321ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ %5d | %5.2g | %5s | %4d" 322ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %4d | %4d | %5d | %4d" 323ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %6d | %5d | %11s ]\n", 324fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_INDEX_NUM( seg, segments ), 325ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ 326ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ? (int)seg->first->ox / 64.0 327ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : (int)seg->first->oy / 64.0, 328ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_dir_str( (AF_Direction)seg->dir ), 329ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->first, points ), 330ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->last, points ), 331ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->link, segments ), 332ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->serif, segments ), 333ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->edge, edges ), 334ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg->height, 335ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg->height - ( seg->max_coord - seg->min_coord ), 336fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_edge_flags_to_string( seg->flags ) )); 337ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 340aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 341aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 342aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 343aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 344aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 345aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Fetch number of segments. */ 346aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 347aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 348aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 349aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 350aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Error 351aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner af_glyph_hints_get_num_segments( AF_GlyphHints hints, 352aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int dimension, 353aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int* num_segments ) 354aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner { 355aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Dimension dim; 356aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_AxisHints axis; 357aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 358aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 359aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; 360aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 361aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner axis = &hints->axis[dim]; 362aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner *num_segments = axis->num_segments; 363aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 364727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 365aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 366aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 367aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 368aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 369aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 370aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 371aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Fetch offset of segments into user supplied offset array. */ 372aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 373aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 374aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 375aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 376aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Error 377aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner af_glyph_hints_get_segment_offset( AF_GlyphHints hints, 378aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int dimension, 379aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int idx, 3809c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos *offset, 3819c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Bool *is_blue, 3829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos *blue_offset ) 383aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner { 384aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Dimension dim; 385aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_AxisHints axis; 386aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Segment seg; 387aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 388aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 389aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner if ( !offset ) 390727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 391aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 392aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; 393aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 394aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner axis = &hints->axis[dim]; 395aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 396aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner if ( idx < 0 || idx >= axis->num_segments ) 397727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 398aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 3999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod seg = &axis->segments[idx]; 4009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox 4019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod : seg->first->oy; 4029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( seg->edge ) 4039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); 4049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod else 4059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *is_blue = FALSE; 4069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 4079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( *is_blue ) 4089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *blue_offset = seg->edge->blue_edge->cur; 4099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod else 4109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *blue_offset = 0; 411aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 413aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 414aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 415aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 416aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 417aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 419aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Dump the array of linked edges. */ 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 421aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 422aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 423aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 425ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_edges( AF_GlyphHints hints, 426ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int dimension; 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( dimension = 1; dimension >= 0; dimension-- ) 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dimension]; 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges = axis->edges; 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge limit = edges + axis->num_edges; 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge; 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges 441aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner * since they have a constant X coordinate. 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 443ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "Table of %s edges:\n", 444ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ ? "vertical" 445ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : "horizontal" )); 446727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( axis->num_edges ) 447ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ index | pos | dir | link" 448ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | serif | blue | opos | pos | flags ]\n" )); 449727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 450ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " (none)\n" )); 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( edge = edges; edge < limit; edge++ ) 453ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ %5d | %5.2g | %5s | %4d" 454ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %5d | %c | %5.2f | %5.2f | %11s ]\n", 455fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_INDEX_NUM( edge, edges ), 456ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease (int)edge->opos / 64.0, 457ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_dir_str( (AF_Direction)edge->dir ), 458ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( edge->link, edges ), 459ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( edge->serif, edges ), 460ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->blue_edge ? 'y' : 'n', 461ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->opos / 64.0, 462ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->pos / 64.0, 463fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_edge_flags_to_string( edge->flags ) )); 464ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 467aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 468aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 469aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 471ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#undef AF_DUMP 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 473aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* !FT_DEBUG_AUTOFIT */ 474aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 475aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 476aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Compute the direction value of a given vector. */ 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( AF_Direction ) 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_direction_compute( FT_Pos dx, 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos dy ) 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos ll, ss; /* long and short arm lengths */ 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Direction dir; /* candidate direction */ 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= dx ) 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= -dx ) 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_UP; 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dy; 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dx; 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_LEFT; 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = -dx; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dy; 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* dy < dx */ 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= -dx ) 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_RIGHT; 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dx; 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dy; 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_DOWN; 512fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ll = -dy; 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dx; 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 517fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* return no direction if arm lengths do not differ enough */ 518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ 519fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* the long arm is never negative */ 520fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ll <= 14 * FT_ABS( ss ) ) 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_NONE; 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return dir; 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_init( AF_GlyphHints hints, 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 531fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* no need to initialize the embedded items */ 532fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) ); 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->memory = memory; 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_done( AF_GlyphHints hints ) 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 540fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Memory memory; 541727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int dim; 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 544727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !( hints && hints->memory ) ) 545727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return; 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 547fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki memory = hints->memory; 548fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 549727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* 550727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * note that we don't need to free the segment and edge 551727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * buffers since they are really within the hints->points array 552727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */ 553727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) 554727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 555727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_AxisHints axis = &hints->axis[dim]; 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->num_segments = 0; 559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->max_segments = 0; 560fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->segments != axis->embedded.segments ) 561fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( axis->segments ); 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 563727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->num_edges = 0; 564727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->max_edges = 0; 565fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->edges != axis->embedded.edges ) 566fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( axis->edges ); 567727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 569fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->contours != hints->embedded.contours ) 570fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( hints->contours ); 571727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->max_contours = 0; 572727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->num_contours = 0; 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 574fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->points != hints->embedded.points ) 575fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( hints->points ); 576727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->max_points = 0; 577fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->num_points = 0; 578727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 579727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->memory = NULL; 580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 583aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Reset metrics. */ 584aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 5869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod af_glyph_hints_rescale( AF_GlyphHints hints, 5879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleMetrics metrics ) 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->metrics = metrics; 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->scaler_flags = metrics->scaler.flags; 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 594aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Recompute all AF_Point in AF_GlyphHints from the definitions */ 595aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* in a source outline. */ 596aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_reload( AF_GlyphHints hints, 599aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Outline* outline ) 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 601727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points; 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt old_max, new_max; 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed x_scale = hints->x_scale; 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed y_scale = hints->y_scale; 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos x_delta = hints->x_delta; 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos y_delta = hints->y_delta; 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = hints->memory; 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_points = 0; 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_contours = 0; 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[0].num_segments = 0; 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[0].num_edges = 0; 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[1].num_segments = 0; 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[1].num_edges = 0; 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 619aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* first of all, reallocate the contours array if necessary */ 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = (FT_UInt)outline->n_contours; 621fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki old_max = (FT_UInt)hints->max_contours; 622fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 623fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( new_max <= AF_CONTOURS_EMBEDDED ) 624fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 625fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->contours == NULL ) 626fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 627fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->contours = hints->embedded.contours; 628fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_contours = AF_CONTOURS_EMBEDDED; 629fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 630fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 631fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( new_max > old_max ) 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 633fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->contours == hints->embedded.contours ) 634fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->contours = NULL; 635fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 636fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */ 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) 639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 641fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_contours = (FT_Int)new_max; 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * then reallocate the points arrays if necessary -- 646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * note that we reserve two additional point positions, used to 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * hint metrics appropriately 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = (FT_UInt)( outline->n_points + 2 ); 650fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki old_max = (FT_UInt)hints->max_points; 651fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 652fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( new_max <= AF_POINTS_EMBEDDED ) 653fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 654fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->points == NULL ) 655fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 656fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->points = hints->embedded.points; 657fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_points = AF_POINTS_EMBEDDED; 658fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 659fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 660fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( new_max > old_max ) 661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 662fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->points == hints->embedded.points ) 663fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->points = NULL; 664fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 665fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */ 666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 670fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_points = (FT_Int)new_max; 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_points = outline->n_points; 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_contours = outline->n_contours; 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* We can't rely on the value of `FT_Outline.flags' to know the fill */ 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* direction used for a glyph, given that some fonts are broken (e.g., */ 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the Arphic ones). We thus recompute it each time we need to. */ 679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; 681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; 682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_scale = x_scale; 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->y_scale = y_scale; 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_delta = x_delta; 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->y_delta = y_delta; 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->xmin_delta = 0; 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->xmax_delta = 0; 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project points = hints->points; 698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( hints->num_points == 0 ) 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* compute coordinates & Bezier flags, next and prev */ 707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector* vec = outline->points; 709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char* tag = outline->tags; 710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point end = points + outline->contours[0]; 711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point prev = end; 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int contour_index = 0; 713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++, vec++, tag++ ) 716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 7179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->in_dir = (FT_Char)AF_DIR_NONE; 7189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->out_dir = (FT_Char)AF_DIR_NONE; 7199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->fx = (FT_Short)vec->x; 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->fy = (FT_Short)vec->y; 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( FT_CURVE_TAG( *tag ) ) 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_CURVE_TAG_CONIC: 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags = AF_FLAG_CONIC; 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_CURVE_TAG_CUBIC: 731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags = AF_FLAG_CUBIC; 732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 734aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner point->flags = AF_FLAG_NONE; 735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->prev = prev; 738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev->next = point; 739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev = point; 740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == end ) 742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ++contour_index < outline->n_contours ) 744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 745aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich end = points + outline->contours[contour_index]; 746aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich prev = end; 747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 752aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* set up the contours array */ 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour = hints->contours; 755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour_limit = contour + hints->num_contours; 756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project short* end = outline->contours; 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project short idx = 0; 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; contour < contour_limit; contour++, end++ ) 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project contour[0] = points + idx; 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (short)( end[0] + 1 ); 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 7689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 7699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Compute directions of `in' and `out' vectors. 7709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 7719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Note that distances between points that are very near to each 7729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * other are accumulated. In other words, the auto-hinter 7739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * prepends the small vectors between near points to the first 7749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-near vector. All intermediate points are tagged as 7759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * weak; the directions are adjusted also to be equal to the 7769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * accumulated one. 7779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 7789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7799c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* value 20 in `near_limit' is heuristic */ 780ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; 781ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Int near_limit = 20 * units_per_em / 2048; 7829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Int near_limit2 = 2 * near_limit - 1; 783ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point* contour; 7859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point* contour_limit = hints->contours + hints->num_contours; 786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 7879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7889c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( contour = hints->contours; contour < contour_limit; contour++ ) 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 7909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point first = *contour; 7919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next, prev, curr; 7929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos out_x, out_y; 7949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 7969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* since the first point of a contour could be part of a */ 7979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* series of near points, go backwards to find the first */ 7989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* non-near point and adjust `first' */ 7999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = first; 8019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev = first->prev; 8029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod while ( prev != first ) 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 8059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = point->fx - prev->fx; 8069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = point->fy - prev->fy; 8079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 8099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * We use Taxicab metrics to measure the vector length. 8109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 8119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Note that the accumulated distances so far could have the 8129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * opposite direction of the distance measured here. For this 8139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * reason we use `near_limit2' for the comparison to get a 8149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-near point even in the worst case. 8159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 8169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) 8179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod break; 8189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = prev; 8209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev = prev->prev; 8219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 822ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8239c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* adjust first point */ 8249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first = point; 825ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8269c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* now loop over all points of the contour to get */ 8279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* `in' and `out' vector directions */ 828ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr = first; 830ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 8329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * We abuse the `u' and `v' fields to store index deltas to the 8339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * next and previous non-near point, respectively. 8349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 8359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * To avoid problems with not having non-near points, we point to 8369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * `first' by default as the next non-near point. 8379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 8389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 8399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( first - curr ); 8409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first->v = -curr->u; 841ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = 0; 8439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = 0; 844ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 845fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki next = first; 846fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki do 8479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Direction out_dir; 849ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 850ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 851fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point = next; 8529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next = point->next; 853ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x += next->fx - point->fx; 8559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y += next->fy - point->fy; 8569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) 8589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->flags |= AF_FLAG_WEAK_INTERPOLATION; 8609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 861ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 862ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( next - curr ); 8649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->v = -curr->u; 8659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_dir = af_direction_compute( out_x, out_y ); 8679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* adjust directions for all points inbetween; */ 8699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* the loop also updates position of `curr' */ 8709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->out_dir = (FT_Char)out_dir; 8719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( curr = curr->next; curr != next; curr = curr->next ) 8729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->in_dir = (FT_Char)out_dir; 8749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->out_dir = (FT_Char)out_dir; 8759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 8769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->in_dir = (FT_Char)out_dir; 8779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( first - curr ); 8799c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first->v = -curr->u; 8809c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8819c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = 0; 8829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = 0; 883fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 884fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } while ( next != first ); 8859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 8889c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * The next step is to `simplify' an outline's topology so that we 8899c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * can identify local extrema more reliably: A series of 8909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-horizontal or non-vertical vectors pointing into the same 8919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * quadrant are handled as a single, long vector. From a 8929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * topological point of the view, the intermediate points are of no 8939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * interest and thus tagged as weak. 8949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = points; point < point_limit; point++ ) 8979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 8999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 900ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->in_dir == AF_DIR_NONE && 9029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->out_dir == AF_DIR_NONE ) 903ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 9049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* check whether both vectors point into the same quadrant */ 9059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos in_x, in_y; 9079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos out_x, out_y; 9089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next_u = point + point->u; 9109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point prev_v = point + point->v; 9119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 912ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod in_x = point->fx - prev_v->fx; 9149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod in_y = point->fy - prev_v->fy; 9159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = next_u->fx - point->fx; 9179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = next_u->fy - point->fy; 9189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 ) 9209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 9219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* yes, so tag current point as weak */ 9229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* and update index deltas */ 9239c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->flags |= AF_FLAG_WEAK_INTERPOLATION; 9259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9269c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev_v->u = (FT_Pos)( next_u - prev_v ); 9279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->v = -prev_v->u; 9289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 9299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 9309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 9329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 9339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Finally, check for remaining weak points. Everything else not 9349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * collected in edges so far is then implicitly classified as strong 9359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * points. 9369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 9389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = points; point < point_limit; point++ ) 9399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 9409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 9419c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 942aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 943727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( point->flags & AF_FLAG_CONTROL ) 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 945ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* control points are always weak */ 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Is_Weak_Point: 947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_WEAK_INTERPOLATION; 948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->out_dir == point->in_dir ) 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->out_dir != AF_DIR_NONE ) 952ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 953ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* current point lies on a horizontal or */ 954ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* vertical segment (but doesn't start or end it) */ 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Is_Weak_Point; 956ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 958ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 9599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next_u = point + point->u; 9609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point prev_v = point + point->v; 9619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( ft_corner_is_flat( point->fx - prev_v->fx, 9649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->fy - prev_v->fy, 9659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->fx - point->fx, 9669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->fy - point->fy ) ) 9679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 9689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* either the `in' or the `out' vector is much more */ 9699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* dominant than the other one, so tag current point */ 9709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* as weak and update index deltas */ 9719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev_v->u = (FT_Pos)( next_u - prev_v ); 9739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->v = -prev_v->u; 9749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod goto Is_Weak_Point; 9769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 977ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->in_dir == -point->out_dir ) 980ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 981ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* current point forms a spike */ 982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Is_Weak_Point; 983ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 993aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Store the hinted outline in an FT_Outline structure. */ 994aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_save( AF_GlyphHints hints, 997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline* outline ) 998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point = hints->points; 1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point limit = point + hints->num_points; 1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector* vec = outline->points; 1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char* tag = outline->tags; 1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; point < limit; point++, vec++, tag++ ) 1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = point->x; 1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = point->y; 1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & AF_FLAG_CONIC ) 1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_CONIC; 1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->flags & AF_FLAG_CUBIC ) 1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_CUBIC; 1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_ON; 1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * EDGE POINT GRID-FITTING 1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1027aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Align all points of an edge to the same coordinate value, */ 1028aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* either horizontally or vertically. */ 1029aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_edge_points( AF_GlyphHints hints, 1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = & hints->axis[dim]; 1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segments = axis->segments; 1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segment_limit = segments + axis->num_segments; 1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment seg; 1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < segment_limit; seg++ ) 1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = seg->edge; 1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point, first, last; 1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge == NULL ) 1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first = seg->first; 1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = seg->last; 1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = first; 1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = edge->pos; 1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_TOUCH_X; 1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == last ) 1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = point->next; 1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < segment_limit; seg++ ) 1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = seg->edge; 1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point, first, last; 1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge == NULL ) 1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first = seg->first; 1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = seg->last; 1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = first; 1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = edge->pos; 1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_TOUCH_Y; 1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == last ) 1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = point->next; 1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * STRONG POINT INTERPOLATION 1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1102aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Hint the strong points -- this is equivalent to the TrueType `IP' */ 1103aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* hinting instruction. */ 1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_strong_points( AF_GlyphHints hints, 1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dim]; 1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges = axis->edges; 1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge_limit = edges + axis->num_edges; 1114fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt touch_flag; 1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_X; 1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_Y; 1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges < edge_limit ) 1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge; 1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos u, ou, fu; /* point position */ 1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta; 1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & touch_flag ) 1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if this point is candidate to weak interpolation, we */ 1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* interpolate it after all strong points have been processed */ 1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1140fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ) 1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_VERT ) 1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = point->fy; 1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ou = point->oy; 1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = point->fx; 1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ou = point->ox; 1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fu = u; 1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is the point before the first edge? */ 1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges; 1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = edge->fpos - u; 1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta >= 0 ) 1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos - ( edge->opos - ou ); 1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is the point after the last edge? */ 1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edge_limit - 1; 1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = u - edge->fpos; 1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta >= 0 ) 1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos + ( ou - edge->opos ); 1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1175295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_PtrDist min, max, mid; 1176aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos fpos; 1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find enclosing edges */ 1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = edge_limit - edges; 1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1 1184aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* for a small number of edges, a linear search is better */ 1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( max <= 8 ) 1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1187295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_PtrDist nn; 1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1189aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < max; nn++ ) 1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges[nn].fpos >= u ) 1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges[nn].fpos == u ) 1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edges[nn].pos; 1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = nn; 1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( max + min ) >> 1; 1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges + mid; 1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fpos = edge->fpos; 1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u < fpos ) 1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u > fpos ) 1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we are on the edge */ 1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos; 1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1221aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* point is not on an edge */ 1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge before = edges + min - 1; 1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge after = edges + min + 0; 1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* assert( before && after && before != after ) */ 1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( before->scale == 0 ) 1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project before->scale = FT_DivFix( after->pos - before->pos, 1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project after->fpos - before->fpos ); 1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = before->pos + FT_MulFix( fu - before->fpos, 1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project before->scale ); 1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Store_Point: 1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* save the point position */ 1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = u; 1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = u; 1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= touch_flag; 1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * WEAK POINT INTERPOLATION 1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1257aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Shift the original coordinates of all points between `p1' and */ 1258aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* `p2' to get hinted coordinates, using the same difference as */ 1259aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* given by `ref'. */ 1260aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_shift( AF_Point p1, 1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p2, 1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref ) 1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p; 1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta = ref->u - ref->v; 1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1269aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta == 0 ) 1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p < ref; p++ ) 1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = p->v + delta; 1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = ref + 1; p <= p2; p++ ) 1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = p->v + delta; 1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1281aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Interpolate the original coordinates of all points between `p1' and */ 1282aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */ 1283aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* reference points. The `u' and `v' members are the current and */ 1284aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* original coordinate values, respectively. */ 1285aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* */ 1286aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Details can be found in the TrueType bytecode specification. */ 1287aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( AF_Point p1, 1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p2, 1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref1, 1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref2 ) 1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p; 1295fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Pos u, v1, v2, u1, u2, d1, d2; 1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p1 > p2 ) 1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1301fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ref1->v > ref2->v ) 1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1303fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki p = ref1; 1304fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ref1 = ref2; 1305fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ref2 = p; 1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1308fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki v1 = ref1->v; 1309fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki v2 = ref2->v; 1310fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u1 = ref1->u; 1311fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u2 = ref2->u; 1312fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki d1 = u1 - v1; 1313fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki d2 = u2 - v2; 1314fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1315fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( u1 == u2 || v1 == v2 ) 1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u <= v1 ) 1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u >= v2 ) 1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d2; 1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1326fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u = u1; 1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1333fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 ); 1334fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1335fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1340fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( u <= v1 ) 1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1342fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( u >= v2 ) 1343fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u += d2; 1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1345fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u = u1 + FT_MulFix( u - v1, scale ); 1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1353aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Hint the weak points -- this is equivalent to the TrueType `IUP' */ 1354aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* hinting instruction. */ 1355aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_weak_points( AF_GlyphHints hints, 1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour = hints->contours; 1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour_limit = contour + hints->num_contours; 1364fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt touch_flag; 1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point end_point; 1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point first_point; 1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* PASS 1: Move segment points to edge positions */ 1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_X; 1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->u = point->x; 1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->v = point->ox; 1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_Y; 1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->u = point->y; 1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->v = point->oy; 1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; contour < contour_limit; contour++ ) 1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point first_touched, last_touched; 1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = *contour; 1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end_point = point->prev; 1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_point = point; 1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find first touched point */ 1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point > end_point ) /* no touched point in contour */ 1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NextContour; 1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & touch_flag ) 1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_touched = point; 1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1418aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_ASSERT( point <= end_point && 1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ( point->flags & touch_flag ) != 0 ); 1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1421aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* skip any touched neighbours */ 1422aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner while ( point < end_point && 1423aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner ( point[1].flags & touch_flag ) != 0 ) 1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched = point; 1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find the next touched point, if any */ 1429aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner point++; 1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point > end_point ) 1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto EndContour; 1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( point->flags & touch_flag ) != 0 ) 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* interpolate between last_touched and point */ 1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( last_touched + 1, point - 1, 1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, point ); 1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project EndContour: 1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* special case: only one point was touched */ 1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_touched == first_touched ) 1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_shift( first_point, end_point, first_touched ); 1450aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* interpolate the last part */ 1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_touched < end_point ) 1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( last_touched + 1, end_point, 1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, first_touched ); 1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( first_touched > points ) 1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( first_point, first_touched - 1, 1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, first_touched ); 1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project NextContour: 1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ; 1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now save the interpolated values back to x/y */ 1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = point->u; 1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = point->u; 1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1480aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef AF_CONFIG_OPTION_USE_WARPER 1481aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1482aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Apply (small) warp scale and warp delta for given dimension. */ 1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_scale_dim( AF_GlyphHints hints, 1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim, 1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed scale, 1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta ) 1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points_limit = points + hints->num_points; 1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < points_limit; point++ ) 1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = FT_MulFix( point->fx, scale ) + delta; 1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < points_limit; point++ ) 1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = FT_MulFix( point->fy, scale ) + delta; 1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1507aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* AF_CONFIG_OPTION_USE_WARPER */ 1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 1510