1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  psmodule.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    PSNames module implementation (body).                                */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 1996-2003, 2005-2008, 2012, 2013 by                          */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_DEBUG_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_POSTSCRIPT_CMAPS_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psmodule.h"
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "pstables.h"
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psnamerr.h"
28295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "pspic.h"
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define VARIANT_BIT         0x80000000UL
38295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define BASE_GLYPH( code )  ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Return the Unicode value corresponding to a given glyph.  Note that */
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* we do deal with glyph variants by detecting a non-initial dot in    */
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the name, as in `A.swash' or `e.final'; in this case, the           */
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* VARIANT_BIT is set in the return value.                             */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_UInt32
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicode_value( const char*  glyph_name )
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the name begins with `uni', then the glyph name may be a */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* hard-coded unicode character code.                          */
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_name[0] == 'u' &&
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph_name[1] == 'n' &&
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph_name[2] == 'i' )
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* determine whether the next four characters following are */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* hexadecimal.                                             */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: Add code to deal with ligatures, i.e. glyph names like */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      `uniXXXXYYYYZZZZ'...                                   */
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int       count;
62295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_UInt32    value = 0;
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  p     = glyph_name + 3;
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( count = 4; count > 0; count--, p++ )
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        char          c = *p;
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        unsigned int  d;
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        d = (unsigned char)c - '0';
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 10 )
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          d = (unsigned char)c - 'A';
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( d >= 6 )
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d = 16;
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d += 10;
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Exit if a non-uppercase hexadecimal character was found   */
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* -- this also catches character codes below `0' since such */
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* negative numbers cast to `unsigned int' are far too big.  */
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 16 )
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        value = ( value << 4 ) + d;
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* there must be exactly four hex digits */
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count == 0 )
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '\0' )
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return value;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '.' )
97295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          return (FT_UInt32)( value | VARIANT_BIT );
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the name begins with `u', followed by four to six uppercase */
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* hexadecimal digits, it is a hard-coded unicode character code. */
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_name[0] == 'u' )
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int       count;
106295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_UInt32    value = 0;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  p     = glyph_name + 1;
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( count = 6; count > 0; count--, p++ )
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        char          c = *p;
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        unsigned int  d;
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        d = (unsigned char)c - '0';
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 10 )
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          d = (unsigned char)c - 'A';
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( d >= 6 )
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d = 16;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d += 10;
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 16 )
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        value = ( value << 4 ) + d;
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count <= 2 )
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '\0' )
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return value;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '.' )
137295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          return (FT_UInt32)( value | VARIANT_BIT );
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Look for a non-initial dot in the glyph name in order to */
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* find variants like `A.swash', `e.final', etc.            */
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  p   = glyph_name;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  dot = NULL;
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; *p; p++ )
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '.' && p > glyph_name )
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          dot = p;
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now look up the glyph in the Adobe Glyph List */
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !dot )
159295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
161295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
162295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                            VARIANT_BIT );
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* ft_qsort callback to sort the unicode map */
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( int )
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  compare_uni_maps( const void*  a,
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const void*  b )
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_UniMap*  map1 = (PS_UniMap*)a;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_UniMap*  map2 = (PS_UniMap*)b;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32   unicode1 = BASE_GLYPH( map1->unicode );
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32   unicode2 = BASE_GLYPH( map2->unicode );
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* sort base glyphs before glyph variants */
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( unicode1 == unicode2 )
1800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( map1->unicode > map2->unicode )
1820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 1;
1830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else if ( map1->unicode < map2->unicode )
1840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return -1;
1850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
1860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 0;
1870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( unicode1 > unicode2 )
1910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 1;
1920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else if ( unicode1 < unicode2 )
1930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return -1;
1940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
1950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 0;
1960a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* support for extra glyphs not handled (well) in AGL; */
2010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we add extra mappings for them if necessary         */
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define EXTRA_GLYPH_LIST_SIZE  10
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static const FT_UInt32  ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* WGL 4 */
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x0394,
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x03A9,
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x2215,
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x00AD,
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x02C9,
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x03BC,
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x2219,
2150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    0x00A0,
2160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* Romanian */
2170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    0x021A,
2180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    0x021B
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static const char  ft_extra_glyph_names[] =
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'D','e','l','t','a',0,
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'O','m','e','g','a',0,
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'f','r','a','c','t','i','o','n',0,
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'h','y','p','h','e','n',0,
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'm','a','c','r','o','n',0,
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'm','u',0,
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,
2300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    's','p','a','c','e',0,
2310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    'T','c','o','m','m','a','a','c','c','e','n','t',0,
2320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    't','c','o','m','m','a','a','c','c','e','n','t',0
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Int
2360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     0,
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     6,
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    12,
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    21,
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    28,
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    35,
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    38,
2450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    53,
2460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    59,
2470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    72
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ps_check_extra_glyph_name( const char*  gname,
2530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                             FT_UInt      glyph,
2540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                             FT_UInt*     extra_glyphs,
2550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                             FT_UInt     *states )
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  n;
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( ft_strcmp( ft_extra_glyph_names +
2630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        ft_extra_glyph_name_offsets[n], gname ) == 0 )
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( states[n] == 0 )
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* mark this extra glyph as a candidate for the cmap */
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          states[n]     = 1;
2690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          extra_glyphs[n] = glyph;
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ps_check_extra_glyph_unicode( FT_UInt32  uni_char,
2800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                FT_UInt   *states )
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  n;
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( uni_char == ft_extra_glyph_unicodes[n] )
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        /* disable this extra glyph from being added to the cmap */
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        states[n] = 2;
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Build a table that maps Unicode values to glyph indices. */
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicodes_init( FT_Memory             memory,
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PS_Unicodes           table,
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt               num_glyphs,
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PS_GetGlyphNameFunc   get_glyph_name,
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PS_FreeGlyphNameFunc  free_glyph_name,
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Pointer            glyph_data )
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_UInt  extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_UInt  extra_glyphs[EXTRA_GLYPH_LIST_SIZE];
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we first allocate the table */
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->num_maps = 0;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->maps     = 0;
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     n;
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     count;
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PS_UniMap*  map;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32   uni_char;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      map = table->maps;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( n = 0; n < num_glyphs; n++ )
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        const char*  gname = get_glyph_name( glyph_data, n );
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( gname )
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          ps_check_extra_glyph_name( gname, n,
3350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                     extra_glyphs, extra_glyph_list_states );
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          uni_char = ps_unicode_value( gname );
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( BASE_GLYPH( uni_char ) != 0 )
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            ps_check_extra_glyph_unicode( uni_char,
3410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                          extra_glyph_list_states );
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            map->unicode     = uni_char;
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            map->glyph_index = n;
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            map++;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( free_glyph_name )
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            free_glyph_name( glyph_data, gname );
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( extra_glyph_list_states[n] == 1 )
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* This glyph name has an additional representation. */
3570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* Add it to the cmap.                               */
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          map->unicode     = ft_extra_glyph_unicodes[n];
3600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          map->glyph_index = extra_glyphs[n];
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          map++;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now compress the table a bit */
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = (FT_UInt)( map - table->maps );
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count == 0 )
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
370aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* No unicode chars here! */
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( table->maps );
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
373727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error = FT_THROW( No_Unicode_Glyph_Name );
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
375aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
376aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Reallocate if the number of used entries is much smaller. */
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( count < num_glyphs / 2 )
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
381727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error = FT_Err_Ok;
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Sort the table in increasing order of unicode values, */
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* taking care of glyph variants.                        */
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_qsort( table->maps, count, sizeof ( PS_UniMap ),
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  compare_uni_maps );
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->num_maps = count;
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_UInt
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicodes_char_index( PS_Unicodes  table,
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_UInt32    unicode )
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_UniMap  *min, *max, *mid, *result = NULL;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Perform a binary search on the table. */
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    min = table->maps;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    max = min + table->num_maps - 1;
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( min <= max )
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32  base_glyph;
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mid = min + ( ( max - min ) >> 1 );
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( mid->unicode == unicode )
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = mid;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      base_glyph = BASE_GLYPH( mid->unicode );
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( base_glyph == unicode )
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = mid; /* remember match but continue search for base glyph */
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( min == max )
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( base_glyph < unicode )
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = mid + 1;
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = mid - 1;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( result )
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return result->glyph_index;
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
443295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static FT_UInt32
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicodes_char_next( PS_Unicodes  table,
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_UInt32   *unicode )
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    result    = 0;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  char_code = *unicode + 1;
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     min = 0;
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     max = table->num_maps;
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     mid;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PS_UniMap*  map;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32   base_glyph;
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( min < max )
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mid = min + ( ( max - min ) >> 1 );
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map = table->maps + mid;
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( map->unicode == char_code )
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = map->glyph_index;
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        base_glyph = BASE_GLYPH( map->unicode );
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( base_glyph == char_code )
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = map->glyph_index;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( base_glyph < char_code )
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          min = mid + 1;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          max = mid;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( result )
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;               /* we have a variant glyph */
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we didn't find it; check whether we have a map just above it */
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_code = 0;
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( min < table->num_maps )
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map       = table->maps + min;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result    = map->glyph_index;
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        char_code = BASE_GLYPH( map->unicode );
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *unicode = char_code;
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const char*
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_get_macintosh_name( FT_UInt  name_index )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( name_index >= FT_NUM_MAC_NAMES )
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      name_index = 0;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ft_standard_glyph_names + ft_mac_names[name_index];
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const char*
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_get_standard_strings( FT_UInt  sid )
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sid >= FT_NUM_SID_NAMES )
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ft_standard_glyph_names + ft_sid_names[sid];
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
525727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_DEFINE_SERVICE_PSCMAPSREC(
527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    pscmaps_interface,
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicode_ValueFunc)     ps_unicode_value,
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicodes_InitFunc)     ps_unicodes_init,
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
534295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
535295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    t1_standard_encoding,
537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    t1_expert_encoding )
538295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
541727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_DEFINE_SERVICE_PSCMAPSREC(
542727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    pscmaps_interface,
543727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    NULL,
544727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    NULL,
545727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    NULL,
546727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    NULL,
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    t1_standard_encoding,
552727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    t1_expert_encoding )
553295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
554295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
555295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
556295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
557727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_DEFINE_SERVICEDESCREC1(
558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    pscmaps_services,
559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET )
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Pointer
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  psnames_get_service( FT_Module    module,
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       const char*  service_id )
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
566727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */
56741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifdef FT_CONFIG_OPTION_PIC
56841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    FT_Library  library;
56941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
57041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
57141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    if ( !module )
57241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      return NULL;
57341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    library = module->library;
57441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    if ( !library )
57541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      return NULL;
57641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#else
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( module );
57841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#endif
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id );
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
586295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
587727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define PUT_PS_NAMES_SERVICE( a )  NULL
588295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else
589727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define PUT_PS_NAMES_SERVICE( a )  a
590295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
592727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_DEFINE_MODULE(
593727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    psnames_module_class,
59441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0,  /* this is not a font driver, nor a renderer */
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sizeof ( FT_ModuleRec ),
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    "psnames",  /* driver name                         */
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x10000L,   /* driver version                      */
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x20000L,   /* driver requires FreeType 2 or above */
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
602727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    PUT_PS_NAMES_SERVICE(
603727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      (void*)&PSCMAPS_INTERFACE_GET ),   /* module specific interface */
604727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    (FT_Module_Constructor)NULL,
605727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    (FT_Module_Destructor) NULL,
606727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE( psnames_get_service ) )
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
610