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/* */ 7a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin/* Copyright 2003-2017 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 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 { 48a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !axis->segments ) 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, 102055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Bool top_to_bottom_hinting, 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Edge *anedge ) 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = NULL; 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges; 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 111fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->num_edges < AF_EDGES_EMBEDDED ) 112fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 113a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !axis->edges ) 114fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 115fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki axis->edges = axis->embedded.edges; 116fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki axis->max_edges = AF_EDGES_EMBEDDED; 117fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 118fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 119fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( axis->num_edges >= axis->max_edges ) 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int old_max = axis->max_edges; 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int new_max = old_max; 123295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_max >= big_max ) 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max += ( new_max >> 2 ) + 4; 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max < old_max || new_max > big_max ) 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = big_max; 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 136fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->edges == axis->embedded.edges ) 137fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 138fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_NEW_ARRAY( axis->edges, new_max ) ) 139fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 140fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ft_memcpy( axis->edges, axis->embedded.edges, 141fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki sizeof ( axis->embedded.edges ) ); 142fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 143fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 144fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 145fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) 146fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 147fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->max_edges = new_max; 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edges = axis->edges; 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges + axis->num_edges; 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( edge > edges ) 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 157055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos ) 158055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin : ( edge[-1].fpos < fpos ) ) 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we want the edge with same position and minor direction */ 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to appear before those in the major one in the list */ 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge[-1].fpos == fpos && dir == axis->major_dir ) 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge[0] = edge[-1]; 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge--; 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->num_edges++; 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 173727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *anedge = edge; 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 178aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef FT_DEBUG_AUTOFIT 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include FT_CONFIG_STANDARD_LIBRARY_H 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 182ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* The dump functions are used in the `ftgrid' demo program, too. */ 183ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#define AF_DUMP( varformat ) \ 184ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease do \ 185ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { \ 186ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( to_stdout ) \ 187ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease printf varformat; \ 188ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease else \ 189ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_TRACE7( varformat ); \ 190ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } while ( 0 ) 191ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 192ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const char* 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_dir_str( AF_Direction dir ) 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const char* result; 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( dir ) 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_UP: 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "up"; 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_DOWN: 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "down"; 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_LEFT: 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "left"; 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_RIGHT: 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "right"; 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "none"; 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 221fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 ) 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 224055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin static char* 225055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( char* p, 226055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int idx ) 227055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 228055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( idx == -1 ) 229055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 230055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin p[0] = '-'; 231055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin p[1] = '-'; 232055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin p[2] = '\0'; 233055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 234055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 235055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ft_sprintf( p, "%d", idx ); 236055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 237055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return p; 238055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 239055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 240055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 241055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin static int 242055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_get_segment_index( AF_GlyphHints hints, 243055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int point_idx, 244055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int dimension ) 245055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 246055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_AxisHints axis = &hints->axis[dimension]; 247055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point point = hints->points + point_idx; 248055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Segment segments = axis->segments; 249055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Segment limit = segments + axis->num_segments; 250055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Segment segment; 251055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 252055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 253055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for ( segment = segments; segment < limit; segment++ ) 254055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 255055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( segment->first <= segment->last ) 256055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 257055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( point >= segment->first && point <= segment->last ) 258055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 259055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 260055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 261055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 262055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point p = segment->first; 263055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 264055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 265055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for (;;) 266055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 267055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( point == p ) 268055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Exit; 269055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 270055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( p == segment->last ) 271055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 272055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 273055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin p = p->next; 274055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 275055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 276055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 277055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 278055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Exit: 279055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( segment == limit ) 280055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return -1; 281055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 282055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return (int)( segment - segments ); 283055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 284055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 285055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 286055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin static int 287055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_get_edge_index( AF_GlyphHints hints, 288055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int segment_idx, 289055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int dimension ) 290055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 291055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_AxisHints axis = &hints->axis[dimension]; 292055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Edge edges = axis->edges; 293055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Segment segment = axis->segments + segment_idx; 294055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 295055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 296055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges ); 297055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 298055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 299055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 300aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 301aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 302aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 304ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_points( AF_GlyphHints hints, 305ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 307055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point points = hints->points; 308055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point limit = points + hints->num_points; 309055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point* contour = hints->contours; 310055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point* climit = contour + hints->num_contours; 311055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point point; 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 314fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_DUMP(( "Table of points:\n" )); 315fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 316fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->num_points ) 317055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( " index hedge hseg vedge vseg flags " 318055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " xorg yorg xscale yscale xfit yfit" )); 319fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 320fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_DUMP(( " (none)\n" )); 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < limit; point++ ) 323055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 324055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int point_idx = AF_INDEX_NUM( point, points ); 325055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 ); 326055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 ); 327055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 328055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char buf1[16], buf2[16], buf3[16], buf4[16]; 329055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 330055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 331055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* insert extra newline at the beginning of a contour */ 332055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( contour < climit && *contour == point ) 333055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 334055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( "\n" )); 335055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin contour++; 336055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 337055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 338055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( " %5d %5s %5s %5s %5s %s" 339055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " %5d %5d %7.2f %7.2f %7.2f %7.2f\n", 340055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin point_idx, 341055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf1, 342055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_get_edge_index( hints, segment_idx_1, 1 ) ), 343055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf2, segment_idx_1 ), 344055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf3, 345055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_get_edge_index( hints, segment_idx_0, 0 ) ), 346055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf4, segment_idx_0 ), 347055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ( point->flags & AF_FLAG_NEAR ) 348055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ? " near " 349055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 350055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin ? " weak " 351055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin : "strong", 352055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 353ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->fx, 354ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->fy, 355ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->ox / 64.0, 356ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->oy / 64.0, 357ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->x / 64.0, 358055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin point->y / 64.0 )); 359055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 360ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 362aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 363aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 364aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const char* 368fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_edge_flags_to_string( FT_UInt flags ) 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static char temp[32]; 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int pos = 0; 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( flags & AF_EDGE_ROUND ) 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project ft_memcpy( temp + pos, "round", 5 ); 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos += 5; 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( flags & AF_EDGE_SERIF ) 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos > 0 ) 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project temp[pos++] = ' '; 3830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project ft_memcpy( temp + pos, "serif", 5 ); 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos += 5; 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos == 0 ) 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return "normal"; 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 389727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease temp[pos] = '\0'; 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return temp; 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 395aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Dump the array of linked segments. */ 396aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 397aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 398aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 399aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 401ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_segments( AF_GlyphHints hints, 402ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int dimension; 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( dimension = 1; dimension >= 0; dimension-- ) 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dimension]; 410727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Point points = hints->points; 411727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Edge edges = axis->edges; 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segments = axis->segments; 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment limit = segments + axis->num_segments; 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment seg; 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 416055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char buf1[16], buf2[16], buf3[16]; 417055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 419ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "Table of %s segments:\n", 420ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ ? "vertical" 421ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : "horizontal" )); 422727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( axis->num_segments ) 423055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( " index pos delta dir from to " 424055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " link serif edge" 425055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " height extra flags\n" )); 426727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 427ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " (none)\n" )); 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < limit; seg++ ) 430055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( " %5d %5d %5d %5s %4d %4d" 431055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " %4s %5s %4s" 432055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " %6d %5d %11s\n", 433fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_INDEX_NUM( seg, segments ), 434055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin seg->pos, 435055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin seg->delta, 436ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_dir_str( (AF_Direction)seg->dir ), 437ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->first, points ), 438ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->last, points ), 439055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 440055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ), 441055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ), 442055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ), 443055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 444ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg->height, 445ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg->height - ( seg->max_coord - seg->min_coord ), 446fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_edge_flags_to_string( seg->flags ) )); 447ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 450aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 451aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 452aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 453aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 454aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 455aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Fetch number of segments. */ 456aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 457aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 458aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 459aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 460aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Error 461aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner af_glyph_hints_get_num_segments( AF_GlyphHints hints, 462aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int dimension, 463aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int* num_segments ) 464aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner { 465aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Dimension dim; 466aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_AxisHints axis; 467aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 468aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 469aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; 470aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 471aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner axis = &hints->axis[dim]; 472aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner *num_segments = axis->num_segments; 473aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 474727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 475aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 476aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 477aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 478aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 479aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 480aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 481aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Fetch offset of segments into user supplied offset array. */ 482aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 483aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 484aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 485aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 486aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Error 487aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner af_glyph_hints_get_segment_offset( AF_GlyphHints hints, 488aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int dimension, 489aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int idx, 4909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos *offset, 4919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Bool *is_blue, 4929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos *blue_offset ) 493aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner { 494aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Dimension dim; 495aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_AxisHints axis; 496aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Segment seg; 497aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 498aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 499aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner if ( !offset ) 500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 501aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 502aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; 503aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 504aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner axis = &hints->axis[dim]; 505aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 506aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner if ( idx < 0 || idx >= axis->num_segments ) 507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 508aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 5099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod seg = &axis->segments[idx]; 5109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox 5119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod : seg->first->oy; 5129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( seg->edge ) 5139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); 5149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod else 5159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *is_blue = FALSE; 5169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 5179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( *is_blue ) 5189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *blue_offset = seg->edge->blue_edge->cur; 5199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod else 5209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *blue_offset = 0; 521aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 523aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 524aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 525aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 526aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 527aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 529aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Dump the array of linked edges. */ 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 531aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 532aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 533aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 535ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_edges( AF_GlyphHints hints, 536ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int dimension; 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( dimension = 1; dimension >= 0; dimension-- ) 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dimension]; 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges = axis->edges; 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge limit = edges + axis->num_edges; 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge; 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 548055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char buf1[16], buf2[16]; 549055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges 553aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner * since they have a constant X coordinate. 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 555055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( dimension == AF_DIMENSION_HORZ ) 556055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", 557055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin "vertical", 558055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 65536.0 * 64.0 / hints->x_scale, 559055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 10.0 * hints->x_scale / 65536.0 / 64.0 )); 560055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 561055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", 562055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin "horizontal", 563055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 65536.0 * 64.0 / hints->y_scale, 564055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 10.0 * hints->y_scale / 65536.0 / 64.0 )); 565055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 566727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( axis->num_edges ) 567055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( " index pos dir link serif" 568055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " blue opos pos flags\n" )); 569727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 570ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " (none)\n" )); 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( edge = edges; edge < limit; edge++ ) 573055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_DUMP(( " %5d %7.2f %5s %4s %5s" 574055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " %c %7.2f %7.2f %11s\n", 575fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki AF_INDEX_NUM( edge, edges ), 576ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease (int)edge->opos / 64.0, 577ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_dir_str( (AF_Direction)edge->dir ), 578055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ), 579055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ), 580055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 581ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->blue_edge ? 'y' : 'n', 582ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->opos / 64.0, 583ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->pos / 64.0, 584fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki af_edge_flags_to_string( edge->flags ) )); 585ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 588aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 589aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 590aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 592ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#undef AF_DUMP 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 594aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* !FT_DEBUG_AUTOFIT */ 595aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 596aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 597aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Compute the direction value of a given vector. */ 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( AF_Direction ) 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_direction_compute( FT_Pos dx, 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos dy ) 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos ll, ss; /* long and short arm lengths */ 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Direction dir; /* candidate direction */ 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= dx ) 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= -dx ) 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_UP; 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dy; 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dx; 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_LEFT; 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = -dx; 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dy; 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* dy < dx */ 623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= -dx ) 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_RIGHT; 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dx; 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dy; 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_DOWN; 633fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ll = -dy; 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dx; 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 638fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* return no direction if arm lengths do not differ enough */ 639727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ 640fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* the long arm is never negative */ 641fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ll <= 14 * FT_ABS( ss ) ) 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_NONE; 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return dir; 645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_init( AF_GlyphHints hints, 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 652fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* no need to initialize the embedded items */ 653fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) ); 654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->memory = memory; 655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_done( AF_GlyphHints hints ) 660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 661fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Memory memory; 662727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int dim; 663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 665727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !( hints && hints->memory ) ) 666727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return; 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 668fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki memory = hints->memory; 669fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 670727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* 671727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * note that we don't need to free the segment and edge 672727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * buffers since they are really within the hints->points array 673727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */ 674727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) 675727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 676727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_AxisHints axis = &hints->axis[dim]; 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 679727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->num_segments = 0; 680727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->max_segments = 0; 681fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->segments != axis->embedded.segments ) 682fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( axis->segments ); 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 684727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->num_edges = 0; 685727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->max_edges = 0; 686fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( axis->edges != axis->embedded.edges ) 687fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( axis->edges ); 688727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 690fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->contours != hints->embedded.contours ) 691fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( hints->contours ); 692727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->max_contours = 0; 693727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->num_contours = 0; 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 695fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->points != hints->embedded.points ) 696fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( hints->points ); 697727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->max_points = 0; 698fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->num_points = 0; 699727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 700727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->memory = NULL; 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 704aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Reset metrics. */ 705aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 7079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod af_glyph_hints_rescale( AF_GlyphHints hints, 7089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleMetrics metrics ) 709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->metrics = metrics; 711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->scaler_flags = metrics->scaler.flags; 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 715aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Recompute all AF_Point in AF_GlyphHints from the definitions */ 716aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* in a source outline. */ 717aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_reload( AF_GlyphHints hints, 720aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Outline* outline ) 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 722727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points; 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt old_max, new_max; 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed x_scale = hints->x_scale; 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed y_scale = hints->y_scale; 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos x_delta = hints->x_delta; 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos y_delta = hints->y_delta; 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = hints->memory; 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_points = 0; 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_contours = 0; 734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[0].num_segments = 0; 736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[0].num_edges = 0; 737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[1].num_segments = 0; 738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[1].num_edges = 0; 739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 740aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* first of all, reallocate the contours array if necessary */ 741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = (FT_UInt)outline->n_contours; 742fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki old_max = (FT_UInt)hints->max_contours; 743fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 744fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( new_max <= AF_CONTOURS_EMBEDDED ) 745fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 746a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !hints->contours ) 747fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 748fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->contours = hints->embedded.contours; 749fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_contours = AF_CONTOURS_EMBEDDED; 750fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 751fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 752fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( new_max > old_max ) 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 754fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->contours == hints->embedded.contours ) 755fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->contours = NULL; 756fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 757fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */ 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 762fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_contours = (FT_Int)new_max; 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * then reallocate the points arrays if necessary -- 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * note that we reserve two additional point positions, used to 768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * hint metrics appropriately 769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = (FT_UInt)( outline->n_points + 2 ); 771fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki old_max = (FT_UInt)hints->max_points; 772fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 773fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( new_max <= AF_POINTS_EMBEDDED ) 774fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 775a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !hints->points ) 776fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 777fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->points = hints->embedded.points; 778fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_points = AF_POINTS_EMBEDDED; 779fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 780fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 781fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( new_max > old_max ) 782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 783fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( hints->points == hints->embedded.points ) 784fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->points = NULL; 785fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 786fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */ 787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 791fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki hints->max_points = (FT_Int)new_max; 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_points = outline->n_points; 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_contours = outline->n_contours; 796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* We can't rely on the value of `FT_Outline.flags' to know the fill */ 798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* direction used for a glyph, given that some fonts are broken (e.g., */ 799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the Arphic ones). We thus recompute it each time we need to. */ 800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; 802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) 805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; 807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; 808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_scale = x_scale; 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->y_scale = y_scale; 812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_delta = x_delta; 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->y_delta = y_delta; 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->xmin_delta = 0; 816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->xmax_delta = 0; 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project points = hints->points; 819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( hints->num_points == 0 ) 820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 826055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* value 20 in `near_limit' is heuristic */ 827055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; 828055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int near_limit = 20 * units_per_em / 2048; 829055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* compute coordinates & Bezier flags, next and prev */ 832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector* vec = outline->points; 834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char* tag = outline->tags; 835055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Short endpoint = outline->contours[0]; 836055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin AF_Point end = points + endpoint; 837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point prev = end; 838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int contour_index = 0; 839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++, vec++, tag++ ) 842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 843055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Pos out_x, out_y; 844055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 845055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 8469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->in_dir = (FT_Char)AF_DIR_NONE; 8479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->out_dir = (FT_Char)AF_DIR_NONE; 8489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->fx = (FT_Short)vec->x; 850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->fy = (FT_Short)vec->y; 851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; 852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; 853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 854055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin end->fx = (FT_Short)outline->points[endpoint].x; 855055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin end->fy = (FT_Short)outline->points[endpoint].y; 856055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( FT_CURVE_TAG( *tag ) ) 858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_CURVE_TAG_CONIC: 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags = AF_FLAG_CONIC; 861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_CURVE_TAG_CUBIC: 863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags = AF_FLAG_CUBIC; 864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 866aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner point->flags = AF_FLAG_NONE; 867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 869055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin out_x = point->fx - prev->fx; 870055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin out_y = point->fy - prev->fy; 871055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 872055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) 873055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin prev->flags |= AF_FLAG_NEAR; 874055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->prev = prev; 876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev->next = point; 877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev = point; 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == end ) 880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ++contour_index < outline->n_contours ) 882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 883055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin endpoint = outline->contours[contour_index]; 884055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin end = points + endpoint; 885055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin prev = end; 886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 891aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* set up the contours array */ 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour = hints->contours; 894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour_limit = contour + hints->num_contours; 895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project short* end = outline->contours; 896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project short idx = 0; 897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; contour < contour_limit; contour++, end++ ) 900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project contour[0] = points + idx; 902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (short)( end[0] + 1 ); 903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 9079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 9089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Compute directions of `in' and `out' vectors. 9099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 9109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Note that distances between points that are very near to each 911055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * other are accumulated. In other words, the auto-hinter either 9129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * prepends the small vectors between near points to the first 913055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * non-near vector, or the sum of small vector lengths exceeds a 914055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * threshold, thus `grouping' the small vectors. All intermediate 915055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * points are tagged as weak; the directions are adjusted also to 916055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin * be equal to the accumulated one. 9179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 9189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 919055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int near_limit2 = 2 * near_limit - 1; 920ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point* contour; 9229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point* contour_limit = hints->contours + hints->num_contours; 923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 9249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( contour = hints->contours; contour < contour_limit; contour++ ) 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 9279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point first = *contour; 9289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next, prev, curr; 9299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos out_x, out_y; 9319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 9339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* since the first point of a contour could be part of a */ 9349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* series of near points, go backwards to find the first */ 9359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* non-near point and adjust `first' */ 9369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = first; 9389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev = first->prev; 9399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod while ( prev != first ) 941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 9429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = point->fx - prev->fx; 9439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = point->fy - prev->fy; 9449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 9469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * We use Taxicab metrics to measure the vector length. 9479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 9489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Note that the accumulated distances so far could have the 9499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * opposite direction of the distance measured here. For this 9509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * reason we use `near_limit2' for the comparison to get a 9519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-near point even in the worst case. 9529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 9539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) 9549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod break; 9559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = prev; 9579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev = prev->prev; 9589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 959ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* adjust first point */ 9619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first = point; 962ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* now loop over all points of the contour to get */ 9649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* `in' and `out' vector directions */ 965ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 966055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin curr = first; 967ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 9699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * We abuse the `u' and `v' fields to store index deltas to the 9709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * next and previous non-near point, respectively. 9719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 9729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * To avoid problems with not having non-near points, we point to 9739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * `first' by default as the next non-near point. 9749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 9759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 9769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( first - curr ); 9779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first->v = -curr->u; 978ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9799c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = 0; 9809c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = 0; 981ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 982fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki next = first; 983fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki do 9849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 9859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Direction out_dir; 986ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 987ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 988fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point = next; 989055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin next = point->next; 990ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 9919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x += next->fx - point->fx; 9929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y += next->fy - point->fy; 9939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) 9959c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 9969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->flags |= AF_FLAG_WEAK_INTERPOLATION; 9979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 998ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 999ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 10009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( next - curr ); 10019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->v = -curr->u; 10029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_dir = af_direction_compute( out_x, out_y ); 10049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* adjust directions for all points inbetween; */ 10069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* the loop also updates position of `curr' */ 10079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->out_dir = (FT_Char)out_dir; 10089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( curr = curr->next; curr != next; curr = curr->next ) 10099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 10109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->in_dir = (FT_Char)out_dir; 10119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->out_dir = (FT_Char)out_dir; 10129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 10139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->in_dir = (FT_Char)out_dir; 10149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( first - curr ); 10169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first->v = -curr->u; 10179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = 0; 10199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = 0; 1020fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1021fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } while ( next != first ); 10229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 10259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * The next step is to `simplify' an outline's topology so that we 10269c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * can identify local extrema more reliably: A series of 10279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-horizontal or non-vertical vectors pointing into the same 10289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * quadrant are handled as a single, long vector. From a 10299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * topological point of the view, the intermediate points are of no 10309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * interest and thus tagged as weak. 10319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = points; point < point_limit; point++ ) 10349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 10359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 10369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 1037ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 10389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->in_dir == AF_DIR_NONE && 10399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->out_dir == AF_DIR_NONE ) 1040ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 10419c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* check whether both vectors point into the same quadrant */ 10429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos in_x, in_y; 10449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos out_x, out_y; 10459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next_u = point + point->u; 10479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point prev_v = point + point->v; 10489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 1049ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 10509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod in_x = point->fx - prev_v->fx; 10519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod in_y = point->fy - prev_v->fy; 10529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = next_u->fx - point->fx; 10549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = next_u->fy - point->fy; 10559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 ) 10579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 10589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* yes, so tag current point as weak */ 10599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* and update index deltas */ 10609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->flags |= AF_FLAG_WEAK_INTERPOLATION; 10629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev_v->u = (FT_Pos)( next_u - prev_v ); 10649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->v = -prev_v->u; 10659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 10669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 10679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 10709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Finally, check for remaining weak points. Everything else not 10719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * collected in edges so far is then implicitly classified as strong 10729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * points. 10739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = points; point < point_limit; point++ ) 10769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 10779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 10789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 1079aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1080727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( point->flags & AF_FLAG_CONTROL ) 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1082ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* control points are always weak */ 1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Is_Weak_Point: 1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_WEAK_INTERPOLATION; 1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->out_dir == point->in_dir ) 1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->out_dir != AF_DIR_NONE ) 1089ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1090ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* current point lies on a horizontal or */ 1091ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* vertical segment (but doesn't start or end it) */ 1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Is_Weak_Point; 1093ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1095ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 10969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next_u = point + point->u; 10979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point prev_v = point + point->v; 10989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 10999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 11009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( ft_corner_is_flat( point->fx - prev_v->fx, 11019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->fy - prev_v->fy, 11029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->fx - point->fx, 11039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->fy - point->fy ) ) 11049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 11059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* either the `in' or the `out' vector is much more */ 11069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* dominant than the other one, so tag current point */ 11079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* as weak and update index deltas */ 11089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 11099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev_v->u = (FT_Pos)( next_u - prev_v ); 11109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->v = -prev_v->u; 11119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 11129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod goto Is_Weak_Point; 11139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 1114ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->in_dir == -point->out_dir ) 1117ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 1118ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* current point forms a spike */ 1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Is_Weak_Point; 1120ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1130aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Store the hinted outline in an FT_Outline structure. */ 1131aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_save( AF_GlyphHints hints, 1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline* outline ) 1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point = hints->points; 1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point limit = point + hints->num_points; 1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector* vec = outline->points; 1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char* tag = outline->tags; 1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; point < limit; point++, vec++, tag++ ) 1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = point->x; 1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = point->y; 1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & AF_FLAG_CONIC ) 1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_CONIC; 1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->flags & AF_FLAG_CUBIC ) 1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_CUBIC; 1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_ON; 1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * EDGE POINT GRID-FITTING 1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1164aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Align all points of an edge to the same coordinate value, */ 1165aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* either horizontally or vertically. */ 1166aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_edge_points( AF_GlyphHints hints, 1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = & hints->axis[dim]; 1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segments = axis->segments; 1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segment_limit = segments + axis->num_segments; 1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment seg; 1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < segment_limit; seg++ ) 1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = seg->edge; 1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point, first, last; 1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1185a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !edge ) 1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first = seg->first; 1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = seg->last; 1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = first; 1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = edge->pos; 1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_TOUCH_X; 1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == last ) 1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = point->next; 1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < segment_limit; seg++ ) 1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = seg->edge; 1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point, first, last; 1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1211a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !edge ) 1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first = seg->first; 1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = seg->last; 1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = first; 1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = edge->pos; 1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_TOUCH_Y; 1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == last ) 1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = point->next; 1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * STRONG POINT INTERPOLATION 1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1239aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Hint the strong points -- this is equivalent to the TrueType `IP' */ 1240aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* hinting instruction. */ 1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_strong_points( AF_GlyphHints hints, 1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dim]; 1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges = axis->edges; 1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge_limit = edges + axis->num_edges; 1251fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt touch_flag; 1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_X; 1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_Y; 1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges < edge_limit ) 1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge; 1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos u, ou, fu; /* point position */ 1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta; 1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & touch_flag ) 1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if this point is candidate to weak interpolation, we */ 1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* interpolate it after all strong points have been processed */ 1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1277fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ) 1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_VERT ) 1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = point->fy; 1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ou = point->oy; 1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = point->fx; 1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ou = point->ox; 1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fu = u; 1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is the point before the first edge? */ 1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges; 1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = edge->fpos - u; 1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta >= 0 ) 1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos - ( edge->opos - ou ); 1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is the point after the last edge? */ 1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edge_limit - 1; 1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = u - edge->fpos; 1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta >= 0 ) 1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos + ( ou - edge->opos ); 1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1312295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_PtrDist min, max, mid; 1313aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos fpos; 1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find enclosing edges */ 1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = edge_limit - edges; 1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1 1321aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* for a small number of edges, a linear search is better */ 1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( max <= 8 ) 1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1324295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_PtrDist nn; 1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1326aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < max; nn++ ) 1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges[nn].fpos >= u ) 1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges[nn].fpos == u ) 1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edges[nn].pos; 1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = nn; 1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( max + min ) >> 1; 1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges + mid; 1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fpos = edge->fpos; 1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u < fpos ) 1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u > fpos ) 1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we are on the edge */ 1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos; 1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1358aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* point is not on an edge */ 1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge before = edges + min - 1; 1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge after = edges + min + 0; 1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* assert( before && after && before != after ) */ 1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( before->scale == 0 ) 1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project before->scale = FT_DivFix( after->pos - before->pos, 1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project after->fpos - before->fpos ); 1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = before->pos + FT_MulFix( fu - before->fpos, 1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project before->scale ); 1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Store_Point: 1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* save the point position */ 1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = u; 1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = u; 1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= touch_flag; 1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * WEAK POINT INTERPOLATION 1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1394aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Shift the original coordinates of all points between `p1' and */ 1395aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* `p2' to get hinted coordinates, using the same difference as */ 1396aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* given by `ref'. */ 1397aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_shift( AF_Point p1, 1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p2, 1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref ) 1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p; 1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta = ref->u - ref->v; 1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1406aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta == 0 ) 1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p < ref; p++ ) 1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = p->v + delta; 1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = ref + 1; p <= p2; p++ ) 1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = p->v + delta; 1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1418aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Interpolate the original coordinates of all points between `p1' and */ 1419aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */ 1420aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* reference points. The `u' and `v' members are the current and */ 1421aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* original coordinate values, respectively. */ 1422aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* */ 1423aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Details can be found in the TrueType bytecode specification. */ 1424aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( AF_Point p1, 1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p2, 1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref1, 1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref2 ) 1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p; 1432fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Pos u, v1, v2, u1, u2, d1, d2; 1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p1 > p2 ) 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1438fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ref1->v > ref2->v ) 1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1440fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki p = ref1; 1441fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ref1 = ref2; 1442fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ref2 = p; 1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1445fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki v1 = ref1->v; 1446fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki v2 = ref2->v; 1447fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u1 = ref1->u; 1448fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u2 = ref2->u; 1449fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki d1 = u1 - v1; 1450fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki d2 = u2 - v2; 1451fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1452fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( u1 == u2 || v1 == v2 ) 1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u <= v1 ) 1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u >= v2 ) 1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d2; 1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1463fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u = u1; 1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1470fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Fixed scale = FT_DivFix( u2 - u1, v2 - v1 ); 1471fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1472fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1477fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( u <= v1 ) 1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1479fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( u >= v2 ) 1480fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u += d2; 1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1482fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki u = u1 + FT_MulFix( u - v1, scale ); 1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1490aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Hint the weak points -- this is equivalent to the TrueType `IUP' */ 1491aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* hinting instruction. */ 1492aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_weak_points( AF_GlyphHints hints, 1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour = hints->contours; 1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour_limit = contour + hints->num_contours; 1501fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt touch_flag; 1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point end_point; 1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point first_point; 1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* PASS 1: Move segment points to edge positions */ 1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_X; 1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->u = point->x; 1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->v = point->ox; 1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_Y; 1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->u = point->y; 1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->v = point->oy; 1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; contour < contour_limit; contour++ ) 1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point first_touched, last_touched; 1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = *contour; 1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end_point = point->prev; 1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_point = point; 1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find first touched point */ 1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point > end_point ) /* no touched point in contour */ 1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NextContour; 1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & touch_flag ) 1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_touched = point; 1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1555aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_ASSERT( point <= end_point && 1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ( point->flags & touch_flag ) != 0 ); 1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1558aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* skip any touched neighbours */ 1559aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner while ( point < end_point && 1560aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner ( point[1].flags & touch_flag ) != 0 ) 1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched = point; 1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find the next touched point, if any */ 1566aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner point++; 1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point > end_point ) 1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto EndContour; 1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( point->flags & touch_flag ) != 0 ) 1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* interpolate between last_touched and point */ 1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( last_touched + 1, point - 1, 1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, point ); 1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project EndContour: 1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* special case: only one point was touched */ 1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_touched == first_touched ) 1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_shift( first_point, end_point, first_touched ); 1587aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* interpolate the last part */ 1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_touched < end_point ) 1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( last_touched + 1, end_point, 1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, first_touched ); 1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( first_touched > points ) 1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( first_point, first_touched - 1, 1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, first_touched ); 1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project NextContour: 1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ; 1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now save the interpolated values back to x/y */ 1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = point->u; 1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = point->u; 1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1617aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef AF_CONFIG_OPTION_USE_WARPER 1618aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1619aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Apply (small) warp scale and warp delta for given dimension. */ 1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_scale_dim( AF_GlyphHints hints, 1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim, 1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed scale, 1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta ) 1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points_limit = points + hints->num_points; 1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < points_limit; point++ ) 1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = FT_MulFix( point->fx, scale ) + delta; 1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < points_limit; point++ ) 1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = FT_MulFix( point->fy, scale ) + delta; 1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1644aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* AF_CONFIG_OPTION_USE_WARPER */ 1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 1647