1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* ttgxvar.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* TrueType GX Font Variation loader */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 7a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin/* Copyright 2004-2017 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ 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 19295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 20295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 21295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ 22295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 23fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */ 24295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 25295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* The documentation for `gvar' is not intelligible; `cvar' refers you */ 26295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* to `gvar' and is thus also incomprehensible. */ 27295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 28295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* The documentation for `avar' appears correct, but Apple has no fonts */ 29295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* with an `avar' table, so it is hard to test. */ 30295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 31295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* Many thanks to John Jenkins (at Apple) in figuring this out. */ 32295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 33295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 34295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* Apple's `kern' table has some references to tuple indices, but as */ 35295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* there is no indication where these indices are defined, nor how to */ 36295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* interpolate the kerning values (different tuples have different */ 37295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* classes) this issue is ignored. */ 38295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 39295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h> 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_CONFIG_CONFIG_H 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_SFNT_H 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_MULTIPLE_MASTERS_H 49a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#include FT_LIST_H 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttpload.h" 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttgxvar.h" 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "tterrors.h" 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 60fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define FT_Stream_FTell( stream ) \ 61727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease (FT_ULong)( (stream)->cursor - (stream)->base ) 62fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define FT_Stream_SeekSet( stream, off ) \ 63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease ( (stream)->cursor = (stream)->base + (off) ) 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* messages during execution. */ 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_COMPONENT 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT trace_ttgxvar 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** Internal Routines *****/ 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* indicates that there is a delta for every point without needing to */ 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* enumerate all of them. */ 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 91727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 92727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* ensure that value `0' has the same width as a pointer */ 93727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 96fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define GX_PT_POINTS_ARE_WORDS 0x80U 97fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define GX_PT_POINT_RUN_COUNT_MASK 0x7FU 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ft_var_readpackedpoints */ 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Read a set of points to which the following deltas will apply. */ 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Points are packed with a run length encoding. */ 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: The data stream. */ 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 112055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* size :: The size of the table holding the data. */ 113055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* */ 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Output> */ 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* point_cnt :: The number of points read. A zero value means that */ 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* all points in the glyph will be affected, without */ 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* enumerating them individually. */ 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* An array of FT_UShort containing the affected points or the */ 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* special value ALL_POINTS. */ 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UShort* 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_var_readpackedpoints( FT_Stream stream, 125055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_ULong size, 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt *point_cnt ) 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 128aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_UShort *points = NULL; 129fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt n; 130fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt runcnt; 131fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt i, j; 132fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UShort first; 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( error ); 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 139fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki *point_cnt = 0; 140fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 141fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki n = FT_GET_BYTE(); 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( n == 0 ) 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ALL_POINTS; 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( n & GX_PT_POINTS_ARE_WORDS ) 146fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 147fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki n &= GX_PT_POINT_RUN_COUNT_MASK; 148fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki n <<= 8; 149fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki n |= FT_GET_BYTE(); 150fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 152055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( n > size ) 153055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 154055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" )); 155055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return NULL; 156055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 157055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 158055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* in the nested loops below we increase `i' twice; */ 159055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* it is faster to simply allocate one more slot */ 160055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* than to add another test within the loop */ 161055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( FT_NEW_ARRAY( points, n + 1 ) ) 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 164fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki *point_cnt = n; 165fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 166055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin first = 0; 167055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin i = 0; 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( i < n ) 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project runcnt = FT_GET_BYTE(); 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( runcnt & GX_PT_POINTS_ARE_WORDS ) 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 173fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki runcnt &= GX_PT_POINT_RUN_COUNT_MASK; 174055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin first += FT_GET_USHORT(); 175fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki points[i++] = first; 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 177fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* first point not included in run count */ 178fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < runcnt; j++ ) 179fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 180fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first += FT_GET_USHORT(); 181fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki points[i++] = first; 182055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( i >= n ) 183055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 184fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 188055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin first += FT_GET_BYTE(); 189fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki points[i++] = first; 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 191fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < runcnt; j++ ) 192fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 193fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first += FT_GET_BYTE(); 194fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki points[i++] = first; 195055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( i >= n ) 196055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 197fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return points; 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 205fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define GX_DT_DELTAS_ARE_ZERO 0x80U 206fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define GX_DT_DELTAS_ARE_WORDS 0x40U 207fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define GX_DT_DELTA_RUN_COUNT_MASK 0x3FU 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ft_var_readpackeddeltas */ 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Read a set of deltas. These are packed slightly differently than */ 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* points. In particular there is no overall count. */ 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: The data stream. */ 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 222055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* size :: The size of the table holding the data. */ 223055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* */ 224fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* delta_cnt :: The number of deltas to be read. */ 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* An array of FT_Short containing the deltas for the affected */ 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* points. (This only gets the deltas for one dimension. It will */ 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* generally be called twice, once for x, once for y. When used in */ 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* cvt table, it will only be called once.) */ 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Short* 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_var_readpackeddeltas( FT_Stream stream, 234055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_ULong size, 235fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt delta_cnt ) 236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 237aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Short *deltas = NULL; 238fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt runcnt, cnt; 239fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt i, j; 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 241727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( error ); 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 246055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( delta_cnt > size ) 247055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 248055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" )); 249055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return NULL; 250055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 251055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project i = 0; 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( i < delta_cnt ) 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project runcnt = FT_GET_BYTE(); 259fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cnt = runcnt & GX_DT_DELTA_RUN_COUNT_MASK; 260fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 263fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* `runcnt' zeroes get added */ 264fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j <= cnt && i < delta_cnt; j++ ) 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas[i++] = 0; 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 269fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* `runcnt' shorts from the stack */ 270fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j <= cnt && i < delta_cnt; j++ ) 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas[i++] = FT_GET_SHORT(); 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 275fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* `runcnt' signed bytes from the stack */ 276fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j <= cnt && i < delta_cnt; j++ ) 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas[i++] = FT_GET_CHAR(); 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 280fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( j <= cnt ) 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 282fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* bad format */ 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( deltas ); 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return deltas; 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ft_var_load_avar */ 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Parse the `avar' table if present. It need not be, so we return */ 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* nothing. */ 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: The font face. */ 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_var_load_avar( TT_Face face ) 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 307fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Stream stream = FT_FACE_STREAM( face ); 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_Blend blend = face->blend; 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_AVarSegment segment; 311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 312fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Long version; 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Long axisCount; 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int i, j; 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( error ); 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 320fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "AVAR " )); 321fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 322a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->avar_checked = TRUE; 323a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = face->goto_table( face, TTAG_avar, stream, &table_len ); 324a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 325a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 326a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "is missing\n" )); 327a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 328a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 329a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 330a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_FRAME_ENTER( table_len ) ) 331a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 332a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 333a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin version = FT_GET_LONG(); 334a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisCount = FT_GET_LONG(); 335a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 336a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( version != 0x00010000L ) 337a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 338a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "bad table version\n" )); 339a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 340a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 341a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 342a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "loaded\n" )); 343a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 344a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( axisCount != (FT_Long)blend->mmvar->num_axis ) 345a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 346a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `fvar'\n" 347a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " table are different\n" )); 348a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 349a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 350a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 351a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) 352a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 353a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 354a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin segment = &blend->avar_segment[0]; 355a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < axisCount; i++, segment++ ) 356a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 357a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " axis %d:\n", i )); 358a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 359a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin segment->pairCount = FT_GET_USHORT(); 360a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( (FT_ULong)segment->pairCount * 4 > table_len || 361a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) 362a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 363a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Failure. Free everything we have done so far. We must do */ 364a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* it right now since loading the `avar' table is optional. */ 365a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 366a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = i - 1; j >= 0; j-- ) 367a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->avar_segment[j].correspondence ); 368a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 369a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->avar_segment ); 370a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->avar_segment = NULL; 371a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 372a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 373a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 374a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 0; j < segment->pairCount; j++ ) 375a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 376a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* convert to Fixed */ 377a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; 378a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; 379a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 380a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " mapping %.5f to %.5f\n", 381a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin segment->correspondence[j].fromCoord / 65536.0, 382a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin segment->correspondence[j].toCoord / 65536.0 )); 383a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 384a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 385a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( "\n" )); 386a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 387a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 388a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin Exit: 389a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_EXIT(); 390a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 391a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 392a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 393a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* some macros we need */ 394a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin #define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) 395a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 396a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin #define FT_fdot14ToFixed( x ) \ 397a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) 398a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin #define FT_intToFixed( i ) \ 399a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) 400a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin #define FT_fixedToInt( x ) \ 401a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) 402a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 403a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 404a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Error 405a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_load_item_variation_store( TT_Face face, 406a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong offset, 407a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarStore itemStore ) 408a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 409a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Stream stream = FT_FACE_STREAM( face ); 410a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Memory memory = stream->memory; 411a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 412a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error; 413a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UShort format; 414a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong region_offset; 415a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt i, j, k; 416a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt shortDeltaCount; 417a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 418a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend = face->blend; 419a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarData varData; 420a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 421a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong* dataOffsetArray = NULL; 422a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 423a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 424a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_STREAM_SEEK( offset ) || 425a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( format ) ) 426a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 427a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 428a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( format != 1 ) 429a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 430a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n", 431a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin format )); 432a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 433a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 434a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 435a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 436a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* read top level fields */ 437a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_ULONG( region_offset ) || 438a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( itemStore->dataCount ) ) 439a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 440a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 441a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* we need at least one entry in `itemStore->varData' */ 442a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !itemStore->dataCount ) 443a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 444a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" )); 445a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 446a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 447a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 448a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 449a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* make temporary copy of item variation data offsets; */ 450a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* we will parse region list first, then come back */ 451a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) ) 452a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 453a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 454a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < itemStore->dataCount; i++ ) 455a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 456a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_ULONG( dataOffsetArray[i] ) ) 457a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 458a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 459a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 460a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* parse array of region records (region list) */ 461a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_STREAM_SEEK( offset + region_offset ) ) 462a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 463a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 464a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_USHORT( itemStore->axisCount ) || 465a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( itemStore->regionCount ) ) 466a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 467a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 468a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis ) 469a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 470a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "ft_var_load_item_variation_store:" 471a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " number of axes in item variation store\n" 472a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " " 473a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " and `fvar' table are different\n" )); 474a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 475a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 476a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 477a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 478a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) ) 479a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 480a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 481a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < itemStore->regionCount; i++ ) 482a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 483a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_AxisCoords axisCoords; 484a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 485a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 486a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, 487a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin itemStore->axisCount ) ) 488a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 489a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 490a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisCoords = itemStore->varRegionList[i].axisList; 491a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 492a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 0; j < itemStore->axisCount; j++ ) 493a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 494a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Short start, peak, end; 495a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 496a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 497a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_SHORT( start ) || 498a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_SHORT( peak ) || 499a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_SHORT( end ) ) 500a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 501a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 502a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisCoords[j].startCoord = FT_fdot14ToFixed( start ); 503a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisCoords[j].peakCoord = FT_fdot14ToFixed( peak ); 504a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisCoords[j].endCoord = FT_fdot14ToFixed( end ); 505a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 506a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 507a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 508a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* end of region list parse */ 509a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 510a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* use dataOffsetArray now to parse varData items */ 511a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) ) 512a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 513a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 514a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < itemStore->dataCount; i++ ) 515a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 516a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData = &itemStore->varData[i]; 517a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 518a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) ) 519a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 520a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 521a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_USHORT( varData->itemCount ) || 522a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( shortDeltaCount ) || 523a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( varData->regionIdxCount ) ) 524a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 525a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 526a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* check some data consistency */ 527a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( shortDeltaCount > varData->regionIdxCount ) 528a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 529a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "bad short count %d or region count %d\n", 530a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin shortDeltaCount, 531a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->regionIdxCount )); 532a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 533a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 534a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 535a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 536a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( varData->regionIdxCount > itemStore->regionCount ) 537a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 538a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n", 539a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->regionIdxCount, 540a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin i )); 541a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 542a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 543a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 544a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 545a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* parse region indices */ 546a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( varData->regionIndices, 547a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->regionIdxCount ) ) 548a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 549a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 550a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 0; j < varData->regionIdxCount; j++ ) 551a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 552a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_USHORT( varData->regionIndices[j] ) ) 553a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 554a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 555a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( varData->regionIndices[j] >= itemStore->regionCount ) 556a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 557a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "bad region index %d\n", 558a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->regionIndices[j] )); 559a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 560a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 561a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 562a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 563a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 564a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Parse delta set. */ 565a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 566a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes */ 567a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* each; on output, deltas are expanded to `regionIdxCount' shorts */ 568a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* each. */ 569a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( varData->deltaSet, 570a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->regionIdxCount * varData->itemCount ) ) 571a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 572a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 573a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* the delta set is stored as a 2-dimensional array of shorts; */ 574a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* sign-extend signed bytes to signed shorts */ 575a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) 576a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 577a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( k = 0; k < shortDeltaCount; k++, j++ ) 578a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 579a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* read the short deltas */ 580a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Short delta; 581a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 582a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 583a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_SHORT( delta ) ) 584a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 585a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 586a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->deltaSet[j] = delta; 587a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 588a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 589a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( ; k < varData->regionIdxCount; k++, j++ ) 590a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 591a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* read the (signed) byte deltas */ 592a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Char delta; 593a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 594a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 595a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_CHAR( delta ) ) 596a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 597a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 598a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData->deltaSet[j] = delta; 599a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 600a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 601a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 602a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 603a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin Exit: 604a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( dataOffsetArray ); 605a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 606a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 607a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 608a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 609a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 610a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Error 611a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_load_delta_set_index_mapping( TT_Face face, 612a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong offset, 613a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_DeltaSetIdxMap map, 614a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarStore itemStore ) 615a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 616a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Stream stream = FT_FACE_STREAM( face ); 617a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Memory memory = stream->memory; 618a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 619a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error; 620a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 621a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UShort format; 622a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt entrySize; 623a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt innerBitCount; 624a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt innerIndexMask; 625a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt i, j; 626a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 627a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 628a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_STREAM_SEEK( offset ) || 629a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( format ) || 630a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( map->mapCount ) ) 631a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 632a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 633a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( format & 0xFFC0 ) 634a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 635a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "bad map format %d\n", format )); 636a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 637a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 638a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 639a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 640a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* bytes per entry: 1, 2, 3, or 4 */ 641a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin entrySize = ( ( format & 0x0030 ) >> 4 ) + 1; 642a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin innerBitCount = ( format & 0x000F ) + 1; 643a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin innerIndexMask = ( 1 << innerBitCount ) - 1; 644a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 645a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) ) 646a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 647a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 648a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( map->outerIndex, map->mapCount ) ) 649a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 650a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 651a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < map->mapCount; i++ ) 652a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 653a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt mapData = 0; 654a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt outerIndex, innerIndex; 655a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 656a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 657a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* read map data one unsigned byte at a time, big endian */ 658a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 0; j < entrySize; j++ ) 659a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 660a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Byte data; 661a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 662a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 663a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_BYTE( data ) ) 664a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 665a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 666a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin mapData = ( mapData << 8 ) | data; 667a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 668a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 669a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outerIndex = mapData >> innerBitCount; 670a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 671a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( outerIndex >= itemStore->dataCount ) 672a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 673a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "outerIndex[%d] == %d out of range\n", 674a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin i, 675a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outerIndex )); 676a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 677a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 678a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 679a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 680a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin map->outerIndex[i] = outerIndex; 681a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 682a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin innerIndex = mapData & innerIndexMask; 683a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 684a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( innerIndex >= itemStore->varData[outerIndex].itemCount ) 685a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 686a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "innerIndex[%d] == %d out of range\n", 687a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin i, 688a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin innerIndex )); 689a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 690a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 691a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 692a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 693a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin map->innerIndex[i] = innerIndex; 694a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 695a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 696a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin Exit: 697a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 698a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 699a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 700a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 701a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 702a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 703a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 704a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* ft_var_load_hvvar */ 705a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 706a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 707a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* If `vertical' is zero, parse the `HVAR' table and set */ 708a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* `blend->hvar_loaded' to TRUE. On success, `blend->hvar_checked' */ 709a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* is set to TRUE. */ 710a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 711a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* If `vertical' is not zero, parse the `VVAR' table and set */ 712a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* `blend->vvar_loaded' to TRUE. On success, `blend->vvar_checked' */ 713a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* is set to TRUE. */ 714a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 715a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Some memory may remain allocated on error; it is always freed in */ 716a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* `tt_done_blend', however. */ 717a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 718a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <InOut> */ 719a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* face :: The font face. */ 720a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 721a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Return> */ 722a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* FreeType error code. 0 means success. */ 723a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 724a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Error 725a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_load_hvvar( TT_Face face, 726a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Bool vertical ) 727a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 728a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Stream stream = FT_FACE_STREAM( face ); 729a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Memory memory = stream->memory; 730a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 731a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend = face->blend; 732a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 733a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_HVVarTable table; 734a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 735a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error; 736a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UShort majorVersion; 737a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong table_len; 738a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong table_offset; 739a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong store_offset; 740a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong widthMap_offset; 741a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 742a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 743a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( vertical ) 744a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 745a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->vvar_loaded = TRUE; 746a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 747a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "VVAR " )); 748a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 749a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = face->goto_table( face, TTAG_VVAR, stream, &table_len ); 750a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 751a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 752a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 753a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->hvar_loaded = TRUE; 754a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 755a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "HVAR " )); 756a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 757a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = face->goto_table( face, TTAG_HVAR, stream, &table_len ); 758a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 759a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 760a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 761a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 762a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "is missing\n" )); 763a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 764a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 765a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 766a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table_offset = FT_STREAM_POS(); 767a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 768a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* skip minor version */ 769a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_USHORT( majorVersion ) || 770a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_STREAM_SKIP( 2 ) ) 771a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 772a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 773a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( majorVersion != 1 ) 774a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 775a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "bad table version %d\n", majorVersion )); 776a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 777a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 778a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 779a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 780a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_ULONG( store_offset ) || 781a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_ULONG( widthMap_offset ) ) 782a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 783a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 784a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( vertical ) 785a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 786a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW( blend->vvar_table ) ) 787a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 788a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table = blend->vvar_table; 789a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 790a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 791a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 792a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW( blend->hvar_table ) ) 793a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 794a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table = blend->hvar_table; 795a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 796a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 797a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = ft_var_load_item_variation_store( 798a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face, 799a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table_offset + store_offset, 800a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &table->itemStore ); 801a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 802a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 803a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 804a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( widthMap_offset ) 805a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 806a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = ft_var_load_delta_set_index_mapping( 807a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face, 808a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table_offset + widthMap_offset, 809a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &table->widthMap, 810a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &table->itemStore ); 811a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 812a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 813a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 814a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 815a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "loaded\n" )); 816a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_Err_Ok; 817a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 818a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin Exit: 819a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !error ) 820a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 821a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( vertical ) 822a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 823a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->vvar_checked = TRUE; 824a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 825a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* FreeType doesn't provide functions to quickly retrieve */ 826a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* TSB, BSB, or VORG values; we thus don't have to implement */ 827a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* support for those three item variation stores. */ 828a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 829a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->variation_support |= TT_FACE_FLAG_VAR_VADVANCE; 830a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 831a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 832a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 833a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->hvar_checked = TRUE; 834a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 835a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* FreeType doesn't provide functions to quickly retrieve */ 836a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* LSB or RSB values; we thus don't have to implement */ 837a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* support for those two item variation stores. */ 838a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 839a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->variation_support |= TT_FACE_FLAG_VAR_HADVANCE; 840a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 841a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 842a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 843a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 844a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 845a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 846a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 847a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Int 848a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_get_item_delta( TT_Face face, 849a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarStore itemStore, 850a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt outerIndex, 851a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt innerIndex ) 852a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 853a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarData varData; 854a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Short* deltaSet; 855a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 856a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt master, j; 857a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed netAdjustment = 0; /* accumulated adjustment */ 858a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed scaledDelta; 859a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed delta; 860a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 861a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 862a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* See pseudo code from `Font Variations Overview' */ 863a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* in the OpenType specification. */ 864a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 865a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData = &itemStore->varData[outerIndex]; 866a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex]; 867a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 868a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* outer loop steps through master designs to be blended */ 869a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( master = 0; master < varData->regionIdxCount; master++ ) 870a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 871a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed scalar = FT_FIXED_ONE; 872a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt regionIndex = varData->regionIndices[master]; 873a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 874a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_AxisCoords axis = itemStore->varRegionList[regionIndex].axisList; 875a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 876a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 877a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* inner loop steps through axes in this region */ 878a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 0; j < itemStore->axisCount; j++, axis++ ) 879a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 880a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed axisScalar; 881a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 882a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 883a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* compute the scalar contribution of this axis; */ 884a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* ignore invalid ranges */ 885a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( axis->startCoord > axis->peakCoord || 886a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axis->peakCoord > axis->endCoord ) 887a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = FT_FIXED_ONE; 888a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 889a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( axis->startCoord < 0 && 890a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axis->endCoord > 0 && 891a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axis->peakCoord != 0 ) 892a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = FT_FIXED_ONE; 893a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 894a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* peak of 0 means ignore this axis */ 895a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( axis->peakCoord == 0 ) 896a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = FT_FIXED_ONE; 897a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 898a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* ignore this region if coords are out of range */ 899a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( face->blend->normalizedcoords[j] < axis->startCoord || 900a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->blend->normalizedcoords[j] > axis->endCoord ) 901a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = 0; 902a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 903a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* calculate a proportional factor */ 904a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 905a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 906a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->blend->normalizedcoords[j] == axis->peakCoord ) 907a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = FT_FIXED_ONE; 908a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) 909a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = 910a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_DivFix( face->blend->normalizedcoords[j] - axis->startCoord, 911a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axis->peakCoord - axis->startCoord ); 912a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 913a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axisScalar = 914a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_DivFix( axis->endCoord - face->blend->normalizedcoords[j], 915a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin axis->endCoord - axis->peakCoord ); 916a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 917a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 918a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* take product of all the axis scalars */ 919a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scalar = FT_MulFix( scalar, axisScalar ); 920a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 921a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } /* per-axis loop */ 922a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 923a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* get the scaled delta for this region */ 924a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin delta = FT_intToFixed( deltaSet[master] ); 925a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin scaledDelta = FT_MulFix( scalar, delta ); 926a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 927a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* accumulate the adjustments from each region */ 928a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin netAdjustment = netAdjustment + scaledDelta; 929a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 930a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } /* per-region loop */ 931a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 932a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return FT_fixedToInt( netAdjustment ); 933a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 934a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 935a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 936a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 937a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 938a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 939a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* tt_hvadvance_adjust */ 940a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 941a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 942a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Apply `HVAR' advance width or `VVAR' advance height adjustment of */ 943a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* a given glyph. */ 944a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 945a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Input> */ 946a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* gindex :: The glyph index. */ 947a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 948a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* vertical :: If set, handle `VVAR' table. */ 949a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 950a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <InOut> */ 951a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* face :: The font face. */ 952a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 953a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* adelta :: Points to width or height value that gets modified. */ 954a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 955a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Error 956a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_hvadvance_adjust( TT_Face face, 957a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt gindex, 958a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Int *avalue, 959a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Bool vertical ) 960a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 961a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error = FT_Err_Ok; 962a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt innerIndex, outerIndex; 963a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Int delta; 964a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 965a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_HVVarTable table; 966a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 967a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 968a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->doblend || !face->blend ) 969a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 970a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 971a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( vertical ) 972a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 973a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend->vvar_loaded ) 974a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 975a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* initialize vvar table */ 976a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->blend->vvar_error = ft_var_load_hvvar( face, 1 ); 977a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 978a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 979a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend->vvar_checked ) 980a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 981a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = face->blend->vvar_error; 982a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 983a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 984a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 985a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table = face->blend->vvar_table; 986a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 987a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 988a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 989a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend->hvar_loaded ) 990a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 991a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* initialize hvar table */ 992a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->blend->hvar_error = ft_var_load_hvvar( face, 0 ); 993a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 994a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 995a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend->hvar_checked ) 996a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 997a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = face->blend->hvar_error; 998a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 999a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1000a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1001a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table = face->blend->hvar_table; 1002a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1003a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1004a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* advance width or height adjustments are always present in an */ 1005a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* `HVAR' or `VVAR' table; no need to test for this capability */ 1006a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1007a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( table->widthMap.innerIndex ) 1008a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 10092357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin FT_UInt idx = gindex; 10102357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin 10112357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin 10122357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin if ( idx >= table->widthMap.mapCount ) 10132357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin idx = table->widthMap.mapCount - 1; 1014a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1015a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* trust that HVAR parser has checked indices */ 10162357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin outerIndex = table->widthMap.outerIndex[idx]; 10172357eb4d408bd48fb7ad5641c6967f4d50ecc4a8Jungshik Shin innerIndex = table->widthMap.innerIndex[idx]; 1018a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1019a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 1020a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1021a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarData varData; 1022a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1023a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1024a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* no widthMap data */ 1025a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outerIndex = 0; 1026a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin innerIndex = gindex; 1027a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1028a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin varData = &table->itemStore.varData[outerIndex]; 1029a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( gindex >= varData->itemCount ) 1030a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1031a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "gindex %d out of range\n", gindex )); 1032a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Argument ); 1033a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 1034a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1035a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1036a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1037a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin delta = ft_var_get_item_delta( face, 1038a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &table->itemStore, 1039a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outerIndex, 1040a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin innerIndex ); 1041a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1042a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( "%s value %d adjusted by %d units (%s)\n", 1043a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin vertical ? "vertical height" : "horizontal width", 1044a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *avalue, 1045a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin delta, 1046a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin vertical ? "VVAR" : "HVAR" )); 1047a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1048a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *avalue += delta; 1049a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1050a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin Exit: 1051a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 1052a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1053a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1054a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1055a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( FT_Error ) 1056a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_hadvance_adjust( TT_Face face, 1057a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt gindex, 1058a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Int *avalue ) 1059a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1060a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return tt_hvadvance_adjust( face, gindex, avalue, 0 ); 1061a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1062a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1063a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1064a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( FT_Error ) 1065a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_vadvance_adjust( TT_Face face, 1066a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt gindex, 1067a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Int *avalue ) 1068a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1069a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return tt_hvadvance_adjust( face, gindex, avalue, 1 ); 1070a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1071a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1072a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1073a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#define GX_VALUE_SIZE 8 1074a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1075a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* all values are FT_Short or FT_UShort entities; */ 1076a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* we treat them consistently as FT_Short */ 1077a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#define GX_VALUE_CASE( tag, dflt ) \ 1078a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin case MVAR_TAG_ ## tag : \ 1079a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin p = (FT_Short*)&face->dflt; \ 1080a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin break 1081a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1082a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#define GX_GASP_CASE( idx ) \ 1083a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin case MVAR_TAG_GASP_ ## idx : \ 1084a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( idx < face->gasp.numRanges - 1 ) \ 1085a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin p = (FT_Short*)&face->gasp.gaspRanges[idx].maxPPEM; \ 1086a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else \ 1087a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin p = NULL; \ 1088a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin break 1089a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1090a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1091a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Short* 1092a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_get_value_pointer( TT_Face face, 1093a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong mvar_tag ) 1094a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1095a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Short* p; 1096a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1097a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1098a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin switch ( mvar_tag ) 1099a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1100a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 0 ); 1101a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 1 ); 1102a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 2 ); 1103a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 3 ); 1104a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 4 ); 1105a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 5 ); 1106a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 6 ); 1107a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 7 ); 1108a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 8 ); 1109a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_GASP_CASE( 9 ); 1110a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1111a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( CPHT, os2.sCapHeight ); 1112a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HASC, os2.sTypoAscender ); 1113a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HCLA, os2.usWinAscent ); 1114a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HCLD, os2.usWinDescent ); 1115a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HCOF, horizontal.caret_Offset ); 1116a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HCRN, horizontal.caret_Slope_Run ); 1117a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HCRS, horizontal.caret_Slope_Rise ); 1118a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HDSC, os2.sTypoDescender ); 1119a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( HLGP, os2.sTypoLineGap ); 1120a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SBXO, os2.ySubscriptXOffset); 1121a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SBXS, os2.ySubscriptXSize ); 1122a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SBYO, os2.ySubscriptYOffset ); 1123a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SBYS, os2.ySubscriptYSize ); 1124a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SPXO, os2.ySuperscriptXOffset ); 1125a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SPXS, os2.ySuperscriptXSize ); 1126a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SPYO, os2.ySuperscriptYOffset ); 1127a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( SPYS, os2.ySuperscriptYSize ); 1128a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( STRO, os2.yStrikeoutPosition ); 1129a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( STRS, os2.yStrikeoutSize ); 1130a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( UNDO, postscript.underlinePosition ); 1131a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( UNDS, postscript.underlineThickness ); 1132a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( VASC, vertical.Ascender ); 1133a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( VCOF, vertical.caret_Offset ); 1134a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( VCRN, vertical.caret_Slope_Run ); 1135a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( VCRS, vertical.caret_Slope_Rise ); 1136a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( VDSC, vertical.Descender ); 1137a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( VLGP, vertical.Line_Gap ); 1138a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_VALUE_CASE( XHGT, os2.sxHeight ); 1139a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1140a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin default: 1141a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* ignore unknown tag */ 1142a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin p = NULL; 1143a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1144a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1145a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return p; 1146a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1147a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1148a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1149a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 1150a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1151a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 1152a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* ft_var_load_mvar */ 1153a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1154a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 1155a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Parse the `MVAR' table. */ 1156a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1157a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Some memory may remain allocated on error; it is always freed in */ 1158a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* `tt_done_blend', however. */ 1159a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1160a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <InOut> */ 1161a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* face :: The font face. */ 1162a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1163a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static void 1164a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_load_mvar( TT_Face face ) 1165a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1166a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Stream stream = FT_FACE_STREAM( face ); 1167a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Memory memory = stream->memory; 1168a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1169a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend = face->blend; 1170a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarStore itemStore; 1171a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Value value, limit; 1172a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1173a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error; 1174a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UShort majorVersion; 1175a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong table_len; 1176a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong table_offset; 1177a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UShort store_offset; 1178a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_ULong records_offset; 1179a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1180a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1181a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "MVAR " )); 1182a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1183a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = face->goto_table( face, TTAG_MVAR, stream, &table_len ); 1184a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 1185a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1186a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "is missing\n" )); 1187a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1188a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1189a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1190a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table_offset = FT_STREAM_POS(); 1191a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1192a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* skip minor version */ 1193a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_READ_USHORT( majorVersion ) || 1194a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_STREAM_SKIP( 2 ) ) 1195a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1196a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1197a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( majorVersion != 1 ) 1198a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1199a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "bad table version %d\n", majorVersion )); 1200a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1201a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1202a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1203a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW( blend->mvar_table ) ) 1204a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1205a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1206a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* skip reserved entry and value record size */ 1207a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_STREAM_SKIP( 4 ) || 1208a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( blend->mvar_table->valueCount ) || 1209a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_READ_USHORT( store_offset ) ) 1210a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1211a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1212a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin records_offset = FT_STREAM_POS(); 1213a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1214a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = ft_var_load_item_variation_store( 1215a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face, 1216a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table_offset + store_offset, 1217a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &blend->mvar_table->itemStore ); 1218a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 1219a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1220a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1221a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_NEW_ARRAY( blend->mvar_table->values, 1222a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->mvar_table->valueCount ) ) 1223a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1224a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1225a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_STREAM_SEEK( records_offset ) || 1226a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_ENTER( blend->mvar_table->valueCount * GX_VALUE_SIZE ) ) 1227a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1228a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1229a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value = blend->mvar_table->values; 1230a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin limit = value + blend->mvar_table->valueCount; 1231a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin itemStore = &blend->mvar_table->itemStore; 1232a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1233a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( ; value < limit; value++ ) 1234a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1235a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value->tag = FT_GET_ULONG(); 1236a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value->outerIndex = FT_GET_USHORT(); 1237a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value->innerIndex = FT_GET_USHORT(); 1238a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1239a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( value->outerIndex >= itemStore->dataCount || 1240a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value->innerIndex >= itemStore->varData[value->outerIndex] 1241a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin .itemCount ) 1242a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1243a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin error = FT_THROW( Invalid_Table ); 1244a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin break; 1245a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1246a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1247a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1248a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_EXIT(); 1249a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1250a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( error ) 1251a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return; 1252a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1253a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "loaded\n" )); 1254a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1255a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value = blend->mvar_table->values; 1256a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin limit = value + blend->mvar_table->valueCount; 1257a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1258a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* save original values of the data MVAR is going to modify */ 1259a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( ; value < limit; value++ ) 1260a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1261a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Short* p = ft_var_get_value_pointer( face, value->tag ); 12629888dce90e659608e20790214fac16d921322077Jungshik Shin if ( p ) 12639888dce90e659608e20790214fac16d921322077Jungshik Shin value->unmodified = *p; 12649888dce90e659608e20790214fac16d921322077Jungshik Shin#ifdef FT_DEBUG_LEVEL_TRACE 12659888dce90e659608e20790214fac16d921322077Jungshik Shin else 12669888dce90e659608e20790214fac16d921322077Jungshik Shin FT_TRACE1(( "ft_var_load_mvar: Ignoring unknown tag `%c%c%c%c'\n", 12679888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag >> 24 ), 12689888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag >> 16 ), 12699888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag >> 8 ), 12709888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag ) )); 12719888dce90e659608e20790214fac16d921322077Jungshik Shin#endif 1272a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1273a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1274a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->variation_support |= TT_FACE_FLAG_VAR_MVAR; 1275a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1276a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1277a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1278a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static FT_Error 1279a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_size_reset_iterator( FT_ListNode node, 1280a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin void* user ) 1281a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1282a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_Size size = (TT_Size)node->data; 1283a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1284a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UNUSED( user ); 1285a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1286a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1287a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_size_reset( size, 1 ); 1288a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1289a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return FT_Err_Ok; 1290a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1291a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1292a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1293a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 1294a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1295a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 1296a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* tt_apply_mvar */ 1297a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1298a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 1299a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Apply `MVAR' table adjustments. */ 1300a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1301a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <InOut> */ 1302a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* face :: The font face. */ 1303a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 1304a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( void ) 1305a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_apply_mvar( TT_Face face ) 1306a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1307a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend = face->blend; 1308a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Value value, limit; 1309a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1311a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) 1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1314a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value = blend->mvar_table->values; 1315a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin limit = value + blend->mvar_table->valueCount; 1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1317a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( ; value < limit; value++ ) 1318fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1319a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Short* p = ft_var_get_value_pointer( face, value->tag ); 1320a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Int delta; 1321a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1322a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1323a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin delta = ft_var_get_item_delta( face, 1324a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &blend->mvar_table->itemStore, 1325a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value->outerIndex, 1326a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin value->innerIndex ); 1327a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 13289888dce90e659608e20790214fac16d921322077Jungshik Shin if ( p ) 13299888dce90e659608e20790214fac16d921322077Jungshik Shin { 13309888dce90e659608e20790214fac16d921322077Jungshik Shin FT_TRACE5(( "value %c%c%c%c (%d units) adjusted by %d units (MVAR)\n", 13319888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag >> 24 ), 13329888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag >> 16 ), 13339888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag >> 8 ), 13349888dce90e659608e20790214fac16d921322077Jungshik Shin (FT_Char)( value->tag ), 13359888dce90e659608e20790214fac16d921322077Jungshik Shin value->unmodified, 13369888dce90e659608e20790214fac16d921322077Jungshik Shin delta )); 13379888dce90e659608e20790214fac16d921322077Jungshik Shin 13389888dce90e659608e20790214fac16d921322077Jungshik Shin /* since we handle both signed and unsigned values as FT_Short, */ 13399888dce90e659608e20790214fac16d921322077Jungshik Shin /* ensure proper overflow arithmetic */ 13409888dce90e659608e20790214fac16d921322077Jungshik Shin *p = (FT_Short)( value->unmodified + (FT_Short)delta ); 13419888dce90e659608e20790214fac16d921322077Jungshik Shin } 1342fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1343fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1344a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* adjust all derived values */ 1345fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1346a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Face root = &face->root; 1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1348fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1349a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->os2.version != 0xFFFFU ) 1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1351a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) 1352a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1353a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->ascender = face->os2.sTypoAscender; 1354a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->descender = face->os2.sTypoDescender; 1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1356a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->height = root->ascender - root->descender + 1357a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->os2.sTypoLineGap; 1358a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1359a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 1360a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1361a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->ascender = (FT_Short)face->os2.usWinAscent; 1362a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->descender = -(FT_Short)face->os2.usWinDescent; 1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1364a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->height = root->ascender - root->descender; 1365a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1368a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->underline_position = face->postscript.underlinePosition - 1369a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->postscript.underlineThickness / 2; 1370a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin root->underline_thickness = face->postscript.underlineThickness; 1371fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1372a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* iterate over all FT_Size objects and call `tt_size_reset' */ 1373a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* to propagate the metrics changes */ 1374a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_List_Iterate( &root->sizes_list, 1375a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_size_reset_iterator, 1376a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin NULL ); 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct GX_GVar_Head_ 1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Long version; 1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort axisCount; 1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort globalCoordCount; 1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong offsetToCoord; 1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort glyphCount; 1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort flags; 1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong offsetToData; 1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } GX_GVar_Head; 1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ft_var_load_gvar */ 1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 1400fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Parse the `gvar' table if present. If `fvar' is there, `gvar' had */ 1401fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* better be there too. */ 1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: The font face. */ 1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_var_load_gvar( TT_Face face ) 1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1412fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Stream stream = FT_FACE_STREAM( face ); 1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_Blend blend = face->blend; 1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, j; 1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong gvar_start; 1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong offsetToData; 1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_GVar_Head gvar_head; 1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const FT_Frame_Field gvar_fields[] = 1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_STRUCTURE 1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE GX_GVar_Head 1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_START( 20 ), 1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_LONG ( version ), 1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_USHORT( axisCount ), 1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_USHORT( globalCoordCount ), 1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_ULONG ( offsetToCoord ), 1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_USHORT( glyphCount ), 1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_USHORT( flags ), 1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_ULONG ( offsetToData ), 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_END 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1439fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1440fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "GVAR " )); 1441fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1442a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( face->goto_table( face, 1443a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TTAG_gvar, 1444a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin stream, 1445a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &table_len ) ) ) 1446fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1447fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "is missing\n" )); 1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1449fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gvar_start = FT_STREAM_POS( ); 1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) 1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1455fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( gvar_head.version != 0x00010000L ) 1456fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1457fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE1(( "bad table version\n" )); 1458fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki error = FT_THROW( Invalid_Table ); 1459fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Exit; 1460fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1461fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1462fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) 1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1464fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" 1465fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " table are different\n" )); 1466727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Table ); 1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1470055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* rough sanity check, ignoring offsets */ 1471055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount > 1472055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin table_len / 2 ) 1473055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1474055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE1(( "ft_var_load_gvar:" 1475055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " invalid number of global coordinates\n" )); 1476055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin error = FT_THROW( Invalid_Table ); 1477055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Exit; 1478055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1479055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1480a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* rough sanity check: offsets can be either 2 or 4 bytes */ 1481055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( (FT_ULong)gvar_head.glyphCount * 1482a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len ) 1483055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1484055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" )); 1485055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin error = FT_THROW( Invalid_Table ); 1486055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Exit; 1487055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1488055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1489055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE2(( "loaded\n" )); 1490055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1491055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gvar_size = table_len; 1492055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->tuplecount = gvar_head.globalCoordCount; 1493055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gv_glyphcnt = gvar_head.glyphCount; 1494055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offsetToData = gvar_start + gvar_head.offsetToData; 1495055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1496fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "gvar: there are %d shared coordinates:\n", 1497fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki blend->tuplecount )); 1498fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) 1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gvar_head.flags & 1 ) 1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* long offsets (one more offset than glyphs, to mark size of last) */ 1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) 1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1508fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i <= blend->gv_glyphcnt; i++ ) 1509fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); 1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* short offsets (one more offset than glyphs, to mark size of last) */ 1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) 1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1519fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i <= blend->gv_glyphcnt; i++ ) 1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; 1521fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* XXX: Undocumented: `*2'! */ 1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( blend->tuplecount != 0 ) 1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( blend->tuplecoords, 1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gvar_head.axisCount * blend->tuplecount ) ) 1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1532fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || 1533fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) 1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1536fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < blend->tuplecount; i++ ) 1537fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1538fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( " [ " )); 1539055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ ) 1540fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend->tuplecoords[i * gvar_head.axisCount + j] = 1542055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_GET_SHORT() * 4; /* convert to FT_Fixed */ 1543a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( "%.5f ", 1544fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); 1545fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1546fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "]\n" )); 1547fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1548fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1549fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "\n" )); 1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ft_var_apply_tuple */ 1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Figure out whether a given tuple (design) applies to the current */ 1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* blend, and if so, what is the scaling factor. */ 1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* blend :: The current blend of the font. */ 1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tupleIndex :: A flag saying whether this is an intermediate */ 1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tuple or not. */ 1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tuple_coords :: The coordinates of the tuple in normalized axis */ 1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* units. */ 1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* im_start_coords :: The initial coordinates where this tuple starts */ 1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to apply (for intermediate coordinates). */ 1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* im_end_coords :: The final coordinates after which this tuple no */ 1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* longer applies (for intermediate coordinates). */ 1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* An FT_Fixed value containing the scaling factor. */ 1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Fixed 1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_var_apply_tuple( GX_Blend blend, 1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort tupleIndex, 1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* tuple_coords, 1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* im_start_coords, 1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* im_end_coords ) 1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i; 1594727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Fixed apply = 0x10000L; 1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1597fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < blend->num_axis; i++ ) 1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1599a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " axis coordinate %d (%.5f):\n", 1600fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki i, blend->normalizedcoords[i] / 65536.0 )); 1601055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) 1602a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " intermediate coordinates %d (%.5f, %.5f):\n", 1603055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin i, 1604055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_start_coords[i] / 65536.0, 1605055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[i] / 65536.0 )); 1606fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1607fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* It's not clear why (for intermediate tuples) we don't need */ 1608fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* to check against start/end -- the documentation says we don't. */ 1609fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Similarly, it's unclear why we don't need to scale along the */ 1610fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* axis. */ 1611fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tuple_coords[i] == 0 ) 1613fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1614fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE6(( " tuple coordinate is zero, ignored\n", i )); 1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1616fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1617fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1618055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( blend->normalizedcoords[i] == 0 ) 1619fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1620fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE6(( " axis coordinate is zero, stop\n" )); 1621fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki apply = 0; 1622fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki break; 1623fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1625055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( blend->normalizedcoords[i] == tuple_coords[i] ) 1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1627a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " tuple coordinate value %.5f fits perfectly\n", 1628fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tuple_coords[i] / 65536.0 )); 1629055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* `apply' does not change */ 1630055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1633055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) 1634fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* not an intermediate tuple */ 1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1637055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || 1638055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) 1639055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1640a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " tuple coordinate value %.5f is exceeded, stop\n", 1641055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tuple_coords[i] / 65536.0 )); 1642055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin apply = 0; 1643055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1644055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1646a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " tuple coordinate value %.5f fits\n", 1647055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tuple_coords[i] / 65536.0 )); 1648727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease apply = FT_MulDiv( apply, 1649055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->normalizedcoords[i], 1650055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tuple_coords[i] ); 1651fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1653fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1654055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* intermediate tuple */ 1655055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1656055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( blend->normalizedcoords[i] < im_start_coords[i] || 1657055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->normalizedcoords[i] > im_end_coords[i] ) 1658055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1659a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] is exceeded," 1660055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " stop\n", 1661055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_start_coords[i] / 65536.0, 1662055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[i] / 65536.0 )); 1663055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin apply = 0; 1664055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1665055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1666055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1667055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( blend->normalizedcoords[i] < tuple_coords[i] ) 1668055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1669a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", 1670055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_start_coords[i] / 65536.0, 1671055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[i] / 65536.0 )); 1672055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin apply = FT_MulDiv( apply, 1673055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->normalizedcoords[i] - im_start_coords[i], 1674055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tuple_coords[i] - im_start_coords[i] ); 1675055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1676055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1677055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 1678055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1679a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", 1680055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_start_coords[i] / 65536.0, 1681055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[i] / 65536.0 )); 1682055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin apply = FT_MulDiv( apply, 1683055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[i] - blend->normalizedcoords[i], 1684055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[i] - tuple_coords[i] ); 1685055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1686fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1689a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE6(( " apply factor is %.5f\n", apply / 65536.0 )); 1690fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return apply; 1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ 1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct GX_FVar_Head_ 1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Long version; 1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort offsetToData; 1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort axisCount; 1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort axisSize; 1710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort instanceCount; 1711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort instanceSize; 1712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } GX_FVar_Head; 1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct fvar_axis_ 1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong axisTag; 1719fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Fixed minValue; 1720fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Fixed defaultValue; 1721fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Fixed maxValue; 1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort flags; 1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort nameID; 1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } GX_FVar_Axis; 1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TT_Get_MM_Var */ 1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Check that the font's `fvar' table is valid, parse it, and return */ 1735a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* those data. It also loads (and parses) the `MVAR' table, if */ 1736a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* possible. */ 1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: The font face. */ 1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TT_Get_MM_Var initializes the blend structure. */ 1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Output> */ 1743055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* master :: The `fvar' data (must be freed by caller). Can be NULL, */ 1744055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* which makes this function simply load MM support. */ 1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_Get_MM_Var( TT_Face face, 1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MM_Var* *master ) 1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = face->root.memory; 1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 1756727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong fvar_start; 1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int i, j; 1759aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner FT_MM_Var* mmvar = NULL; 1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* next_coords; 1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_String* next_name; 1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Var_Axis* a; 1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Var_Named_Style* ns; 1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_FVar_Head fvar_head; 1765a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Bool usePsName; 1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const FT_Frame_Field fvar_fields[] = 1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_STRUCTURE 1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE GX_FVar_Head 1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_START( 16 ), 1774a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_LONG ( version ), 1775a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_USHORT ( offsetToData ), 1776a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_SKIP_SHORT, 1777a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_USHORT ( axisCount ), 1778a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_USHORT ( axisSize ), 1779a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_USHORT ( instanceCount ), 1780a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FRAME_USHORT ( instanceSize ), 1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_END 1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const FT_Frame_Field fvaraxis_fields[] = 1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_STRUCTURE 1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE GX_FVar_Axis 1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_START( 20 ), 1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_ULONG ( axisTag ), 1792fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FRAME_LONG ( minValue ), 1793fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FRAME_LONG ( defaultValue ), 1794fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FRAME_LONG ( maxValue ), 1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_USHORT( flags ), 1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_USHORT( nameID ), 1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_END 1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1801fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* read the font data and set up the internal representation */ 1802fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* if not already done */ 1803fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1804a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend ) 1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1806fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "FVAR " )); 1807fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* both `fvar' and `gvar' must be present */ 1809a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar, 1810a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin stream, &table_len ) ) ) 1811fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1812a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* CFF2 is an alternate to gvar here */ 1813a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2, 1814a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin stream, &table_len ) ) ) 1815a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1816a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE1(( "\n" 1817a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" )); 1818a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin goto Exit; 1819a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1820fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1822a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar, 1823a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin stream, &table_len ) ) ) 1824fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 1825fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE1(( "is missing\n" )); 1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1827fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fvar_start = FT_STREAM_POS( ); 1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1831a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* the validity of the `fvar' header data was already checked */ 1832a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* in function `sfnt_init_face' */ 1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) 1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1836a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin usePsName = FT_BOOL( fvar_head.instanceSize == 1837a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 6 + 4 * fvar_head.axisCount ); 1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1839fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "loaded\n" )); 1840fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1841fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount )); 1842fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW( face->blend ) ) 1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1846aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich /* cannot overflow 32-bit arithmetic because of limits above */ 1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->blend->mmvar_len = 1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sizeof ( FT_MM_Var ) + 1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fvar_head.axisCount * sizeof ( FT_Var_Axis ) + 1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + 1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + 1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 5 * fvar_head.axisCount; 1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) 1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->blend->mmvar = mmvar; 1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1858fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* set up pointers and offsets into the `mmvar' array; */ 1859fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* the data gets filled in later on */ 1860fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->num_axis = 1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fvar_head.axisCount; 1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->num_designs = 1864727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease ~0U; /* meaningless in this context; each glyph */ 1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* may have a different number of designs */ 1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* (or tuples, as called by Apple) */ 1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->num_namedstyles = 1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project fvar_head.instanceCount; 1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->axis = 1870fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki (FT_Var_Axis*)&( mmvar[1] ); 1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->namedstyle = 1872fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); 1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_coords = 1875fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] ); 1876fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < fvar_head.instanceCount; i++ ) 1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->namedstyle[i].coords = next_coords; 1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_coords += fvar_head.axisCount; 1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_name = (FT_String*)next_coords; 1883fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < fvar_head.axisCount; i++ ) 1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->axis[i].name = next_name; 1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_name += 5; 1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1889fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* now fill in the data */ 1890fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) 1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a = mmvar->axis; 1895fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < fvar_head.axisCount; i++ ) 1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_FVar_Axis axis_rec; 1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) 1901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->tag = axis_rec.axisTag; 1903fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->minimum = axis_rec.minValue; 1904fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->def = axis_rec.defaultValue; 1905fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->maximum = axis_rec.maxValue; 1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->strid = axis_rec.nameID; 1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->name[0] = (FT_String)( a->tag >> 24 ); 1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); 1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); 1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); 1912fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->name[4] = '\0'; 1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1914a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( a->minimum > a->def || 1915a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->def > a->maximum ) 1916a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 1917a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "TT_Get_MM_Var:" 1918a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " invalid \"%s\" axis record; disabling\n", 1919a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->name )); 1920a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1921a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->minimum = a->def; 1922a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->maximum = a->def; 1923a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 1924a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1925a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " \"%s\": minimum=%.5f, default=%.5f, maximum=%.5f\n", 1926fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->name, 1927fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->minimum / 65536.0, 1928fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->def / 65536.0, 1929fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->maximum / 65536.0 )); 1930fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1931fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a++; 1932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1934fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "\n" )); 1935fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ns = mmvar->namedstyle; 1937fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) 1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1939a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* PostScript names add 2 bytes to the instance record size */ 1940a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) + 1941a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 4L * fvar_head.axisCount ) ) 1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ns->strid = FT_GET_USHORT(); 1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (void) /* flags = */ FT_GET_USHORT(); 1946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1947fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < fvar_head.axisCount; j++ ) 1948fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ns->coords[j] = FT_GET_LONG(); 1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1950a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( usePsName ) 1951a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ns->psid = FT_GET_USHORT(); 1952a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1955a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1956a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_load_mvar( face ); 1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1959fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* fill the output array if requested */ 1960fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1961a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( master ) 1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt n; 1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) 1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); 1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->axis = 1971fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki (FT_Var_Axis*)&( mmvar[1] ); 1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->namedstyle = 1973fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); 1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_coords = 1975fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); 1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1977fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( n = 0; n < mmvar->num_namedstyles; n++ ) 1978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar->namedstyle[n].coords = next_coords; 1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_coords += mmvar->num_axis; 1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1983fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a = mmvar->axis; 1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_name = (FT_String*)next_coords; 1985fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( n = 0; n < mmvar->num_axis; n++ ) 1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a->name = next_name; 1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* standard PostScript names for some standard apple tags */ 1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( a->tag == TTAG_wght ) 1991fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->name = (char*)"Weight"; 1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( a->tag == TTAG_wdth ) 1993fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->name = (char*)"Width"; 1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( a->tag == TTAG_opsz ) 1995fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->name = (char*)"OpticalSize"; 1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( a->tag == TTAG_slnt ) 1997fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->name = (char*)"Slant"; 1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_name += 5; 2000fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a++; 2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *master = mmvar; 2004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TT_Set_MM_Blend */ 2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Set the blend (normalized) coordinates for this instance of the */ 2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* font. Check that the `gvar' table is reasonable and does some */ 2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* initial preparation. */ 2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: The font. */ 2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Initialize the blend structure with `gvar' data. */ 2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 2026fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* num_coords :: The number of available coordinates. If it is */ 2027fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* larger than the number of axes, ignore the excess */ 2028fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* values. If it is smaller than the number of axes, */ 2029fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* use the default value (0) for the remaining axes. */ 2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2031fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* coords :: An array of `num_coords', each between [-1,1]. */ 2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_Set_MM_Blend( TT_Face face, 2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_coords, 2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* coords ) 2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2041727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_Blend blend; 2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MM_Var* mmvar; 2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i; 2045a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Bool is_default_instance = 1; 2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = face->root.memory; 2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project enum 2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mcvt_retain, 2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mcvt_modify, 2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mcvt_load 2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } manageCvt; 2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->doblend = FALSE; 2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2059a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend ) 2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2061a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) 2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend = face->blend; 2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar = blend->mmvar; 2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2068fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( num_coords > mmvar->num_axis ) 2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2070fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n", 2071fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki mmvar->num_axis, num_coords )); 2072fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki num_coords = mmvar->num_axis; 2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2075fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "normalized design coordinates:\n" )); 2076fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2077fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < num_coords; i++ ) 2078fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2079a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); 2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) 2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2082a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n" 2083fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " is out of range [-1;1]\n", 2084fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki coords[i] / 65536.0 )); 2085727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Argument ); 2086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2088a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2089a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coords[i] != 0 ) 2090a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin is_default_instance = 0; 2091fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2092fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2093fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "\n" )); 2094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2095a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->isCFF2 && !blend->glyphoffsets ) 2096a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) ) 2097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2099a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !blend->normalizedcoords ) 2100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2101fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) 2102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project manageCvt = mcvt_modify; 2105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If we have not set the blend coordinates before this, then the */ 2107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* cvt table will still be what we read from the `cvt ' table and */ 2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we don't need to reload it. We may need to change it though... */ 2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 21120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project manageCvt = mcvt_retain; 2113fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2114fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < num_coords; i++ ) 21150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 21160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project if ( blend->normalizedcoords[i] != coords[i] ) 21170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project { 2118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project manageCvt = mcvt_load; 21190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project break; 21200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 21210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project } 2122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2123fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( ; i < mmvar->num_axis; i++ ) 2124fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2125fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( blend->normalizedcoords[i] != 0 ) 2126fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2127fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki manageCvt = mcvt_load; 2128fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki break; 2129fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2130fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2131fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If we don't change the blend coords then we don't need to do */ 2133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* anything to the cvt table. It will be correct. Otherwise we */ 2134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no longer have the original cvt (it was modified when we set */ 2135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the blend last time), so we must reload and then modify it. */ 2136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2138fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki blend->num_axis = mmvar->num_axis; 2139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MEM_COPY( blend->normalizedcoords, 2140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project coords, 2141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_coords * sizeof ( FT_Fixed ) ); 2142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->doblend = TRUE; 2144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2145a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->cvt ) 2146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project switch ( manageCvt ) 2148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case mcvt_load: 2150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The cvt table has been loaded already; every time we change the */ 2151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* blend we may need to reload and remodify the cvt table. */ 2152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( face->cvt ); 2153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project face->cvt = NULL; 2154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2155fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki error = tt_face_load_cvt( face, face->root.stream ); 2156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case mcvt_modify: 2159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The original cvt table is in memory. All we need to do is */ 2160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* apply the `cvar' table (if any). */ 2161fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki error = tt_face_vary_cvt( face, face->root.stream ); 2162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project case mcvt_retain: 2165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The cvt table is correct for this set of coordinates. */ 2166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2170a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin face->is_default_instance = is_default_instance; 2171a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 2173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 2180a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* TT_Get_MM_Blend */ 2181a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2182a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 2183a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Get the blend (normalized) coordinates for this instance of the */ 2184a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* font. */ 2185a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2186a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <InOut> */ 2187a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* face :: The font. */ 2188a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Initialize the blend structure with `gvar' data. */ 2189a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2190a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Input> */ 2191a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* num_coords :: The number of available coordinates. If it is */ 2192a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* larger than the number of axes, set the excess */ 2193a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* values to 0. */ 2194a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2195a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* coords :: An array of `num_coords', each between [-1,1]. */ 2196a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2197a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Return> */ 2198a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* FreeType error code. 0 means success. */ 2199a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2200a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( FT_Error ) 2201a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_Get_MM_Blend( TT_Face face, 2202a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt num_coords, 2203a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed* coords ) 2204a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2205a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error = FT_Err_Ok; 2206a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend; 2207a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt i, nc; 2208a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2209a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2210a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend ) 2211a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2212a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) 2213a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 2214a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2215a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2216a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend = face->blend; 2217a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2218a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin nc = num_coords; 2219a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( num_coords > blend->num_axis ) 2220a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2221a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "TT_Get_MM_Blend: only using first %d of %d coordinates\n", 2222a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->num_axis, num_coords )); 2223a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin nc = blend->num_axis; 2224a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2225a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2226a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->doblend ) 2227a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2228a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < nc; i++ ) 2229a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = blend->normalizedcoords[i]; 2230a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2231a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 2232a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2233a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < nc; i++ ) 2234a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = 0; 2235a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2236a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2237a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( ; i < num_coords; i++ ) 2238a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = 0; 2239a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2240a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return FT_Err_Ok; 2241a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2242a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2243a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2244a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 2245a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2246a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 2247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TT_Set_Var_Design */ 2248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 2250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Set the coordinates for the instance, measured in the user */ 2251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* coordinate system. Parse the `avar' table (if present) to convert */ 2252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* from user to normalized coordinates. */ 2253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 2255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: The font face. */ 2256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Initialize the blend struct with `gvar' data. */ 2257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 2259fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* num_coords :: The number of available coordinates. If it is */ 2260fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* larger than the number of axes, ignore the excess */ 2261fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* values. If it is smaller than the number of axes, */ 2262fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* use the default values for the remaining axes. */ 2263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* coords :: A coordinate array with `num_coords' elements. */ 2265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 2267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 2268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 2270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_Set_Var_Design( TT_Face face, 2271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_coords, 2272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* coords ) 2273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 2275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* normalized = NULL; 2276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_Blend blend; 2277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MM_Var* mmvar; 2278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, j; 2279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Var_Axis* a; 2280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_AVarSegment av; 2281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = face->root.memory; 2282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2284a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend ) 2285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2286a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) 2287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend = face->blend; 2291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mmvar = blend->mmvar; 2292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2293fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( num_coords > mmvar->num_axis ) 2294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2295fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "TT_Set_Var_Design:" 2296fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " only using first %d of %d coordinates\n", 2297fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki mmvar->num_axis, num_coords )); 2298fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki num_coords = mmvar->num_axis; 2299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2301a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Axis normalization is a two-stage process. First we normalize */ 2302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ 2303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Then, if there's an `avar' table, we renormalize this range. */ 2304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) 2306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2308fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "design coordinates:\n" )); 2309fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project a = mmvar->axis; 2311fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < num_coords; i++, a++ ) 2312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2313a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed coord = coords[i]; 2314a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2315a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2316a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " %.5f\n", coord / 65536.0 )); 2317a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coord > a->maximum || coord < a->minimum ) 2318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2319a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE1(( 2320a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin "TT_Set_Var_Design: design coordinate %.5f\n" 2321a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " is out of range [%.5f;%.5f]; clamping\n", 2322a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coord / 65536.0, 2323a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->minimum / 65536.0, 2324a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->maximum / 65536.0 )); 2325a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2326a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coord > a->maximum) 2327a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coord = a->maximum; 2328a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 2329a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coord = a->minimum; 2330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2332a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coord < a->def ) 2333fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki normalized[i] = -FT_DivFix( coords[i] - a->def, 2334fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->minimum - a->def ); 2335a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( coord > a->def ) 2336fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki normalized[i] = FT_DivFix( coords[i] - a->def, 2337fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki a->maximum - a->def ); 2338a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 2339a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin normalized[i] = 0; 2340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2342fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "\n" )); 2343fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2344fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( ; i < mmvar->num_axis; i++ ) 2345fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki normalized[i] = 0; 2346fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !blend->avar_checked ) 2348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_var_load_avar( face ); 2349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2350a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( blend->avar_segment ) 2351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2352fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "normalized design coordinates" 2353fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " before applying `avar' data:\n" )); 2354fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project av = blend->avar_segment; 2356fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < mmvar->num_axis; i++, av++ ) 2357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2358fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) 2359fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( normalized[i] < av->correspondence[j].fromCoord ) 2361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2362a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " %.5f\n", normalized[i] / 65536.0 )); 2363a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project normalized[i] = 2365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, 2366727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease av->correspondence[j].toCoord - 2367727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease av->correspondence[j - 1].toCoord, 2368727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease av->correspondence[j].fromCoord - 2369727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease av->correspondence[j - 1].fromCoord ) + 2370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project av->correspondence[j - 1].toCoord; 2371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2373fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2377fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized ); 2378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 2380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( normalized ); 2381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2386a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2387a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 2388a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* TT_Get_Var_Design */ 2389a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2390a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 2391a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Get the design coordinates of the currently selected interpolated */ 2392a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* font. */ 2393a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2394a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Input> */ 2395a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* face :: A handle to the source face. */ 2396a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2397a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* num_coords :: The number of design coordinates to retrieve. If it */ 2398a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* is larger than the number of axes, set the excess */ 2399a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* values to~0. */ 2400a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2401a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Output> */ 2402a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* coords :: The design coordinates array. */ 2403a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2404a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Return> */ 2405a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* FreeType error code. 0~means success. */ 2406a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 2407a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( FT_Error ) 2408a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_Get_Var_Design( TT_Face face, 2409a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt num_coords, 2410a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed* coords ) 2411a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2412a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Error error = FT_Err_Ok; 2413a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2414a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend; 2415a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_MM_Var* mmvar; 2416a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Var_Axis* a; 2417a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2418a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt i, j, nc; 2419a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2420a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2421a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->blend ) 2422a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2423a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) 2424a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return error; 2425a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2426a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2427a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend = face->blend; 2428a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2429a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin nc = num_coords; 2430a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( num_coords > blend->num_axis ) 2431a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2432a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE2(( "TT_Get_Var_Design: only using first %d of %d coordinates\n", 2433a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin blend->num_axis, num_coords )); 2434a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin nc = blend->num_axis; 2435a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2436a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2437a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->doblend ) 2438a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2439a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < nc; i++ ) 2440a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = blend->normalizedcoords[i]; 2441a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2442a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 2443a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2444a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < nc; i++ ) 2445a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = 0; 2446a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2447a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2448a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( ; i < num_coords; i++ ) 2449a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = 0; 2450a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2451a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !blend->avar_checked ) 2452a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_load_avar( face ); 2453a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2454a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( blend->avar_segment ) 2455a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2456a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_AVarSegment av = blend->avar_segment; 2457a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2458a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2459a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( "design coordinates" 2460a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin " after removing `avar' distortion:\n" )); 2461a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2462a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < nc; i++, av++ ) 2463a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2464a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) 2465a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2466a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coords[i] < av->correspondence[j].toCoord ) 2467a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2468a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = 2469a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_MulDiv( coords[i] - av->correspondence[j - 1].toCoord, 2470a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin av->correspondence[j].fromCoord - 2471a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin av->correspondence[j - 1].fromCoord, 2472a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin av->correspondence[j].toCoord - 2473a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin av->correspondence[j - 1].toCoord ) + 2474a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin av->correspondence[j - 1].fromCoord; 2475a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2476a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); 2477a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin break; 2478a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2479a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2480a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2481a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2482a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2483a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin mmvar = blend->mmvar; 2484a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a = mmvar->axis; 2485a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2486a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < nc; i++, a++ ) 2487a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 2488a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coords[i] < 0 ) 2489a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = a->def + FT_MulFix( coords[i], 2490a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->def - a->minimum ); 2491a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( coords[i] > 0 ) 2492a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = a->def + FT_MulFix( coords[i], 2493a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin a->maximum - a->def ); 2494a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 2495a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin coords[i] = a->def; 2496a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2497a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2498a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return FT_Err_Ok; 2499a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 2500a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2501a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2502a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 2503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** GX VAR PARSING ROUTINES *****/ 2506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 2514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_face_vary_cvt */ 2515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 2517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Modify the loaded cvt table according to the `cvar' table and the */ 2518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* font's blend. */ 2519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <InOut> */ 2521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 2522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 2524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stream :: A handle to the input stream. */ 2525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 2527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 2528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Most errors are ignored. It is perfectly valid not to have a */ 2530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* `cvar' table even if there is a `gvar' and `fvar' table. */ 2531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 2533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_vary_cvt( TT_Face face, 2534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream ) 2535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 2537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 2538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_start; 2539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong table_len; 2540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tupleCount; 2541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong offsetToData; 2542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong here; 2543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, j; 2544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* tuple_coords = NULL; 2545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* im_start_coords = NULL; 2546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* im_end_coords = NULL; 2547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_Blend blend = face->blend; 2548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt point_count; 2549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort* localpoints; 2550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short* deltas; 2551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_TRACE2(( "CVAR " )); 2554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2555a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !blend ) 2556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2557fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "\n" 2558fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki "tt_face_vary_cvt: no blend specified\n" )); 2559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Err_Ok; 2560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2563a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->cvt ) 2564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2565fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "\n" 2566fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki "tt_face_vary_cvt: no `cvt ' table\n" )); 2567727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Err_Ok; 2568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = face->goto_table( face, TTAG_cvar, stream, &table_len ); 2572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( error ) 2573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2574295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "is missing\n" )); 2575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2576727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Err_Ok; 2577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_FRAME_ENTER( table_len ) ) 2581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2582727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Err_Ok; 2583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 2584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project table_start = FT_Stream_FTell( stream ); 2587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_GET_LONG() != 0x00010000L ) 2588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2589295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE2(( "bad table version\n" )); 2590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2591727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_Err_Ok; 2592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto FExit; 2593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2595fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "loaded\n" )); 2596fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || 2598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || 2599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) 2600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto FExit; 2601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tupleCount = FT_GET_USHORT(); 2603055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offsetToData = FT_GET_USHORT(); 2604055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2605055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* rough sanity test */ 2606a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > 2607a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin table_len ) 2608055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 2609055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE2(( "tt_face_vary_cvt:" 2610055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " invalid CVT variation array header\n" )); 2611055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2612055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin error = FT_THROW( Invalid_Table ); 2613055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto FExit; 2614055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 2615055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2616055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offsetToData += table_start; 2617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2618055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* The documentation implies there are flags packed into */ 2619055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* `tupleCount', but John Jenkins says that shared points don't apply */ 2620055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* to `cvar', and no other flags are defined. */ 2621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2622055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount & 0xFFF )); 2623fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2624fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) 2625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tupleDataSize; 2627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tupleIndex; 2628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed apply; 2629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2631fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE6(( " tuple %d:\n", i )); 2632fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tupleDataSize = FT_GET_USHORT(); 2634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tupleIndex = FT_GET_USHORT(); 2635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* There is no provision here for a global tuple coordinate section, */ 2637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* so John says. There are no tuple indices, just embedded tuples. */ 2638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) 2640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2641fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < blend->num_axis; j++ ) 2642055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ 2643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* short frac to fixed */ 2644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* skip this tuple; it makes no sense */ 2648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) 2650fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < 2 * blend->num_axis; j++ ) 2651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (void)FT_GET_SHORT(); 2652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsetToData += tupleDataSize; 2654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 2655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) 2658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2659fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < blend->num_axis; j++ ) 2660055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_start_coords[j] = FT_GET_SHORT() * 4; 2661fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < blend->num_axis; j++ ) 2662055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[j] = FT_GET_SHORT() * 4; 2663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project apply = ft_var_apply_tuple( blend, 2666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_UShort)tupleIndex, 2667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tuple_coords, 2668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project im_start_coords, 2669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project im_end_coords ); 2670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( /* tuple isn't active for our blend */ 2671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project apply == 0 || 2672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* global points not allowed, */ 2673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if they aren't local, makes no sense */ 2674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) 2675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsetToData += tupleDataSize; 2677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 2678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project here = FT_Stream_FTell( stream ); 2681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream_SeekSet( stream, offsetToData ); 2683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2684055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin localpoints = ft_var_readpackedpoints( stream, 2685055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin table_len, 2686055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin &point_count ); 2687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas = ft_var_readpackeddeltas( stream, 2688055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin table_len, 2689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point_count == 0 ? face->cvt_size 2690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : point_count ); 2691a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !localpoints || !deltas ) 2692fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ; /* failure, ignore it */ 2693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( localpoints == ALL_POINTS ) 2695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2696fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 2697fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int count = 0; 2698fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 2699fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2700fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2701fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " CVT deltas:\n" )); 2702fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this means that there are deltas for every entry in cvt */ 2704fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < face->cvt_size; j++ ) 2705fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2706fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Long orig_cvt = face->cvt[j]; 2707fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2708fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2709fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki face->cvt[j] = (FT_Short)( orig_cvt + 2710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MulFix( deltas[j], apply ) ); 2711fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2712fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 2713fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( orig_cvt != face->cvt[j] ) 2714fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2715fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " %d: %d -> %d\n", 2716fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki j, orig_cvt, face->cvt[j] )); 2717fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki count++; 2718fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2719fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 2720fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2721fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2722fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 2723fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( !count ) 2724fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " none\n" )); 2725fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 2726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2730fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 2731fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int count = 0; 2732fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 2733fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2734fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2735fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " CVT deltas:\n" )); 2736fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2737fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < point_count; j++ ) 2738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2739a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin int pindex; 2740a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Long orig_cvt; 2741a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2742fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2743a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin pindex = localpoints[j]; 2744a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( (FT_ULong)pindex >= face->cvt_size ) 2745a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin continue; 2746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2747a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin orig_cvt = face->cvt[pindex]; 2748fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki face->cvt[pindex] = (FT_Short)( orig_cvt + 2749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MulFix( deltas[j], apply ) ); 2750fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2751fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 2752fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( orig_cvt != face->cvt[pindex] ) 2753fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2754fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " %d: %d -> %d\n", 2755fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki pindex, orig_cvt, face->cvt[pindex] )); 2756fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki count++; 2757fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2758fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 2759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2760fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2761fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 2762fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( !count ) 2763fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " none\n" )); 2764fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 2765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( localpoints != ALL_POINTS ) 2768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( localpoints ); 2769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( deltas ); 2770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsetToData += tupleDataSize; 2772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream_SeekSet( stream, here ); 2774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2776fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "\n" )); 2777fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FExit: 2779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 2780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 2782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( tuple_coords ); 2783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( im_start_coords ); 2784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( im_end_coords ); 2785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2790fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Shift the original coordinates of all points between indices `p1' */ 2791fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* and `p2', using the same difference as given by index `ref'. */ 2792fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2793fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* modeled after `af_iup_shift' */ 2794fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2795fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki static void 2796fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tt_delta_shift( int p1, 2797fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int p2, 2798fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int ref, 2799fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector* in_points, 2800fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector* out_points ) 2801fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2802fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int p; 2803fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector delta; 2804fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2805fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2806fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki delta.x = out_points[ref].x - in_points[ref].x; 2807fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki delta.y = out_points[ref].y - in_points[ref].y; 2808fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2809fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( delta.x == 0 && delta.y == 0 ) 2810fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki return; 2811fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2812fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( p = p1; p < ref; p++ ) 2813fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2814fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points[p].x += delta.x; 2815fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points[p].y += delta.y; 2816fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2817fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2818fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( p = ref + 1; p <= p2; p++ ) 2819fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2820fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points[p].x += delta.x; 2821fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points[p].y += delta.y; 2822fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2823fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2824fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2825fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2826fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Interpolate the original coordinates of all points with indices */ 2827fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* between `p1' and `p2', using `ref1' and `ref2' as the reference */ 2828fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* point indices. */ 2829fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2830fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */ 2831fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* `Ins_IUP' */ 2832fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2833fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki static void 2834fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tt_delta_interpolate( int p1, 2835fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int p2, 2836fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int ref1, 2837fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int ref2, 2838fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector* in_points, 2839fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector* out_points ) 2840fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2841fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int p, i; 2842fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2843fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Pos out, in1, in2, out1, out2, d1, d2; 2844fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2845fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2846fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( p1 > p2 ) 2847fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki return; 2848fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2849fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* handle both horizontal and vertical coordinates */ 2850fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i <= 1; i++ ) 2851fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2852fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* shift array pointers so that we can access `foo.y' as `foo.x' */ 2853fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in_points = (FT_Vector*)( (FT_Pos*)in_points + i ); 2854fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points = (FT_Vector*)( (FT_Pos*)out_points + i ); 2855fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2856fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( in_points[ref1].x > in_points[ref2].x ) 2857fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2858fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki p = ref1; 2859fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ref1 = ref2; 2860fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ref2 = p; 2861fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2862fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2863fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in1 = in_points[ref1].x; 2864fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in2 = in_points[ref2].x; 2865fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out1 = out_points[ref1].x; 2866fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out2 = out_points[ref2].x; 2867fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki d1 = out1 - in1; 2868fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki d2 = out2 - in2; 2869fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2870fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( out1 == out2 || in1 == in2 ) 2871fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2872fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( p = p1; p <= p2; p++ ) 2873fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2874fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out = in_points[p].x; 2875fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2876fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( out <= in1 ) 2877fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out += d1; 2878fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( out >= in2 ) 2879fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out += d2; 2880fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 2881fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out = out1; 2882fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2883fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points[p].x = out; 2884fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2885fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2886fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 2887fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2888fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Fixed scale = FT_DivFix( out2 - out1, in2 - in1 ); 2889fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2890fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2891fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( p = p1; p <= p2; p++ ) 2892fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2893fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out = in_points[p].x; 2894fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2895fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( out <= in1 ) 2896fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out += d1; 2897fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else if ( out >= in2 ) 2898fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out += d2; 2899fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 2900fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out = out1 + FT_MulFix( out - in1, scale ); 2901fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2902fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points[p].x = out; 2903fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2904fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2905fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2906fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2907fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2908fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2909fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Interpolate points without delta values, similar to */ 2910fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* the `IUP' hinting instruction. */ 2911fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2912fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* modeled after `Ins_IUP */ 2913fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2914fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki static void 2915055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tt_interpolate_deltas( FT_Outline* outline, 2916055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Vector* out_points, 2917055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Vector* in_points, 2918055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Bool* has_delta ) 2919fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2920055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int first_point; 2921055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int end_point; 2922fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2923055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int first_delta; 2924055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int cur_delta; 2925fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2926055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Int point; 2927fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Short contour; 2928fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2929fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2930fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* ignore empty outlines */ 2931fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( !outline->n_contours ) 2932fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki return; 2933fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2934fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki contour = 0; 2935fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point = 0; 2936fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2937fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki do 2938fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2939fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki end_point = outline->contours[contour]; 2940fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first_point = point; 2941fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2942fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* search first point that has a delta */ 2943fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki while ( point <= end_point && !has_delta[point] ) 2944fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point++; 2945fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2946fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( point <= end_point ) 2947fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2948fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first_delta = point; 2949fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cur_delta = point; 2950fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2951fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point++; 2952fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2953fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki while ( point <= end_point ) 2954fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2955fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* search next point that has a delta */ 2956fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* and interpolate intermediate points */ 2957fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( has_delta[point] ) 2958fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2959fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tt_delta_interpolate( cur_delta + 1, 2960fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point - 1, 2961fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cur_delta, 2962fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point, 2963fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in_points, 2964fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points ); 2965fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cur_delta = point; 2966fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2967fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2968fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki point++; 2969fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2970fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2971fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* shift contour if we only have a single delta */ 2972fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( cur_delta == first_delta ) 2973fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tt_delta_shift( first_point, 2974fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki end_point, 2975fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cur_delta, 2976fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in_points, 2977fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points ); 2978fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki else 2979fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 2980fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* otherwise handle remaining points */ 2981fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* at the end and beginning of the contour */ 2982fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tt_delta_interpolate( cur_delta + 1, 2983fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki end_point, 2984fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cur_delta, 2985fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first_delta, 2986fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in_points, 2987fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points ); 2988fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2989fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( first_delta > 0 ) 2990fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki tt_delta_interpolate( first_point, 2991fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first_delta - 1, 2992fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki cur_delta, 2993fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki first_delta, 2994fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki in_points, 2995fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki out_points ); 2996fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2997fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 2998fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki contour++; 2999fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3000fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } while ( contour < outline->n_contours ); 3001fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 3002fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3003fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 3005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 3007fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* TT_Vary_Apply_Glyph_Deltas */ 3008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 3010fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Apply the appropriate deltas to the current glyph. */ 3011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Input> */ 3013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* face :: A handle to the target face object. */ 3014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyph_index :: The index of the glyph being modified. */ 3016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* n_points :: The number of the points in the glyph, including */ 3018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* phantom points. */ 3019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3020fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* <InOut> */ 3021fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* outline :: The outline to change. */ 3022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Return> */ 3024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* FreeType error code. 0 means success. */ 3025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 3027fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki TT_Vary_Apply_Glyph_Deltas( TT_Face face, 3028fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt glyph_index, 3029fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Outline* outline, 3030fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt n_points ) 3031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream stream = face->root.stream; 3033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = stream->memory; 3034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GX_Blend blend = face->blend; 3035fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3036fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Vector* points_org = NULL; 3037055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Vector* points_out = NULL; 3038fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_Bool* has_delta = NULL; 3039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Error error; 3041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong glyph_start; 3042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tupleCount; 3043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong offsetToData; 3044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong here; 3045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, j; 3046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* tuple_coords = NULL; 3047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* im_start_coords = NULL; 3048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed* im_end_coords = NULL; 3049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt point_count, spoint_count = 0; 3050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort* sharedpoints = NULL; 3051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort* localpoints = NULL; 3052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UShort* points; 3053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Short *deltas_x, *deltas_y; 3054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3056a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !face->doblend || !blend ) 3057727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Argument ); 3058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( glyph_index >= blend->gv_glyphcnt || 3060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend->glyphoffsets[glyph_index] == 3061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend->glyphoffsets[glyph_index + 1] ) 3062fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 3063fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" 3064fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki " no variation data for this glyph\n" )); 3065fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki return FT_Err_Ok; 3066fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 3067fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3068fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( FT_NEW_ARRAY( points_org, n_points ) || 3069055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_NEW_ARRAY( points_out, n_points ) || 3070fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_NEW_ARRAY( has_delta, n_points ) ) 3071fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Fail1; 3072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || 3074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - 3075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend->glyphoffsets[glyph_index] ) ) 3076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail1; 3077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project glyph_start = FT_Stream_FTell( stream ); 3079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each set of glyph variation data is formatted similarly to `cvar' */ 3081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* (except we get shared points and global tuples) */ 3082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || 3084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || 3085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) 3086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail2; 3087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tupleCount = FT_GET_USHORT(); 3089055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offsetToData = FT_GET_USHORT(); 3090055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3091055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* rough sanity test */ 3092055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > 3093055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gvar_size ) 3094055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 3095055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" 3096055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " invalid glyph variation array header\n" )); 3097055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3098055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin error = FT_THROW( Invalid_Table ); 3099055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Fail2; 3100055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 3101055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3102055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offsetToData += glyph_start; 3103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) 3105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project here = FT_Stream_FTell( stream ); 3107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream_SeekSet( stream, offsetToData ); 3109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3110055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin sharedpoints = ft_var_readpackedpoints( stream, 3111055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gvar_size, 3112055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin &spoint_count ); 3113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsetToData = FT_Stream_FTell( stream ); 3114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream_SeekSet( stream, here ); 3116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3118055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE5(( "gvar: there are %d tuples:\n", 3119055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tupleCount & GX_TC_TUPLE_COUNT_MASK )); 3120055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3121055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for ( j = 0; j < n_points; j++ ) 3122055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin points_org[j] = outline->points[j]; 3123fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3124fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) 3125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tupleDataSize; 3127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tupleIndex; 3128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed apply; 3129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3131fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE6(( " tuple %d:\n", i )); 3132fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tupleDataSize = FT_GET_USHORT(); 3134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tupleIndex = FT_GET_USHORT(); 3135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) 3137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3138fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < blend->num_axis; j++ ) 3139055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ 3140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* short frac to fixed */ 3141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) 3143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3144055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" 3145055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin " invalid tuple index\n" )); 3146055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Table ); 3148fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki goto Fail2; 3149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_MEM_COPY( 3152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tuple_coords, 3153fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], 3154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blend->num_axis * sizeof ( FT_Fixed ) ); 3155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) 3157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3158fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < blend->num_axis; j++ ) 3159055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_start_coords[j] = FT_GET_SHORT() * 4; 3160fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < blend->num_axis; j++ ) 3161055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin im_end_coords[j] = FT_GET_SHORT() * 4; 3162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project apply = ft_var_apply_tuple( blend, 3165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (FT_UShort)tupleIndex, 3166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tuple_coords, 3167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project im_start_coords, 3168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project im_end_coords ); 3169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( apply == 0 ) /* tuple isn't active for our blend */ 3171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsetToData += tupleDataSize; 3173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 3174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project here = FT_Stream_FTell( stream ); 3177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3178055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Stream_SeekSet( stream, offsetToData ); 3179055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) 3181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3182055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin localpoints = ft_var_readpackedpoints( stream, 3183055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gvar_size, 3184055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin &point_count ); 3185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project points = localpoints; 3186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project points = sharedpoints; 3190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point_count = spoint_count; 3191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas_x = ft_var_readpackeddeltas( stream, 3194055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gvar_size, 3195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point_count == 0 ? n_points 3196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : point_count ); 3197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas_y = ft_var_readpackeddeltas( stream, 3198055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin blend->gvar_size, 3199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project point_count == 0 ? n_points 3200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : point_count ); 3201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3202a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !points || !deltas_y || !deltas_x ) 3203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ; /* failure, ignore it */ 3204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( points == ALL_POINTS ) 3206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3207fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 3208fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int count = 0; 3209fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 3210fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3211fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3212fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " point deltas:\n" )); 3213fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this means that there are deltas for every point in the glyph */ 3215fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < n_points; j++ ) 3216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3217055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Pos delta_x = FT_MulFix( deltas_x[j], apply ); 3218055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Pos delta_y = FT_MulFix( deltas_y[j], apply ); 3219fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3220fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3221a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( j < n_points - 3 ) 3222a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3223a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outline->points[j].x += delta_x; 3224a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outline->points[j].y += delta_y; 3225a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3226a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 3227a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3228a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* To avoid double adjustment of advance width or height, */ 3229a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* adjust phantom points only if there is no HVAR or VVAR */ 3230a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* support, respectively. */ 3231a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( j == ( n_points - 3 ) && 3232a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin !( face->variation_support & 3233a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_FACE_FLAG_VAR_HADVANCE ) ) 3234a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outline->points[j].x += delta_x; 3235a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3236a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( j == ( n_points - 2 ) && 3237a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin !( face->variation_support & 3238a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_FACE_FLAG_VAR_LSB ) ) 3239a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outline->points[j].x += delta_x; 3240a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3241a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( j == ( n_points - 1 ) && 3242a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin !( face->variation_support & 3243a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_FACE_FLAG_VAR_VADVANCE ) ) 3244a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outline->points[j].y += delta_y; 3245a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3246a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else if ( j == ( n_points - 0 ) && 3247a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin !( face->variation_support & 3248a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin TT_FACE_FLAG_VAR_TSB ) ) 3249a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin outline->points[j].y += delta_y; 3250a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3251fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3252fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 3253055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( delta_x || delta_y ) 3254fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 3255fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", 3256fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki j, 3257055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin outline->points[j].x - delta_x, 3258055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin outline->points[j].y - delta_y, 3259fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki outline->points[j].x, 3260fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki outline->points[j].y )); 3261fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki count++; 3262fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 3263fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 3264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3265fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3266fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 3267fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( !count ) 3268fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " none\n" )); 3269fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 3270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3274fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef FT_DEBUG_LEVEL_TRACE 3275fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki int count = 0; 3276fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 3277fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3278fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3279fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* we have to interpolate the missing deltas similar to the */ 3280fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* IUP bytecode instruction */ 3281fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < n_points; j++ ) 3282fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 3283fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki has_delta[j] = FALSE; 3284055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin points_out[j] = points_org[j]; 3285fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 3286fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3287fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki for ( j = 0; j < point_count; j++ ) 3288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3289055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UShort idx = points[j]; 3290fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3291fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3292fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( idx >= n_points ) 3293bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly continue; 3294bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly 3295fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki has_delta[idx] = TRUE; 3296fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3297055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin points_out[idx].x += FT_MulFix( deltas_x[j], apply ); 3298055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin points_out[idx].y += FT_MulFix( deltas_y[j], apply ); 3299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3300fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3301fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* no need to handle phantom points here, */ 3302fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* since solitary points can't be interpolated */ 3303055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin tt_interpolate_deltas( outline, 3304055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin points_out, 3305055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin points_org, 3306055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin has_delta ); 3307fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3308fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " point deltas:\n" )); 3309fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3310055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for ( j = 0; j < n_points; j++ ) 3311fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 3312055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Pos delta_x = points_out[j].x - points_org[j].x; 3313055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Pos delta_y = points_out[j].y - points_org[j].y; 3314055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3315055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3316055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin outline->points[j].x += delta_x; 3317055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin outline->points[j].y += delta_y; 3318055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3319055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifdef FT_DEBUG_LEVEL_TRACE 3320055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( delta_x || delta_y ) 3321fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki { 3322fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", 3323fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki j, 3324055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin outline->points[j].x - delta_x, 3325055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin outline->points[j].y - delta_y, 3326fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki outline->points[j].x, 3327fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki outline->points[j].y )); 3328fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki count++; 3329fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 3330055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif 3331fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki } 3332fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3333055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifdef FT_DEBUG_LEVEL_TRACE 3334fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( !count ) 3335fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE7(( " none\n" )); 3336fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif 3337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( localpoints != ALL_POINTS ) 3340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( localpoints ); 3341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( deltas_x ); 3342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( deltas_y ); 3343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsetToData += tupleDataSize; 3345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Stream_SeekSet( stream, here ); 3347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3349fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_TRACE5(( "\n" )); 3350fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 3351fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki Fail2: 3352055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( sharedpoints != ALL_POINTS ) 3353055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_FREE( sharedpoints ); 3354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( tuple_coords ); 3355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( im_start_coords ); 3356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( im_end_coords ); 3357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FRAME_EXIT(); 3359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail1: 3361fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( points_org ); 3362055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_FREE( points_out ); 3363fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_FREE( has_delta ); 3364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 3366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 3370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Function> */ 3372a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* tt_get_var_blend */ 3373a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 3374a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Description> */ 3375a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* An extended internal version of `TT_Get_MM_Blend' that returns */ 3376a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* pointers instead of copying data, without any initialization of */ 3377a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* the MM machinery in case it isn't loaded yet. */ 3378a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 3379a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_LOCAL_DEF( FT_Error ) 3380a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_get_var_blend( TT_Face face, 3381a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt *num_coords, 3382a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Fixed* *coords, 3383a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_MM_Var* *mm_var ) 3384a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3385a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( face->blend ) 3386a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3387a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( num_coords ) 3388a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *num_coords = face->blend->num_axis; 3389a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coords ) 3390a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *coords = face->blend->normalizedcoords; 3391a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( mm_var ) 3392a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *mm_var = face->blend->mmvar; 3393a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3394a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin else 3395a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3396a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( num_coords ) 3397a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *num_coords = 0; 3398a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( coords ) 3399a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *coords = NULL; 3400a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( mm_var ) 3401a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin *mm_var = NULL; 3402a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3403a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3404a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin return FT_Err_Ok; 3405a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3406a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3407a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3408a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin static void 3409a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_done_item_variation_store( TT_Face face, 3410a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_ItemVarStore itemStore ) 3411a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3412a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Memory memory = FT_FACE_MEMORY( face ); 3413a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt i; 3414a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3415a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3416a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( itemStore->varData ) 3417a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3418a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < itemStore->dataCount; i++ ) 3419a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3420a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( itemStore->varData[i].regionIndices ); 3421a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( itemStore->varData[i].deltaSet ); 3422a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3423a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3424a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( itemStore->varData ); 3425a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3426a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3427a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( itemStore->varRegionList ) 3428a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3429a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < itemStore->regionCount; i++ ) 3430a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( itemStore->varRegionList[i].axisList ); 3431a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3432a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( itemStore->varRegionList ); 3433a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3434a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3435a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3436a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3437a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /*************************************************************************/ 3438a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* */ 3439a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* <Function> */ 3440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* tt_done_blend */ 3441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* <Description> */ 3443fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* Free the blend internal data structure. */ 3444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( void ) 3446a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin tt_done_blend( TT_Face face ) 3447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3448a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_Memory memory = FT_FACE_MEMORY( face ); 3449a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin GX_Blend blend = face->blend; 3450a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3451a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3452a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( blend ) 3453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3454a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_UInt i, num_axes; 3455a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3457a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* blend->num_axis might not be set up yet */ 3458a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin num_axes = blend->mmvar->num_axis; 3459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend->normalizedcoords ); 3461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend->mmvar ); 3462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3463a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( blend->avar_segment ) 3464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3465a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < num_axes; i++ ) 3466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend->avar_segment[i].correspondence ); 3467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend->avar_segment ); 3468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3470a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( blend->hvar_table ) 3471a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3472a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_done_item_variation_store( face, 3473a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &blend->hvar_table->itemStore ); 3474a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3475a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->hvar_table->widthMap.innerIndex ); 3476a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->hvar_table->widthMap.outerIndex ); 3477a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->hvar_table ); 3478a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3479a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3480a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( blend->mvar_table ) 3481a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin { 3482a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ft_var_done_item_variation_store( face, 3483a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin &blend->mvar_table->itemStore ); 3484a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3485a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->mvar_table->values ); 3486a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin FT_FREE( blend->mvar_table ); 3487a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin } 3488a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend->tuplecoords ); 3490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend->glyphoffsets ); 3491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( blend ); 3492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 3496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 3499