afhints.c revision 9c745321260bb728ab1cd1c8fd5f075854b2ad49
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/* */ 79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/* Copyright 2003-2007, 2009-2014 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 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( axis->num_segments >= axis->max_segments ) 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int old_max = axis->max_segments; 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int new_max = old_max; 50295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_max >= big_max ) 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 55727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max += ( new_max >> 2 ) + 4; 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max < old_max || new_max > big_max ) 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = big_max; 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->max_segments = new_max; 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project segment = axis->segments + axis->num_segments++; 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *asegment = segment; 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 77aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Get new edge for given axis, direction, and position. */ 78aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL( FT_Error ) 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_axis_hints_new_edge( AF_AxisHints axis, 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int fpos, 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Direction dir, 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 84727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Edge *anedge ) 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 86727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = NULL; 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges; 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( axis->num_edges >= axis->max_edges ) 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int old_max = axis->max_edges; 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int new_max = old_max; 95295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( old_max >= big_max ) 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max += ( new_max >> 2 ) + 4; 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max < old_max || new_max > big_max ) 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = big_max; 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->max_edges = new_max; 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edges = axis->edges; 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges + axis->num_edges; 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( edge > edges ) 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge[-1].fpos < fpos ) 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we want the edge with same position and minor direction */ 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to appear before those in the major one in the list */ 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge[-1].fpos == fpos && dir == axis->major_dir ) 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge[0] = edge[-1]; 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge--; 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project axis->num_edges++; 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ZERO( edge ); 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge->fpos = (FT_Short)fpos; 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge->dir = (FT_Char)dir; 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 138727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *anedge = edge; 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 143aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef FT_DEBUG_AUTOFIT 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include FT_CONFIG_STANDARD_LIBRARY_H 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 147ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* The dump functions are used in the `ftgrid' demo program, too. */ 148ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#define AF_DUMP( varformat ) \ 149ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease do \ 150ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { \ 151ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( to_stdout ) \ 152ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease printf varformat; \ 153ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease else \ 154ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_TRACE7( varformat ); \ 155ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } while ( 0 ) 156ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 157ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const char* 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_dir_str( AF_Direction dir ) 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const char* result; 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( dir ) 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_UP: 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "up"; 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_DOWN: 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "down"; 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_LEFT: 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "left"; 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case AF_DIR_RIGHT: 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "right"; 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = "none"; 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 189aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 190aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 191aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 193ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_points( AF_GlyphHints hints, 194ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point limit = points + hints->num_points; 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 201ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "Table of points:\n" 202ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " [ index | xorg | yorg | xscale | yscale" 203ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | xfit | yfit | flags ]\n" )); 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < limit; point++ ) 206ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ %5d | %5d | %5d | %6.2f | %6.2f" 207ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n", 208ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point - points, 209ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->fx, 210ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->fy, 211ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->ox / 64.0, 212ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->oy / 64.0, 213ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->x / 64.0, 214ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease point->y / 64.0, 215ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', 216ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', 217ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', 218ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', 219ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', 220ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' ')); 221ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 223aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 224aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 225aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const char* 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_edge_flags_to_string( AF_Edge_Flags flags ) 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static char temp[32]; 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project int pos = 0; 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( flags & AF_EDGE_ROUND ) 236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project ft_memcpy( temp + pos, "round", 5 ); 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos += 5; 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( flags & AF_EDGE_SERIF ) 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos > 0 ) 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project temp[pos++] = ' '; 2440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project ft_memcpy( temp + pos, "serif", 5 ); 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos += 5; 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( pos == 0 ) 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return "normal"; 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 250727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease temp[pos] = '\0'; 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return temp; 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 256aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Dump the array of linked segments. */ 257aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 258aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 259aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 260aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 262ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_segments( AF_GlyphHints hints, 263ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int dimension; 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( dimension = 1; dimension >= 0; dimension-- ) 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dimension]; 271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Point points = hints->points; 272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_Edge edges = axis->edges; 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segments = axis->segments; 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment limit = segments + axis->num_segments; 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment seg; 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 278ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "Table of %s segments:\n", 279ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ ? "vertical" 280ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : "horizontal" )); 281727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( axis->num_segments ) 282ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ index | pos | dir | from" 283ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | to | link | serif | edge" 284ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | height | extra | flags ]\n" )); 285727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 286ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " (none)\n" )); 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < limit; seg++ ) 289ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ %5d | %5.2g | %5s | %4d" 290ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %4d | %4d | %5d | %4d" 291ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %6d | %5d | %11s ]\n", 292ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg - segments, 293ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ 294ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ? (int)seg->first->ox / 64.0 295ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : (int)seg->first->oy / 64.0, 296ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_dir_str( (AF_Direction)seg->dir ), 297ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->first, points ), 298ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->last, points ), 299ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->link, segments ), 300ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->serif, segments ), 301ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( seg->edge, edges ), 302ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg->height, 303ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease seg->height - ( seg->max_coord - seg->min_coord ), 304ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) )); 305ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 308aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 309aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 310aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 311aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 312aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 313aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Fetch number of segments. */ 314aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 315aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 316aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 317aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 318aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Error 319aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner af_glyph_hints_get_num_segments( AF_GlyphHints hints, 320aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int dimension, 321aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int* num_segments ) 322aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner { 323aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Dimension dim; 324aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_AxisHints axis; 325aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 326aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 327aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; 328aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 329aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner axis = &hints->axis[dim]; 330aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner *num_segments = axis->num_segments; 331aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 333aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 334aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 335aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 336aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 337aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 338aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 339aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Fetch offset of segments into user supplied offset array. */ 340aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 341aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 342aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 343aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 344aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Error 345aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner af_glyph_hints_get_segment_offset( AF_GlyphHints hints, 346aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int dimension, 347aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_Int idx, 3489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos *offset, 3499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Bool *is_blue, 3509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos *blue_offset ) 351aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner { 352aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Dimension dim; 353aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_AxisHints axis; 354aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner AF_Segment seg; 355aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 356aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 357aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner if ( !offset ) 358727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 359aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 360aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT; 361aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 362aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner axis = &hints->axis[dim]; 363aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 364aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner if ( idx < 0 || idx >= axis->num_segments ) 365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 366aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 3679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod seg = &axis->segments[idx]; 3689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox 3699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod : seg->first->oy; 3709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( seg->edge ) 3719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); 3729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod else 3739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *is_blue = FALSE; 3749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 3759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( *is_blue ) 3769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *blue_offset = seg->edge->blue_edge->cur; 3779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod else 3789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod *blue_offset = 0; 379aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 380727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 381aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 382aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 383aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 384aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 385aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 387aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Dump the array of linked edges. */ 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 389aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 390aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner extern "C" { 391aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void 393ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_glyph_hints_dump_edges( AF_GlyphHints hints, 394ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool to_stdout ) 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int dimension; 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( dimension = 1; dimension >= 0; dimension-- ) 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dimension]; 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges = axis->edges; 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge limit = edges + axis->num_edges; 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge; 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges 409aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner * since they have a constant X coordinate. 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 411ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "Table of %s edges:\n", 412ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease dimension == AF_DIMENSION_HORZ ? "vertical" 413ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease : "horizontal" )); 414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( axis->num_edges ) 415ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ index | pos | dir | link" 416ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | serif | blue | opos | pos | flags ]\n" )); 417727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 418ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " (none)\n" )); 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( edge = edges; edge < limit; edge++ ) 421ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( " [ %5d | %5.2g | %5s | %4d" 422ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease " | %5d | %c | %5.2f | %5.2f | %11s ]\n", 423ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge - edges, 424ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease (int)edge->opos / 64.0, 425ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_dir_str( (AF_Direction)edge->dir ), 426ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( edge->link, edges ), 427ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_INDEX_NUM( edge->serif, edges ), 428ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->blue_edge ? 'y' : 'n', 429ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->opos / 64.0, 430ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease edge->pos / 64.0, 431ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) )); 432ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease AF_DUMP(( "\n" )); 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 435aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef __cplusplus 436aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner } 437aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 439ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#undef AF_DUMP 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 441aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* !FT_DEBUG_AUTOFIT */ 442aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 443aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 444aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Compute the direction value of a given vector. */ 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( AF_Direction ) 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_direction_compute( FT_Pos dx, 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos dy ) 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos ll, ss; /* long and short arm lengths */ 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Direction dir; /* candidate direction */ 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= dx ) 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= -dx ) 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_UP; 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dy; 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dx; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_LEFT; 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = -dx; 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dy; 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* dy < dx */ 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dy >= -dx ) 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_RIGHT; 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dx; 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dy; 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_DOWN; 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ll = dy; 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss = dx; 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 485727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* return no direction if arm lengths differ too much */ 486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */ 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ss *= 14; 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_ABS( ll ) <= FT_ABS( ss ) ) 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dir = AF_DIR_NONE; 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return dir; 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_init( AF_GlyphHints hints, 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ZERO( hints ); 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->memory = memory; 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_done( AF_GlyphHints hints ) 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Memory memory = hints->memory; 508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int dim; 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !( hints && hints->memory ) ) 512727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return; 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* 515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * note that we don't need to free the segment and edge 516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease * buffers since they are really within the hints->points array 517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease */ 518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) 519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease AF_AxisHints axis = &hints->axis[dim]; 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->num_segments = 0; 524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->max_segments = 0; 525727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FREE( axis->segments ); 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->num_edges = 0; 528727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease axis->max_edges = 0; 529727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FREE( axis->edges ); 530727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 532727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FREE( hints->contours ); 533727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->max_contours = 0; 534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->num_contours = 0; 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 536727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FREE( hints->points ); 537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->num_points = 0; 538727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->max_points = 0; 539727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 540727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease hints->memory = NULL; 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 544aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Reset metrics. */ 545aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 5479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod af_glyph_hints_rescale( AF_GlyphHints hints, 5489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_StyleMetrics metrics ) 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->metrics = metrics; 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->scaler_flags = metrics->scaler.flags; 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 555aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Recompute all AF_Point in AF_GlyphHints from the definitions */ 556aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* in a source outline. */ 557aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_reload( AF_GlyphHints hints, 560aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Outline* outline ) 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 562727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points; 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt old_max, new_max; 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed x_scale = hints->x_scale; 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed y_scale = hints->y_scale; 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos x_delta = hints->x_delta; 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos y_delta = hints->y_delta; 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = hints->memory; 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_points = 0; 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_contours = 0; 574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[0].num_segments = 0; 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[0].num_edges = 0; 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[1].num_segments = 0; 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[1].num_edges = 0; 579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 580aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* first of all, reallocate the contours array if necessary */ 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = (FT_UInt)outline->n_contours; 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project old_max = hints->max_contours; 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max > old_max ) 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 585aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->max_contours = new_max; 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * then reallocate the points arrays if necessary -- 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * note that we reserve two additional point positions, used to 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * hint metrics appropriately 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project new_max = (FT_UInt)( outline->n_points + 2 ); 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project old_max = hints->max_points; 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( new_max > old_max ) 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 602aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->max_points = new_max; 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_points = outline->n_points; 611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->num_contours = outline->n_contours; 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* We can't rely on the value of `FT_Outline.flags' to know the fill */ 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* direction used for a glyph, given that some fonts are broken (e.g., */ 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the Arphic ones). We thus recompute it each time we need to. */ 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; 623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_scale = x_scale; 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->y_scale = y_scale; 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->x_delta = x_delta; 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->y_delta = y_delta; 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->xmin_delta = 0; 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hints->xmax_delta = 0; 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project points = hints->points; 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( hints->num_points == 0 ) 636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* compute coordinates & Bezier flags, next and prev */ 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector* vec = outline->points; 646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char* tag = outline->tags; 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point end = points + outline->contours[0]; 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point prev = end; 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int contour_index = 0; 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++, vec++, tag++ ) 653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 6549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->in_dir = (FT_Char)AF_DIR_NONE; 6559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->out_dir = (FT_Char)AF_DIR_NONE; 6569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->fx = (FT_Short)vec->x; 658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->fy = (FT_Short)vec->y; 659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; 660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; 661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( FT_CURVE_TAG( *tag ) ) 663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_CURVE_TAG_CONIC: 665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags = AF_FLAG_CONIC; 666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case FT_CURVE_TAG_CUBIC: 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags = AF_FLAG_CUBIC; 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default: 671aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner point->flags = AF_FLAG_NONE; 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->prev = prev; 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev->next = point; 676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev = point; 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == end ) 679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ++contour_index < outline->n_contours ) 681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 682aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich end = points + outline->contours[contour_index]; 683aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich prev = end; 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 689aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* set up the contours array */ 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour = hints->contours; 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour_limit = contour + hints->num_contours; 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project short* end = outline->contours; 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project short idx = 0; 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; contour < contour_limit; contour++, end++ ) 698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project contour[0] = points + idx; 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (short)( end[0] + 1 ); 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 7059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 7069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Compute directions of `in' and `out' vectors. 7079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 7089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Note that distances between points that are very near to each 7099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * other are accumulated. In other words, the auto-hinter 7109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * prepends the small vectors between near points to the first 7119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-near vector. All intermediate points are tagged as 7129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * weak; the directions are adjusted also to be equal to the 7139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * accumulated one. 7149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 7159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* value 20 in `near_limit' is heuristic */ 717ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; 718ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Int near_limit = 20 * units_per_em / 2048; 7199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Int near_limit2 = 2 * near_limit - 1; 720ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point* contour; 7229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point* contour_limit = hints->contours + hints->num_contours; 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 7249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( contour = hints->contours; contour < contour_limit; contour++ ) 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 7279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point first = *contour; 7289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next, prev, curr; 7299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos out_x, out_y; 7319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Bool is_first; 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 7359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* since the first point of a contour could be part of a */ 7369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* series of near points, go backwards to find the first */ 7379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* non-near point and adjust `first' */ 7389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = first; 7409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev = first->prev; 7419c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod while ( prev != first ) 743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 7449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = point->fx - prev->fx; 7459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = point->fy - prev->fy; 7469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 7489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * We use Taxicab metrics to measure the vector length. 7499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 7509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Note that the accumulated distances so far could have the 7519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * opposite direction of the distance measured here. For this 7529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * reason we use `near_limit2' for the comparison to get a 7539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-near point even in the worst case. 7549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 7559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 ) 7569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod break; 7579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 7589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = prev; 7599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev = prev->prev; 7609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 761ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* adjust first point */ 7639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first = point; 764ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* now loop over all points of the contour to get */ 7669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* `in' and `out' vector directions */ 767ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr = first; 769ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 7719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * We abuse the `u' and `v' fields to store index deltas to the 7729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * next and previous non-near point, respectively. 7739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 7749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * To avoid problems with not having non-near points, we point to 7759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * `first' by default as the next non-near point. 7769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * 7779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 7789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( first - curr ); 7799c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first->v = -curr->u; 780ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7819c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = 0; 7829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = 0; 783ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod is_first = 1; 785ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = first; 7879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point != first || is_first; 7889c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point = point->next ) 7899c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 7909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Direction out_dir; 791ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 792ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod is_first = 0; 794ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7959c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next = point->next; 796ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 7979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x += next->fx - point->fx; 7989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y += next->fy - point->fy; 7999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) 8019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->flags |= AF_FLAG_WEAK_INTERPOLATION; 8039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 804ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 805ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( next - curr ); 8079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->v = -curr->u; 8089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_dir = af_direction_compute( out_x, out_y ); 8109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* adjust directions for all points inbetween; */ 8129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* the loop also updates position of `curr' */ 8139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->out_dir = (FT_Char)out_dir; 8149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( curr = curr->next; curr != next; curr = curr->next ) 8159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->in_dir = (FT_Char)out_dir; 8179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->out_dir = (FT_Char)out_dir; 8189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 8199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next->in_dir = (FT_Char)out_dir; 8209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod curr->u = (FT_Pos)( first - curr ); 8229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod first->v = -curr->u; 8239c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = 0; 8259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = 0; 826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 8279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 8309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * The next step is to `simplify' an outline's topology so that we 8319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * can identify local extrema more reliably: A series of 8329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * non-horizontal or non-vertical vectors pointing into the same 8339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * quadrant are handled as a single, long vector. From a 8349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * topological point of the view, the intermediate points are of no 8359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * interest and thus tagged as weak. 8369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = points; point < point_limit; point++ ) 8399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 8419c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 842ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->in_dir == AF_DIR_NONE && 8449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->out_dir == AF_DIR_NONE ) 845ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 8469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* check whether both vectors point into the same quadrant */ 8479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos in_x, in_y; 8499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Pos out_x, out_y; 8509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next_u = point + point->u; 8529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point prev_v = point + point->v; 8539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 854ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 8559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod in_x = point->fx - prev_v->fx; 8569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod in_y = point->fy - prev_v->fy; 8579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_x = next_u->fx - point->fx; 8599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod out_y = next_u->fy - point->fy; 8609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 ) 8629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* yes, so tag current point as weak */ 8649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* and update index deltas */ 8659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->flags |= AF_FLAG_WEAK_INTERPOLATION; 8679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev_v->u = (FT_Pos)( next_u - prev_v ); 8699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->v = -prev_v->u; 8709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 8719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 8729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* 8759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * Finally, check for remaining weak points. Everything else not 8769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * collected in edges so far is then implicitly classified as strong 8779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod * points. 8789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod */ 879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8809c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod for ( point = points; point < point_limit; point++ ) 8819c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 8829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) 8839c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod continue; 884aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 885727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( point->flags & AF_FLAG_CONTROL ) 886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 887ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* control points are always weak */ 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Is_Weak_Point: 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_WEAK_INTERPOLATION; 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->out_dir == point->in_dir ) 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->out_dir != AF_DIR_NONE ) 894ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 895ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* current point lies on a horizontal or */ 896ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* vertical segment (but doesn't start or end it) */ 897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Is_Weak_Point; 898ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 900ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 9019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point next_u = point + point->u; 9029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod AF_Point prev_v = point + point->v; 9039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( ft_corner_is_flat( point->fx - prev_v->fx, 9069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod point->fy - prev_v->fy, 9079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->fx - point->fx, 9089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->fy - point->fy ) ) 9099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod { 9109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* either the `in' or the `out' vector is much more */ 9119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* dominant than the other one, so tag current point */ 9129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod /* as weak and update index deltas */ 9139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod prev_v->u = (FT_Pos)( next_u - prev_v ); 9159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod next_u->v = -prev_v->u; 9169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 9179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod goto Is_Weak_Point; 9189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod } 919ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->in_dir == -point->out_dir ) 922ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 923ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease /* current point forms a spike */ 924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Is_Weak_Point; 925ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 935aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Store the hinted outline in an FT_Outline structure. */ 936aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_save( AF_GlyphHints hints, 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Outline* outline ) 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point = hints->points; 942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point limit = point + hints->num_points; 943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector* vec = outline->points; 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char* tag = outline->tags; 945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; point < limit; point++, vec++, tag++ ) 948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = point->x; 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = point->y; 951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & AF_FLAG_CONIC ) 953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_CONIC; 954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( point->flags & AF_FLAG_CUBIC ) 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_CUBIC; 956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tag[0] = FT_CURVE_TAG_ON; 958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * EDGE POINT GRID-FITTING 965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 969aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Align all points of an edge to the same coordinate value, */ 970aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* either horizontally or vertically. */ 971aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_edge_points( AF_GlyphHints hints, 974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = & hints->axis[dim]; 977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segments = axis->segments; 978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment segment_limit = segments + axis->num_segments; 979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Segment seg; 980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < segment_limit; seg++ ) 985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = seg->edge; 987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point, first, last; 988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge == NULL ) 991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first = seg->first; 994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = seg->last; 995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = first; 996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = edge->pos; 999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_TOUCH_X; 1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == last ) 1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = point->next; 1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( seg = segments; seg < segment_limit; seg++ ) 1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge = seg->edge; 1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point, first, last; 1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edge == NULL ) 1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first = seg->first; 1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = seg->last; 1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = first; 1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = edge->pos; 1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= AF_FLAG_TOUCH_Y; 1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point == last ) 1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = point->next; 1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * STRONG POINT INTERPOLATION 1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1044aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Hint the strong points -- this is equivalent to the TrueType `IP' */ 1045aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* hinting instruction. */ 1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_strong_points( AF_GlyphHints hints, 1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_AxisHints axis = &hints->axis[dim]; 1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edges = axis->edges; 1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge_limit = edges + axis->num_edges; 1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Flags touch_flag; 1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_X; 1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_Y; 1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges < edge_limit ) 1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge edge; 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos u, ou, fu; /* point position */ 1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta; 1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & touch_flag ) 1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if this point is candidate to weak interpolation, we */ 1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* interpolate it after all strong points have been processed */ 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && 1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project !( point->flags & AF_FLAG_INFLECTION ) ) 1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_VERT ) 1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = point->fy; 1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ou = point->oy; 1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = point->fx; 1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ou = point->ox; 1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fu = u; 1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is the point before the first edge? */ 1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges; 1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = edge->fpos - u; 1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta >= 0 ) 1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos - ( edge->opos - ou ); 1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is the point after the last edge? */ 1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edge_limit - 1; 1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = u - edge->fpos; 1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta >= 0 ) 1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos + ( ou - edge->opos ); 1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1118295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_PtrDist min, max, mid; 1119aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Pos fpos; 1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find enclosing edges */ 1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = edge_limit - edges; 1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1 1127aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* for a small number of edges, a linear search is better */ 1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( max <= 8 ) 1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1130295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_PtrDist nn; 1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1132aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( nn = 0; nn < max; nn++ ) 1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges[nn].fpos >= u ) 1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( edges[nn].fpos == u ) 1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edges[nn].pos; 1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = nn; 1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif 1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( max + min ) >> 1; 1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project edge = edges + mid; 1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fpos = edge->fpos; 1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u < fpos ) 1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u > fpos ) 1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we are on the edge */ 1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = edge->pos; 1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Store_Point; 1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1164aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* point is not on an edge */ 1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge before = edges + min - 1; 1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Edge after = edges + min + 0; 1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* assert( before && after && before != after ) */ 1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( before->scale == 0 ) 1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project before->scale = FT_DivFix( after->pos - before->pos, 1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project after->fpos - before->fpos ); 1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = before->pos + FT_MulFix( fu - before->fpos, 1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project before->scale ); 1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Store_Point: 1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* save the point position */ 1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = u; 1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = u; 1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->flags |= touch_flag; 1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /**************************************************************** 1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * WEAK POINT INTERPOLATION 1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * 1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ****************************************************************/ 1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1200aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Shift the original coordinates of all points between `p1' and */ 1201aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* `p2' to get hinted coordinates, using the same difference as */ 1202aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* given by `ref'. */ 1203aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_shift( AF_Point p1, 1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p2, 1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref ) 1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p; 1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta = ref->u - ref->v; 1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1212aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( delta == 0 ) 1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p < ref; p++ ) 1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = p->v + delta; 1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = ref + 1; p <= p2; p++ ) 1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = p->v + delta; 1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1224aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Interpolate the original coordinates of all points between `p1' and */ 1225aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the */ 1226aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* reference points. The `u' and `v' members are the current and */ 1227aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* original coordinate values, respectively. */ 1228aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* */ 1229aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Details can be found in the TrueType bytecode specification. */ 1230aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( AF_Point p1, 1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p2, 1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref1, 1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point ref2 ) 1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point p; 1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos u; 1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos v1 = ref1->v; 1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos v2 = ref2->v; 1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos d1 = ref1->u - v1; 1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos d2 = ref2->u - v2; 1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p1 > p2 ) 1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( v1 == v2 ) 1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u <= v1 ) 1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d2; 1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( v1 < v2 ) 1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u <= v1 ) 1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u >= v2 ) 1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d2; 1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); 1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( p = p1; p <= p2; p++ ) 1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = p->v; 1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( u <= v2 ) 1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d2; 1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( u >= v1 ) 1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u += d1; 1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); 1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p->u = u; 1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1299aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Hint the weak points -- this is equivalent to the TrueType `IUP' */ 1300aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* hinting instruction. */ 1301aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_align_weak_points( AF_GlyphHints hints, 1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim ) 1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point_limit = points + hints->num_points; 1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour = hints->contours; 1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point* contour_limit = contour + hints->num_contours; 1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Flags touch_flag; 1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point end_point; 1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point first_point; 1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* PASS 1: Move segment points to edge positions */ 1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_X; 1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->u = point->x; 1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->v = point->ox; 1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project touch_flag = AF_FLAG_TOUCH_Y; 1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->u = point->y; 1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->v = point->oy; 1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; contour < contour_limit; contour++ ) 1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point first_touched, last_touched; 1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point = *contour; 1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end_point = point->prev; 1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_point = point; 1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find first touched point */ 1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point > end_point ) /* no touched point in contour */ 1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto NextContour; 1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point->flags & touch_flag ) 1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_touched = point; 1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1364aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_ASSERT( point <= end_point && 1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ( point->flags & touch_flag ) != 0 ); 1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1367aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* skip any touched neighbours */ 1368aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner while ( point < end_point && 1369aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner ( point[1].flags & touch_flag ) != 0 ) 1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched = point; 1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* find the next touched point, if any */ 1375aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner point++; 1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (;;) 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( point > end_point ) 1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto EndContour; 1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( point->flags & touch_flag ) != 0 ) 1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point++; 1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* interpolate between last_touched and point */ 1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( last_touched + 1, point - 1, 1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, point ); 1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project EndContour: 1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* special case: only one point was touched */ 1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_touched == first_touched ) 1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_shift( first_point, end_point, first_touched ); 1396aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else /* interpolate the last part */ 1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_touched < end_point ) 1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( last_touched + 1, end_point, 1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, first_touched ); 1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( first_touched > points ) 1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_iup_interp( first_point, first_touched - 1, 1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_touched, first_touched ); 1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project NextContour: 1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ; 1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* now save the interpolated values back to x/y */ 1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = point->u; 1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < point_limit; point++ ) 1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = point->u; 1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1426aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef AF_CONFIG_OPTION_USE_WARPER 1427aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner 1428aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner /* Apply (small) warp scale and warp delta for given dimension. */ 1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project af_glyph_hints_scale_dim( AF_GlyphHints hints, 1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Dimension dim, 1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed scale, 1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Pos delta ) 1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points = hints->points; 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point points_limit = points + hints->num_points; 1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project AF_Point point; 1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dim == AF_DIMENSION_HORZ ) 1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < points_limit; point++ ) 1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->x = FT_MulFix( point->fx, scale ) + delta; 1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( point = points; point < points_limit; point++ ) 1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point->y = FT_MulFix( point->fy, scale ) + delta; 1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1453aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* AF_CONFIG_OPTION_USE_WARPER */ 1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 1456