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/*                                                                         */
7049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 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>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_POSTSCRIPT_CMAPS_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psmodule.h"
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "pstables.h"
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psnamerr.h"
27295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "pspic.h"
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define VARIANT_BIT         0x80000000UL
37295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define BASE_GLYPH( code )  ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Return the Unicode value corresponding to a given glyph.  Note that */
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* we do deal with glyph variants by detecting a non-initial dot in    */
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the name, as in `A.swash' or `e.final'; in this case, the           */
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* VARIANT_BIT is set in the return value.                             */
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_UInt32
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicode_value( const char*  glyph_name )
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the name begins with `uni', then the glyph name may be a */
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* hard-coded unicode character code.                          */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_name[0] == 'u' &&
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph_name[1] == 'n' &&
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph_name[2] == 'i' )
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* determine whether the next four characters following are */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* hexadecimal.                                             */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: Add code to deal with ligatures, i.e. glyph names like */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      `uniXXXXYYYYZZZZ'...                                   */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int       count;
61295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_UInt32    value = 0;
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  p     = glyph_name + 3;
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( count = 4; count > 0; count--, p++ )
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        char          c = *p;
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        unsigned int  d;
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        d = (unsigned char)c - '0';
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 10 )
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          d = (unsigned char)c - 'A';
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( d >= 6 )
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d = 16;
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d += 10;
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Exit if a non-uppercase hexadecimal character was found   */
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* -- this also catches character codes below `0' since such */
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* negative numbers cast to `unsigned int' are far too big.  */
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 16 )
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        value = ( value << 4 ) + d;
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* there must be exactly four hex digits */
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count == 0 )
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '\0' )
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return value;
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '.' )
96295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          return (FT_UInt32)( value | VARIANT_BIT );
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the name begins with `u', followed by four to six uppercase */
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* hexadecimal digits, it is a hard-coded unicode character code. */
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_name[0] == 'u' )
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int       count;
105295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_UInt32    value = 0;
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  p     = glyph_name + 1;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( count = 6; count > 0; count--, p++ )
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        char          c = *p;
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        unsigned int  d;
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        d = (unsigned char)c - '0';
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 10 )
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          d = (unsigned char)c - 'A';
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( d >= 6 )
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d = 16;
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            d += 10;
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( d >= 16 )
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        value = ( value << 4 ) + d;
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count <= 2 )
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '\0' )
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return value;
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '.' )
136295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          return (FT_UInt32)( value | VARIANT_BIT );
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Look for a non-initial dot in the glyph name in order to */
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* find variants like `A.swash', `e.final', etc.            */
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  p   = glyph_name;
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      const char*  dot = NULL;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; *p; p++ )
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *p == '.' && p > glyph_name )
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          dot = p;
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now look up the glyph in the Adobe Glyph List */
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !dot )
158295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
160295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
161295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                            VARIANT_BIT );
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* ft_qsort callback to sort the unicode map */
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( int )
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  compare_uni_maps( const void*  a,
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const void*  b )
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_UniMap*  map1 = (PS_UniMap*)a;
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_UniMap*  map2 = (PS_UniMap*)b;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32   unicode1 = BASE_GLYPH( map1->unicode );
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32   unicode2 = BASE_GLYPH( map2->unicode );
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* sort base glyphs before glyph variants */
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( unicode1 == unicode2 )
1790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( map1->unicode > map2->unicode )
1810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 1;
1820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else if ( map1->unicode < map2->unicode )
1830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return -1;
1840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
1850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 0;
1860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( unicode1 > unicode2 )
1900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 1;
1910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else if ( unicode1 < unicode2 )
1920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return -1;
1930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
1940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        return 0;
1950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* support for extra glyphs not handled (well) in AGL; */
2000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we add extra mappings for them if necessary         */
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define EXTRA_GLYPH_LIST_SIZE  10
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static const FT_UInt32  ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* WGL 4 */
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x0394,
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x03A9,
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x2215,
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x00AD,
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x02C9,
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x03BC,
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x2219,
2140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    0x00A0,
2150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* Romanian */
2160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    0x021A,
2170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    0x021B
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static const char  ft_extra_glyph_names[] =
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'D','e','l','t','a',0,
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'O','m','e','g','a',0,
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'f','r','a','c','t','i','o','n',0,
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'h','y','p','h','e','n',0,
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'm','a','c','r','o','n',0,
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'm','u',0,
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,
2290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    's','p','a','c','e',0,
2300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    'T','c','o','m','m','a','a','c','c','e','n','t',0,
2310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    't','c','o','m','m','a','a','c','c','e','n','t',0
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Int
2350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     0,
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     6,
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    12,
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    21,
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    28,
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    35,
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    38,
2440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    53,
2450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    59,
2460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    72
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ps_check_extra_glyph_name( const char*  gname,
2520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                             FT_UInt      glyph,
2530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                             FT_UInt*     extra_glyphs,
2540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                             FT_UInt     *states )
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  n;
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( ft_strcmp( ft_extra_glyph_names +
2620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        ft_extra_glyph_name_offsets[n], gname ) == 0 )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( states[n] == 0 )
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* mark this extra glyph as a candidate for the cmap */
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          states[n]     = 1;
2680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          extra_glyphs[n] = glyph;
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
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  static void
2780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ps_check_extra_glyph_unicode( FT_UInt32  uni_char,
2790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                FT_UInt   *states )
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  n;
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( uni_char == ft_extra_glyph_unicodes[n] )
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        /* disable this extra glyph from being added to the cmap */
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        states[n] = 2;
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
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  /* Build a table that maps Unicode values to glyph indices. */
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicodes_init( FT_Memory             memory,
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PS_Unicodes           table,
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt               num_glyphs,
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PS_GetGlyphNameFunc   get_glyph_name,
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PS_FreeGlyphNameFunc  free_glyph_name,
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Pointer            glyph_data )
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_UInt  extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_UInt  extra_glyphs[EXTRA_GLYPH_LIST_SIZE];
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we first allocate the table */
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->num_maps = 0;
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->maps     = 0;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     n;
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     count;
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PS_UniMap*  map;
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32   uni_char;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      map = table->maps;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( n = 0; n < num_glyphs; n++ )
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        const char*  gname = get_glyph_name( glyph_data, n );
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( gname )
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          ps_check_extra_glyph_name( gname, n,
3340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                     extra_glyphs, extra_glyph_list_states );
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          uni_char = ps_unicode_value( gname );
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( BASE_GLYPH( uni_char ) != 0 )
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            ps_check_extra_glyph_unicode( uni_char,
3400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                          extra_glyph_list_states );
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            map->unicode     = uni_char;
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            map->glyph_index = n;
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            map++;
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( free_glyph_name )
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            free_glyph_name( glyph_data, gname );
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( extra_glyph_list_states[n] == 1 )
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* This glyph name has an additional representation. */
3560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* Add it to the cmap.                               */
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          map->unicode     = ft_extra_glyph_unicodes[n];
3590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          map->glyph_index = extra_glyphs[n];
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          map++;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now compress the table a bit */
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = (FT_UInt)( map - table->maps );
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count == 0 )
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
369aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* No unicode chars here! */
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( table->maps );
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
372aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          error = PSnames_Err_No_Unicode_Glyph_Name;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
374aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
375aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Reallocate if the number of used entries is much smaller. */
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( count < num_glyphs / 2 )
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = PSnames_Err_Ok;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Sort the table in increasing order of unicode values, */
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* taking care of glyph variants.                        */
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_qsort( table->maps, count, sizeof ( PS_UniMap ),
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  compare_uni_maps );
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->num_maps = count;
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_UInt
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicodes_char_index( PS_Unicodes  table,
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_UInt32    unicode )
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_UniMap  *min, *max, *mid, *result = NULL;
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Perform a binary search on the table. */
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    min = table->maps;
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    max = min + table->num_maps - 1;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( min <= max )
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32  base_glyph;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mid = min + ( ( max - min ) >> 1 );
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( mid->unicode == unicode )
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = mid;
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      base_glyph = BASE_GLYPH( mid->unicode );
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( base_glyph == unicode )
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = mid; /* remember match but continue search for base glyph */
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( min == max )
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( base_glyph < unicode )
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = mid + 1;
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = mid - 1;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( result )
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return result->glyph_index;
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
442295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static FT_UInt32
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_unicodes_char_next( PS_Unicodes  table,
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_UInt32   *unicode )
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    result    = 0;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  char_code = *unicode + 1;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     min = 0;
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     max = table->num_maps;
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt     mid;
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PS_UniMap*  map;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32   base_glyph;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( min < max )
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mid = min + ( ( max - min ) >> 1 );
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map = table->maps + mid;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( map->unicode == char_code )
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = map->glyph_index;
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        base_glyph = BASE_GLYPH( map->unicode );
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( base_glyph == char_code )
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = map->glyph_index;
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( base_glyph < char_code )
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          min = mid + 1;
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          max = mid;
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( result )
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;               /* we have a variant glyph */
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we didn't find it; check whether we have a map just above it */
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_code = 0;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( min < table->num_maps )
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        map       = table->maps + min;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result    = map->glyph_index;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        char_code = BASE_GLYPH( map->unicode );
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *unicode = char_code;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const char*
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_get_macintosh_name( FT_UInt  name_index )
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( name_index >= FT_NUM_MAC_NAMES )
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      name_index = 0;
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ft_standard_glyph_names + ft_mac_names[name_index];
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const char*
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_get_standard_strings( FT_UInt  sid )
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sid >= FT_NUM_SID_NAMES )
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ft_standard_glyph_names + ft_sid_names[sid];
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
524295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface,
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicode_ValueFunc)     ps_unicode_value,
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicodes_InitFunc)     ps_unicodes_init,
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
530295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
531295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
532295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
533295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    t1_standard_encoding,
534295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    t1_expert_encoding
535295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  )
536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface,
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0,
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0,
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0,
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0,
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    t1_standard_encoding,
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    t1_expert_encoding
550295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  )
551295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
552295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
553295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
554295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
555295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_DEFINE_SERVICEDESCREC1(pscmaps_services,
556295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET
557295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  )
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
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  {
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( module );
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id );
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
574295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
575295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define PUT_PS_NAMES_SERVICE(a) 0
576295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else
577295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define PUT_PS_NAMES_SERVICE(a) a
578295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_DEFINE_MODULE(psnames_module_class,
581295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0,  /* this is not a font driver, nor a renderer */
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sizeof ( FT_ModuleRec ),
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    "psnames",  /* driver name                         */
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x10000L,   /* driver version                      */
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    0x20000L,   /* driver requires FreeType 2 or above */
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET),   /* module specific interface */
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Module_Constructor)0,
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Module_Destructor) 0,
592295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE(psnames_get_service)
593295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  )
594295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
598