1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ttsbit.c                                                               */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    TrueType and OpenType embedded bitmap support (body).                */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
8aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich/*            2010 by                                                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  Alas, the memory-optimized sbit loader can't be used when implementing
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  the `old internals' hack
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
2877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifndef FT_CONFIG_OPTION_OLD_INTERNALS
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttsbit0.c"
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#else /* FT_CONFIG_OPTION_OLD_INTERNALS */
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttsbit.h"
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "sferrors.h"
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_ttsbit
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    blit_sbit                                                          */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Blits a bitmap from an input stream into a given target.  Supports */
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    x and y offsets as well as byte padded lines.                      */
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    target      :: The target bitmap/pixmap.                           */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    source      :: The input packed bitmap data.                       */
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    line_bits   :: The number of bits per line.                        */
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    byte_padded :: A flag which is true if lines are byte-padded.      */
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    x_offset    :: The horizontal offset.                              */
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    y_offset    :: The vertical offset.                                */
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    IMPORTANT: The x and y offsets are relative to the top corner of   */
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*               the target bitmap (unlike the normal TrueType           */
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*               convention).  A positive y offset indicates a downwards */
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*               direction!                                              */
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  blit_sbit( FT_Bitmap*  target,
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Byte*    source,
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Int      line_bits,
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Bool     byte_padded,
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Int      x_offset,
8777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner             FT_Int      y_offset,
8877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner             FT_Int      source_height )
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*   line_buff;
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     line_incr;
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     height;
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  acc;
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    loaded;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, compute starting write position */
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    line_incr = target->pitch;
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    line_buff = target->buffer;
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( line_incr < 0 )
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line_buff -= line_incr * ( target->rows - 1 );
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We use the extra-classic `accumulator' trick to extract the bits    */
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* from the source byte stream.                                        */
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Namely, the variable `acc' is a 16-bit accumulator containing the   */
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* last `loaded' bits from the input stream.  The bits are shifted to  */
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the upmost position in `acc'.                                       */
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    acc    = 0;  /* clear accumulator   */
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loaded = 0;  /* no bits were loaded */
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    for ( height = source_height; height > 0; height-- )
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  cur   = line_buff;        /* current write cursor          */
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int    count = line_bits;        /* # of bits to extract per line */
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte   shift = (FT_Byte)( x_offset & 7 ); /* current write shift  */
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte   space = (FT_Byte)( 8 - shift );
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* first of all, read individual source bytes */
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count >= 8 )
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count -= 8;
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          do
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Byte  val;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* ensure that there are at least 8 bits in the accumulator */
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( loaded < 8 )
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              loaded += 8;
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* now write one byte */
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            val = (FT_Byte)( acc >> 8 );
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( shift )
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[0] |= (FT_Byte)( val >> shift );
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[1] |= (FT_Byte)( val << space );
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[0] |= val;
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur++;
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            acc   <<= 8;  /* remove bits from accumulator */
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loaded -= 8;
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            count  -= 8;
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          } while ( count >= 0 );
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* restore `count' to correct value */
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count += 8;
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now write remaining bits (count < 8) */
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count > 0 )
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte  val;
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* ensure that there are at least `count' bits in the accumulator */
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( (FT_Int)loaded < count )
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          loaded += 8;
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* now write remaining bits */
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        val     = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur[0] |= (FT_Byte)( val >> shift );
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( count > space )
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cur[1] |= (FT_Byte)( val << space );
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        acc   <<= count;
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loaded -= count;
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, skip to next line */
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( byte_padded )
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        acc    = 0;
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loaded = 0;   /* clear accumulator on byte-padded lines */
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line_buff += line_incr;
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Frame_Field  sbit_metrics_fields[] =
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_SBit_MetricsRec
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_START( 8 ),
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_BYTE( height ),
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_BYTE( width ),
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_CHAR( horiBearingX ),
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_CHAR( horiBearingY ),
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_BYTE( horiAdvance ),
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_CHAR( vertBearingX ),
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_CHAR( vertBearingY ),
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_BYTE( vertAdvance ),
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_END
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load_SBit_Const_Metrics                                            */
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    range  :: The target range.                                        */
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_SBit_Const_Metrics( TT_SBit_Range  range,
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Stream      stream )
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_READ_ULONG( range->image_size ) )
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load_SBit_Range_Codes                                              */
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    range        :: The target range.                                  */
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream       :: The input stream.                                  */
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    load_offsets :: A flag whether to load the glyph offset table.     */
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_SBit_Range_Codes( TT_SBit_Range  range,
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Stream      stream,
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Bool        load_offsets )
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   count, n, size;
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_READ_ULONG( count ) )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    range->num_glyphs = count;
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Allocate glyph offsets table if needed */
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_offsets )
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size = count * 4L;
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size = count * 2L;
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Allocate glyph codes table and access frame */
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_FRAME_ENTER( size )                     )
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < count; n++ )
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      range->glyph_codes[n] = FT_GET_USHORT();
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( load_offsets )
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        range->glyph_offsets[n] = (FT_ULong)range->image_offset +
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_GET_USHORT();
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load_SBit_Range                                                    */
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads a given `EBLC' index/range table.                            */
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    range  :: The target range.                                        */
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_SBit_Range( TT_SBit_Range  range,
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Stream      stream )
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch( range->index_format )
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 1:   /* variable metrics with 4-byte offsets */
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 3:   /* variable metrics with 2-byte offsets */
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ULong  num_glyphs, n;
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    size_elem;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bool   large = FT_BOOL( range->index_format == 1 );
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( range->last_glyph < range->first_glyph )
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = SFNT_Err_Invalid_File_Format;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        num_glyphs        = range->last_glyph - range->first_glyph + 1L;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        range->num_glyphs = num_glyphs;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        num_glyphs++;                       /* XXX: BEWARE - see spec */
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        size_elem = large ? 4 : 2;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_FRAME_ENTER( num_glyphs * size_elem )         )
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( n = 0; n < num_glyphs; n++ )
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                ( large ? FT_GET_ULONG()
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                        : FT_GET_USHORT() ) );
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_EXIT();
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 2:   /* all glyphs have identical metrics */
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Load_SBit_Const_Metrics( range, stream );
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 4:
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Load_SBit_Range_Codes( range, stream, 1 );
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 5:
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Load_SBit_Const_Metrics( range, stream );
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = Load_SBit_Range_Codes( range, stream, 0 );
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = SFNT_Err_Invalid_File_Format;
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_eblc                                                  */
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the table of embedded bitmap sizes for this face.            */
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: The target face object.                                  */
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_eblc( TT_Face    face,
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
421aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Error   error  = SFNT_Err_Ok;
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed   version;
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   num_strikes;
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   table_base;
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  sbit_line_metrics_fields[] =
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_SBit_LineMetricsRec
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no FT_FRAME_START */
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( ascender ),
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( descender ),
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( max_width ),
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( caret_slope_numerator ),
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( caret_slope_denominator ),
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( caret_offset ),
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( min_origin_SB ),
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( min_advance_SB ),
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( max_before_BL ),
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( min_after_BL ),
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( pads[0] ),
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR( pads[1] ),
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  strike_start_fields[] =
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_SBit_StrikeRec
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no FT_FRAME_START */
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( ranges_offset ),
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SKIP_LONG,
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( num_ranges ),
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( color_ref ),
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  strike_end_fields[] =
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no FT_FRAME_START */
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( start_glyph ),
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( end_glyph ),
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( x_ppem ),
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( y_ppem ),
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( bit_depth ),
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR  ( flags ),
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_sbit_strikes = 0;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* this table is optional */
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_EBLC, stream, 0 );
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->goto_table( face, TTAG_bloc, stream, 0 );
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table_base = FT_STREAM_POS();
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_FRAME_ENTER( 8L ) )
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    version     = FT_GET_LONG();
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    num_strikes = FT_GET_ULONG();
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check version number and strike count */
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( version     != 0x00020000L ||
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         num_strikes >= 0x10000L    )
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
498295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = SFNT_Err_Invalid_File_Format;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the strikes table */
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_sbit_strikes = num_strikes;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now read each strike table separately */
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_SBit_Strike  strike = face->sbit_strikes;
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong        count  = num_strikes;
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_ENTER( 48L * num_strikes ) )
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( count > 0 )
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike )             ||
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_STREAM_READ_FIELDS( strike_end_fields, strike )               )
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count--;
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        strike++;
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_EXIT();
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the index ranges for each strike table */
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_SBit_Strike  strike = face->sbit_strikes;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong        count  = num_strikes;
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( count > 0 )
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TT_SBit_Range  range;
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ULong       count2 = strike->num_ranges;
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* read each range */
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_FRAME_ENTER( strike->num_ranges * 8L )            )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        range = strike->sbit_ranges;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( count2 > 0 )
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->first_glyph  = FT_GET_USHORT();
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->last_glyph   = FT_GET_USHORT();
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->table_offset = table_base + strike->ranges_offset +
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_GET_ULONG();
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          count2--;
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range++;
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_EXIT();
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Now, read each index table */
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count2 = strike->num_ranges;
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        range  = strike->sbit_ranges;
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( count2 > 0 )
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Read the header */
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_STREAM_SEEK( range->table_offset ) ||
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_FRAME_ENTER( 8L )                  )
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->index_format = FT_GET_USHORT();
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->image_format = FT_GET_USHORT();
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range->image_offset = FT_GET_ULONG();
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_EXIT();
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = Load_SBit_Range( range, stream );
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( error )
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          count2--;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          range++;
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count--;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        strike++;
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_free_eblc                                                  */
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Releases the embedded bitmap tables.                               */
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face :: The target face object.                                    */
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_free_eblc( TT_Face  face )
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory       memory       = face->root.memory;
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_Strike  strike       = face->sbit_strikes;
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_Strike  strike_limit = strike + face->num_sbit_strikes;
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( strike )
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; strike < strike_limit; strike++ )
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TT_SBit_Range  range       = strike->sbit_ranges;
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TT_SBit_Range  range_limit = range + strike->num_ranges;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( range )
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( ; range < range_limit; range++ )
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* release the glyph offsets and codes tables */
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* where appropriate                          */
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FREE( range->glyph_offsets );
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FREE( range->glyph_codes );
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( strike->sbit_ranges );
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        strike->num_ranges = 0;
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face->sbit_strikes );
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_sbit_strikes = 0;
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_set_sbit_strike( TT_Face          face,
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Size_Request  req,
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_ULong*        astrike_index )
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_strike_metrics( TT_Face           face,
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong          strike_index,
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Size_Metrics*  metrics )
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_Strike  strike;
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( strike_index >= face->num_sbit_strikes )
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SFNT_Err_Invalid_Argument;
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    strike = face->sbit_strikes + strike_index;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->x_ppem = strike->x_ppem;
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->y_ppem = strike->y_ppem;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender  = strike->hori.ascender << 6;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender = strike->hori.descender << 6;
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX: Is this correct? */
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = ( strike->hori.min_origin_SB  +
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             strike->hori.max_width      +
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             strike->hori.min_advance_SB ) << 6;
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height = metrics->ascender - metrics->descender;
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return SFNT_Err_Ok;
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_sbit_range                                                    */
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Scans a given strike's ranges and return, for a given glyph        */
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    index, the corresponding sbit range, and `EBDT' offset.            */
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph_index   :: The glyph index.                                  */
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    strike        :: The source/current sbit strike.                   */
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    arange        :: The sbit range containing the glyph index.        */
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means the glyph index was found.           */
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_sbit_range( FT_UInt          glyph_index,
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   TT_SBit_Strike   strike,
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   TT_SBit_Range   *arange,
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_ULong        *aglyph_offset )
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_RangeRec  *range, *range_limit;
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether the glyph index is within this strike's */
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* glyph range                                           */
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_index < (FT_UInt)strike->start_glyph ||
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph_index > (FT_UInt)strike->end_glyph   )
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* scan all ranges in strike */
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    range       = strike->sbit_ranges;
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    range_limit = range + strike->num_ranges;
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !range )
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; range < range_limit; range++ )
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( glyph_index >= (FT_UInt)range->first_glyph &&
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           glyph_index <= (FT_UInt)range->last_glyph  )
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UShort  delta = (FT_UShort)( glyph_index - range->first_glyph );
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        switch ( range->index_format )
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 1:
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 3:
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *aglyph_offset = range->glyph_offsets[delta];
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 2:
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *aglyph_offset = range->image_offset +
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           range->image_size * delta;
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 4:
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 5:
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_ULong  n;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( n = 0; n < range->num_glyphs; n++ )
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                if ( range->index_format == 4 )
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  *aglyph_offset = range->glyph_offsets[n];
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                else
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  *aglyph_offset = range->image_offset +
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   n * range->image_size;
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Found;
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* fall-through */
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        default:
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Found:
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* return successfully! */
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *arange  = range;
77777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return SFNT_Err_Ok;
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *arange        = 0;
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *aglyph_offset = 0;
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return SFNT_Err_Invalid_Argument;
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_find_sbit_image                                                 */
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph, at a given strike.                                          */
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face          :: The target face object.                           */
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph_index   :: The glyph index.                                  */
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    strike_index  :: The current strike index.                         */
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    arange        :: The SBit range containing the glyph index.        */
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    astrike       :: The SBit strike containing the glyph index.       */
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.  Returns                    */
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    SFNT_Err_Invalid_Argument if no sbit exists for the requested      */
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph.                                                             */
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL( FT_Error )
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_find_sbit_image( TT_Face          face,
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt          glyph_index,
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong         strike_index,
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      TT_SBit_Range   *arange,
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      TT_SBit_Strike  *astrike,
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong        *aglyph_offset )
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_Strike  strike;
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face->sbit_strikes                        ||
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         ( face->num_sbit_strikes <= strike_index ) )
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    strike = &face->sbit_strikes[strike_index];
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = find_sbit_range( glyph_index, strike,
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             arange, aglyph_offset );
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astrike = strike;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return SFNT_Err_Ok;
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* no embedded bitmap for this glyph in face */
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *arange        = 0;
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astrike       = 0;
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *aglyph_offset = 0;
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return SFNT_Err_Invalid_Argument;
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_load_sbit_metrics                                               */
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Gets the big metrics for a given SBit.                             */
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream      :: The input stream.                                   */
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    range       :: The SBit range containing the glyph.                */
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    big_metrics :: A big SBit metrics structure for the glyph.         */
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    The stream cursor must be positioned at the glyph's offset within  */
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    the `EBDT' table before the call.                                  */
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    If the image format uses variable metrics, the stream cursor is    */
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    positioned just after the metrics header in the `EBDT' table on    */
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    function exit.                                                     */
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL( FT_Error )
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_load_sbit_metrics( FT_Stream        stream,
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        TT_SBit_Range    range,
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        TT_SBit_Metrics  metrics )
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = SFNT_Err_Ok;
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( range->image_format )
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 1:
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 2:
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 8:
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* variable small metrics */
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TT_SBit_SmallMetricsRec  smetrics;
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        static const FT_Frame_Field  sbit_small_metrics_fields[] =
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_SBit_SmallMetricsRec
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_START( 5 ),
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FRAME_BYTE( height ),
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FRAME_BYTE( width ),
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FRAME_CHAR( bearingX ),
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FRAME_CHAR( bearingY ),
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FRAME_BYTE( advance ),
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_END
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        };
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* read small metrics */
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* convert it to a big metrics */
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->height       = smetrics.height;
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->width        = smetrics.width;
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->horiBearingX = smetrics.bearingX;
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->horiBearingY = smetrics.bearingY;
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->horiAdvance  = smetrics.advance;
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* these metrics are made up at a higher level when */
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* needed.                                          */
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->vertBearingX = 0;
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->vertBearingY = 0;
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->vertAdvance  = 0;
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 6:
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 7:
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 9:
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* variable big metrics */
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 5:
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:  /* constant metrics */
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( range->index_format == 2 || range->index_format == 5 )
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *metrics = range->metrics;
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return SFNT_Err_Invalid_File_Format;
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   }
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    crop_bitmap                                                        */
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Crops a bitmap to its tightest bounding box, and adjusts its       */
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    metrics.                                                           */
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    map     :: The bitmap.                                             */
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    metrics :: The corresponding metrics structure.                    */
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  crop_bitmap( FT_Bitmap*       map,
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               TT_SBit_Metrics  metrics )
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* In this situation, some bounding boxes of embedded bitmaps are too  */
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* large.  We need to crop it to a reasonable size.                    */
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      ---------                                                      */
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |       |                -----                                 */
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |  ***  |                |***|                                 */
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |   *   |                | * |                                 */
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |   *   |    ------>     | * |                                 */
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |   *   |                | * |                                 */
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |   *   |                | * |                                 */
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      |  ***  |                |***|                                 */
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      ---------                -----                                 */
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    rows, count;
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   line_len;
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  line;
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, check the top-most lines of the bitmap, and remove    */
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* them if they're empty.                                              */
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line     = (FT_Byte*)map->buffer;
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rows     = map->rows;
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line_len = map->pitch;
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( count = 0; count < rows; count++ )
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  cur   = line;
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  limit = line + line_len;
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; cur < limit; cur++ )
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cur[0] )
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Found_Top;
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* the current line was empty - skip to next one */
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        line  = limit;
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Found_Top:
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check that we have at least one filled line */
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count >= rows )
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Empty_Bitmap;
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, crop the empty upper lines */
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count > 0 )
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        line = (FT_Byte*)map->buffer;
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_MEM_MOVE( line, line + count * line_len,
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     ( rows - count ) * line_len );
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->height       = (FT_Byte)( metrics->height - count );
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->rows -= count;
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rows      -= count;
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* second, crop the lower lines                                        */
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( count = 0; count < rows; count++ )
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  cur   = line;
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  limit = line + line_len;
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; cur < limit; cur++ )
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cur[0] )
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Found_Bottom;
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* the current line was empty - skip to previous one */
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        line -= line_len;
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Found_Bottom:
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count > 0 )
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->height  = (FT_Byte)( metrics->height - count );
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rows            -= count;
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->rows       -= count;
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* third, get rid of the space on the left side of the glyph           */
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  limit;
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line  = (FT_Byte*)map->buffer;
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = line + rows * line_len;
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; line < limit; line += line_len )
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( line[0] & 0x80 )
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Found_Left;
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* shift the whole glyph one pixel to the left */
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line  = (FT_Byte*)map->buffer;
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = line + rows * line_len;
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; line < limit; line += line_len )
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int    n, width = map->width;
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte   old;
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  cur = line;
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        old = (FT_Byte)(cur[0] << 1);
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( n = 8; n < width; n += 8 )
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte  val;
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          val    = cur[1];
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cur[0] = (FT_Byte)( old | ( val >> 7 ) );
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          old    = (FT_Byte)( val << 1 );
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cur++;
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur[0] = old;
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      map->width--;
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX++;
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX++;
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width--;
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( map->width > 0 );
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Found_Left:
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finally, crop the bitmap width to get rid of the space on the right */
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* side of the glyph.                                                  */
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int    right = map->width - 1;
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  limit;
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte   mask;
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      line  = (FT_Byte*)map->buffer + ( right >> 3 );
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = line + rows * line_len;
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mask  = (FT_Byte)( 0x80 >> ( right & 7 ) );
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; line < limit; line += line_len )
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( line[0] & mask )
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Found_Right;
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* crop the whole glyph to the right */
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      map->width--;
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width--;
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( map->width > 0 );
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Found_Right:
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* all right, the bitmap was cropped */
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return;
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Empty_Bitmap:
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    map->width      = 0;
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    map->rows       = 0;
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    map->pitch      = 0;
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    map->pixel_mode = FT_PIXEL_MODE_MONO;
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_SBit_Single( FT_Bitmap*       map,
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Int           x_offset,
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Int           y_offset,
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Int           pix_bits,
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UShort        image_format,
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    TT_SBit_Metrics  metrics,
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream        stream )
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check that the source bitmap fits into the target pixmap */
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x_offset < 0 || x_offset + metrics->width  > map->width ||
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         y_offset < 0 || y_offset + metrics->height > map->rows  )
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = SFNT_Err_Invalid_Argument;
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int   glyph_width  = metrics->width;
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int   glyph_height = metrics->height;
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int   glyph_size;
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int   line_bits    = pix_bits * glyph_width;
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Bool  pad_bytes    = 0;
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute size of glyph image */
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( image_format )
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:  /* byte-padded formats */
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 6:
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int  line_length;
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          switch ( pix_bits )
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 1:
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            line_length = ( glyph_width + 7 ) >> 3;
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 2:
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            line_length = ( glyph_width + 3 ) >> 2;
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 4:
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            line_length = ( glyph_width + 1 ) >> 1;
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          default:
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            line_length =   glyph_width;
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          glyph_size = glyph_height * line_length;
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pad_bytes  = 1;
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 5:
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 7:
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        line_bits  =   glyph_width  * pix_bits;
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:  /* invalid format */
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return SFNT_Err_Invalid_File_Format;
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Now read data and draw glyph into target pixmap       */
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_ENTER( glyph_size ) )
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* don't forget to multiply `x_offset' by `map->pix_bits' as */
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* the sbit blitter doesn't make a difference between pixmap */
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* depths.                                                   */
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
123577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                 x_offset * pix_bits, y_offset, metrics->height );
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_EXIT();
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_SBit_Image( TT_SBit_Strike   strike,
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   TT_SBit_Range    range,
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_ULong         ebdt_pos,
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_ULong         glyph_offset,
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_GlyphSlot     slot,
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int           x_offset,
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int           y_offset,
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Stream        stream,
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   TT_SBit_Metrics  metrics,
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int           depth )
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory   memory = stream->memory;
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap*  map    = &slot->bitmap;
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* place stream at beginning of glyph data and read metrics */
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = tt_load_sbit_metrics( stream, range, metrics );
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This function is recursive.  At the top-level call, we  */
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the dimensions of the higher-level glyph to     */
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the final pixmap buffer.                       */
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( depth == 0 )
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  size;
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      map->width = metrics->width;
1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      map->rows  = metrics->height;
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( strike->bit_depth )
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pixel_mode = FT_PIXEL_MODE_MONO;
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pitch      = ( map->width + 7 ) >> 3;
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pixel_mode = FT_PIXEL_MODE_GRAY2;
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pitch      = ( map->width + 3 ) >> 2;
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 4:
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pixel_mode = FT_PIXEL_MODE_GRAY4;
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pitch      = ( map->width + 1 ) >> 1;
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 8:
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pixel_mode = FT_PIXEL_MODE_GRAY;
1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map->pitch      = map->width;
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return SFNT_Err_Invalid_File_Format;
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size = map->rows * map->pitch;
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check that there is no empty image */
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( size == 0 )
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;     /* exit successfully! */
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_glyphslot_alloc_bitmap( slot, size );
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if (error)
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( range->image_format )
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 1:  /* single sbit image - load it */
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 2:
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 5:
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 6:
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 7:
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               range->image_format, metrics, stream );
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 8:  /* compound format */
132977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( FT_STREAM_SKIP( 1L ) )
133077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
133177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        error = SFNT_Err_Invalid_Stream_Skip;
133277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        goto Exit;
133377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* fallthrough */
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 9:
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default: /* invalid image format */
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SFNT_Err_Invalid_File_Format;
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* All right, we have a compound format.  First of all, read */
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the array of elements.                                    */
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1346aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      TT_SBit_Component  components = NULL;
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_SBit_Component  comp;
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UShort          num_components, count;
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_USHORT( num_components )           ||
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_NEW_ARRAY( components, num_components ) )
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = num_components;
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_ENTER( 4L * num_components ) )
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail_Memory;
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( comp = components; count > 0; count--, comp++ )
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        comp->glyph_code = FT_GET_USHORT();
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        comp->x_offset   = FT_GET_CHAR();
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        comp->y_offset   = FT_GET_CHAR();
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_EXIT();
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Now recursively load each element glyph */
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = num_components;
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      comp  = components;
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; count > 0; count--, comp++ )
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TT_SBit_Range       elem_range;
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TT_SBit_MetricsRec  elem_metrics;
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ULong            elem_offset;
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* find the range for this element */
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = find_sbit_range( comp->glyph_code,
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 strike,
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 &elem_range,
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 &elem_offset );
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail_Memory;
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* now load the element, recursively */
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = Load_SBit_Image( strike,
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 elem_range,
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 ebdt_pos,
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 elem_offset,
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 slot,
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 x_offset + comp->x_offset,
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 y_offset + comp->y_offset,
1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 stream,
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 &elem_metrics,
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 depth + 1 );
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail_Memory;
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Fail_Memory:
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( components );
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_sbit_image                                            */
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads a given glyph sbit image from the font resource.  This also  */
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    returns its metrics.                                               */
1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face         :: The target face object.                            */
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    strike_index :: The current strike index.                          */
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph_index  :: The current glyph index.                           */
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    load_flags   :: The glyph load flags (the code checks for the flag */
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                    FT_LOAD_CROP_BITMAP).                              */
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream       :: The input stream.                                  */
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    map          :: The target pixmap.                                 */
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    metrics      :: A big sbit metrics structure for the glyph image.  */
1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.  Returns an error if no     */
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph sbit exists for the index.                                   */
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*  <Note>                                                               */
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    The `map.buffer' field is always freed before the glyph is loaded. */
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_sbit_image( TT_Face              face,
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_ULong             strike_index,
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt              glyph_index,
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt              load_flags,
1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Stream            stream,
1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Bitmap           *map,
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           TT_SBit_MetricsRec  *metrics )
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong        ebdt_pos, glyph_offset;
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_Strike  strike;
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_Range   range;
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check whether there is a glyph sbit for the current index */
1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = tt_find_sbit_image( face, glyph_index, strike_index,
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                &range, &strike, &glyph_offset );
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, find the location of the `EBDT' table in */
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the font file                                 */
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_EBDT, stream, 0 );
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->goto_table( face, TTAG_bdat, stream, 0 );
1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ebdt_pos = FT_STREAM_POS();
1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             face->root.glyph, 0, 0, stream, metrics, 0 );
1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* setup vertical metrics if needed */
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( strike->flags & 1 )
1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* in case of a horizontal strike only */
1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  advance;
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      advance = strike->hori.ascender - strike->hori.descender;
1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* some heuristic values */
1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertAdvance  = (FT_Char)( advance * 12 / 10 );
1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Crop the bitmap now, unless specified otherwise */
1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_CROP_BITMAP )
1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      crop_bitmap( map, metrics );
1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
150577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1509