psmodule.c revision 7f30c0c64c397ee76d17690dedf86dae1d7f6a1b
1a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/***************************************************************************/
2a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*                                                                         */
3a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  psmodule.c                                                             */
4a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*                                                                         */
5a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*    PSNames module implementation (body).                                */
6a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*                                                                         */
7a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by             */
8a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*                                                                         */
10a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  This file is part of the FreeType project, and may only be used,       */
11a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  modified, and distributed under the terms of the FreeType project      */
12a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  this file you indicate that you have read the license and              */
14a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*  understand and accept it fully.                                        */
15a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/*                                                                         */
16a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/***************************************************************************/
17a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
18cc069beb2d2b6b1cb9f9b9f2af2a7ea12780f634Werner Lemberg
1919ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include <ft2build.h>
2019ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include FT_INTERNAL_OBJECTS_H
217760595f84a8edc365f280a9358d4075d42d51eaDavid Turner#include FT_SERVICE_POSTSCRIPT_CMAPS_H
221f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg
238d3a401fa808a8c70bd6a9ce17d5a840fb0ae2dbDavid Turner#include "psmodule.h"
248d3a401fa808a8c70bd6a9ce17d5a840fb0ae2dbDavid Turner#include "pstables.h"
25cc069beb2d2b6b1cb9f9b9f2af2a7ea12780f634Werner Lemberg
261f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include "psnamerr.h"
271f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg
28aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
29d6752a6bfbda66cfb3040ea7c7138edc6d3e68ffWerner Lemberg#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
30aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
31a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
32aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
33a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
34a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
35607dec79bb6ad524a9d2e7f93b836b795fe234cfWerner Lemberg#define VARIANT_BIT         0x80000000UL
36adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg#define BASE_GLYPH( code )  ( (code) & ~VARIANT_BIT )
37adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
38adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
3956ef6bc4d67230aac635298006fd7a9f1096c744Werner Lemberg  /* Return the Unicode value corresponding to a given glyph.  Note that */
40a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg  /* we do deal with glyph variants by detecting a non-initial dot in    */
41adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg  /* the name, as in `A.swash' or `e.final'; in this case, the           */
42adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg  /* VARIANT_BIT is set in the return value.                             */
43a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg  /*                                                                     */
4468e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg  static FT_UInt32
45b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner  ps_unicode_value( const char*  glyph_name )
46aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
47eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg    /* If the name begins with `uni', then the glyph name may be a */
48a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg    /* hard-coded unicode character code.                          */
49aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    if ( glyph_name[0] == 'u' &&
50aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner         glyph_name[1] == 'n' &&
51aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner         glyph_name[2] == 'i' )
52aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    {
53a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg      /* determine whether the next four characters following are */
54a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg      /* hexadecimal.                                             */
55a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
56a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg      /* XXX: Add code to deal with ligatures, i.e. glyph names like */
57a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg      /*      `uniXXXXYYYYZZZZ'...                                   */
58a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
59a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg      FT_Int       count;
60a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg      FT_ULong     value = 0;
6112841de1c7b37ffb56af5a51b65cc76feb27cde6David Turner      const char*  p     = glyph_name + 3;
62a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
63aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
64a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg      for ( count = 4; count > 0; count--, p++ )
65aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      {
66c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg        char          c = *p;
67c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg        unsigned int  d;
68aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
69a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
70a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        d = (unsigned char)c - '0';
71a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        if ( d >= 10 )
72aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner        {
73aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner          d = (unsigned char)c - 'A';
74aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner          if ( d >= 6 )
75aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner            d = 16;
76aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner          else
77aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner            d += 10;
78aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner        }
79a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
80adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        /* Exit if a non-uppercase hexadecimal character was found   */
81adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        /* -- this also catches character codes below `0' since such */
82adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        /* negative numbers cast to `unsigned int' are far too big.  */
83a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        if ( d >= 16 )
84aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner          break;
85aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
86a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        value = ( value << 4 ) + d;
87aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      }
88eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
89eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      /* there must be exactly four hex digits */
90adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      if ( count == 0 )
91adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      {
92adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( *p == '\0' )
93adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          return value;
94adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( *p == '.' )
95607dec79bb6ad524a9d2e7f93b836b795fe234cfWerner Lemberg          return value | VARIANT_BIT;
96adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      }
97eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg    }
98eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
99eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg    /* If the name begins with `u', followed by four to six uppercase */
1006e87ed9f04f7914e15f9284b0b762b730222c399Werner Lemberg    /* hexadecimal digits, it is a hard-coded unicode character code. */
101eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg    if ( glyph_name[0] == 'u' )
102eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg    {
103eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      FT_Int       count;
104eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      FT_ULong     value = 0;
105eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      const char*  p     = glyph_name + 1;
106eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
107eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
108eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      for ( count = 6; count > 0; count--, p++ )
109eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      {
110eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        char          c = *p;
111eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        unsigned int  d;
112eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
113eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
114eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        d = (unsigned char)c - '0';
115eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        if ( d >= 10 )
116eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        {
117eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg          d = (unsigned char)c - 'A';
118eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg          if ( d >= 6 )
119eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg            d = 16;
120eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg          else
121eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg            d += 10;
122eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        }
123eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
124eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        if ( d >= 16 )
125eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg          break;
126eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
127eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg        value = ( value << 4 ) + d;
128eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg      }
129eb17a92a78645ca232eb2a85aded9b358a589fdcWerner Lemberg
130adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      if ( count <= 2 )
131adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      {
132adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( *p == '\0' )
133adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          return value;
134adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( *p == '.' )
135607dec79bb6ad524a9d2e7f93b836b795fe234cfWerner Lemberg          return value | VARIANT_BIT;
136adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      }
137aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    }
138aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
139adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    /* Look for a non-initial dot in the glyph name in order to */
140adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    /* find variants like `A.swash', `e.final', etc.            */
141aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    {
14212e51f16857feeae87327b5ccf0e519373f6ae59David Turner      const char*  p   = glyph_name;
14312e51f16857feeae87327b5ccf0e519373f6ae59David Turner      const char*  dot = NULL;
144a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
145a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
14612e51f16857feeae87327b5ccf0e519373f6ae59David Turner      for ( ; *p; p++ )
147aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      {
148adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( *p == '.' && p > glyph_name )
149adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        {
15012e51f16857feeae87327b5ccf0e519373f6ae59David Turner          dot = p;
151adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          break;
152adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        }
153aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      }
154aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
155adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      /* now look up the glyph in the Adobe Glyph List */
15612e51f16857feeae87327b5ccf0e519373f6ae59David Turner      if ( !dot )
157adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        return ft_get_adobe_glyph_index( glyph_name, p );
158adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      else
159607dec79bb6ad524a9d2e7f93b836b795fe234cfWerner Lemberg        return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT;
160aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    }
161aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  }
162aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
163aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
164d15bc0d13a163995e1ca11925349bd64d1c33617David Turner  /* ft_qsort callback to sort the unicode map */
16552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg  FT_CALLBACK_DEF( int )
166dee781342b932b60c0c885d4f493b8246710a34cDavid Turner  compare_uni_maps( const void*  a,
167dee781342b932b60c0c885d4f493b8246710a34cDavid Turner                    const void*  b )
168aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
169aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    PS_UniMap*  map1 = (PS_UniMap*)a;
170aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    PS_UniMap*  map2 = (PS_UniMap*)b;
171adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    FT_UInt32   unicode1 = BASE_GLYPH( map1->unicode );
172adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    FT_UInt32   unicode2 = BASE_GLYPH( map2->unicode );
173aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
174a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
175adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    /* sort base glyphs before glyph variants */
176adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    if ( unicode1 == unicode2 )
177adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      return map1->unicode - map2->unicode;
178adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    else
179adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      return unicode1 - unicode2;
180aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  }
181aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
182aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
1837f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  /* support for extra glyphs not handled (well) in AGL; */
1847f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  /* we add extra mappings for them if necessary         */
185a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
1867f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg#define EXTRA_GLYPH_LIST_SIZE  10
187a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
1887f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  static const FT_UInt32  ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =
189a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  {
1907f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    /* WGL 4 */
191a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x0394,
192a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x03A9,
193a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x2215,
194a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x00AD,
195a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x02C9,
196a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x03BC,
197a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    0x2219,
1987f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    0x00A0,
1997f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    /* Romanian */
2007f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    0x021A,
2017f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    0x021B
202a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  };
203a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
2047f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  static const char  ft_extra_glyph_names[] =
205a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  {
206a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'D','e','l','t','a',0,
207a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'O','m','e','g','a',0,
208a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'f','r','a','c','t','i','o','n',0,
209a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'h','y','p','h','e','n',0,
210a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'm','a','c','r','o','n',0,
211a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'm','u',0,
212a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,
2137f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    's','p','a','c','e',0,
2147f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    'T','c','o','m','m','a','a','c','c','e','n','t',0,
2157f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    't','c','o','m','m','a','a','c','c','e','n','t',0
216a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  };
217a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
218a92cec567c816673d1abd237c34a3a01b576b976David Turner  static const FT_Int
2197f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =
220a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  {
221a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg     0,
222a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg     6,
223a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    12,
224a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    21,
225a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    28,
226a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    35,
227a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    38,
2287f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    53,
2297f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    59,
2307f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    72
231a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  };
232a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
233a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
234a92cec567c816673d1abd237c34a3a01b576b976David Turner  static void
2357f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  ps_check_extra_glyph_name( const char*  gname,
2367f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                             FT_UInt      glyph,
2377f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                             FT_UInt*     extra_glyphs,
2387f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                             FT_UInt     *states )
239a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  {
240a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    FT_UInt  n;
241a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
242a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
2437f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
244a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    {
2457f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg      if ( ft_strcmp( ft_extra_glyph_names +
2467f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                        ft_extra_glyph_name_offsets[n], gname ) == 0 )
247a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg      {
248a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        if ( states[n] == 0 )
249a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        {
2507f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          /* mark this extra glyph as a candidate for the cmap */
251a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg          states[n]     = 1;
2527f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          extra_glyphs[n] = glyph;
253a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        }
254a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
255a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        return;
256a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg      }
257a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    }
258a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  }
259a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
260a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
261a92cec567c816673d1abd237c34a3a01b576b976David Turner  static void
2627f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg  ps_check_extra_glyph_unicode( FT_UInt32  uni_char,
2637f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                                FT_UInt   *states )
264a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  {
265a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    FT_UInt  n;
266a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
267a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
2687f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
269a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    {
2707f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg      if ( uni_char == ft_extra_glyph_unicodes[n] )
271a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg      {
2727f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg        /* disable this extra glyph from being added to the cmap */
273a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        states[n] = 2;
274a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
275a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        return;
276a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg      }
277a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg    }
278a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg  }
279a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
280a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
281adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg  /* Build a table that maps Unicode values to glyph indices. */
28252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg  static FT_Error
283457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner  ps_unicodes_init( FT_Memory             memory,
284457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner                    PS_Unicodes           table,
285457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner                    FT_UInt               num_glyphs,
286457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner                    PS_GetGlyphNameFunc   get_glyph_name,
287457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner                    PS_FreeGlyphNameFunc  free_glyph_name,
288457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner                    FT_Pointer            glyph_data )
289aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
290aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    FT_Error  error;
291aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
2927f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    FT_UInt  extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2937f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    FT_UInt  extra_glyphs[EXTRA_GLYPH_LIST_SIZE];
294a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
295a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
296aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    /* we first allocate the table */
297aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    table->num_maps = 0;
298aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    table->maps     = 0;
299aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
3007f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg    if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
301aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    {
302aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      FT_UInt     n;
303aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      FT_UInt     count;
304aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      PS_UniMap*  map;
30568e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg      FT_UInt32   uni_char;
306aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
307a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
308aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      map = table->maps;
309a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
310aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      for ( n = 0; n < num_glyphs; n++ )
311aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      {
3128ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg        const char*  gname = get_glyph_name( glyph_data, n );
313a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
314a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
315a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        if ( gname )
316aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner        {
3177f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          ps_check_extra_glyph_name( gname, n,
3187f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                                     extra_glyphs, extra_glyph_list_states );
319b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner          uni_char = ps_unicode_value( gname );
320a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
321adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          if ( BASE_GLYPH( uni_char ) != 0 )
322aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner          {
3237f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg            ps_check_extra_glyph_unicode( uni_char,
3247f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg                                          extra_glyph_list_states );
325adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg            map->unicode     = uni_char;
326aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner            map->glyph_index = n;
327aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner            map++;
328aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner          }
329457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner
330457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner          if ( free_glyph_name )
331457b4a81a190500fbbea8bc7b5750903704e715fDavid Turner            free_glyph_name( glyph_data, gname );
332aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner        }
333aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      }
334aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
3357f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg      for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
336a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg      {
3377f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg        if ( extra_glyph_list_states[n] == 1 )
338a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        {
3397f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          /* This glyph name has an additional representation. */
3407f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          /* Add it to the cmap.                               */
341a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
3427f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          map->unicode     = ft_extra_glyph_unicodes[n];
3437f30c0c64c397ee76d17690dedf86dae1d7f6a1bWerner Lemberg          map->glyph_index = extra_glyphs[n];
344a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg          map++;
345a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg        }
346a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg      }
347a2f17cc1508ddc476c21356a0b7bbee31d009d65Werner Lemberg
348adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      /* now compress the table a bit */
349914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg      count = (FT_UInt)( map - table->maps );
350a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
351a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg      if ( count == 0 )
352aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      {
353e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner        FT_FREE( table->maps );
354a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        if ( !error )
355adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          error = PSnames_Err_Invalid_Argument;  /* No unicode chars here! */
356adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      }
357adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      else {
358adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        /* Reallocate if the number of used entries is much smaller. */
359adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( count < num_glyphs / 2 )
360adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        {
361adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
362adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          error = PSnames_Err_Ok;
363adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        }
364adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
365adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        /* Sort the table in increasing order of unicode values, */
366adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        /* taking care of glyph variants.                        */
367adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        ft_qsort( table->maps, count, sizeof ( PS_UniMap ),
368adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg                  compare_uni_maps );
369aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      }
370aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
371aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      table->num_maps = count;
372aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    }
373a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
374aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    return error;
375aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  }
376aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
377a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
37852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg  static FT_UInt
3798ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg  ps_unicodes_char_index( PS_Unicodes  table,
3808ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg                          FT_UInt32    unicode )
381aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
382adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    PS_UniMap  *min, *max, *mid, *result = NULL;
383a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
384a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
385adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    /* Perform a binary search on the table. */
386a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg
387aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    min = table->maps;
388aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    max = min + table->num_maps - 1;
389aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
390a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg    while ( min <= max )
391aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    {
392adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      FT_UInt32  base_glyph;
393adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
394adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
395adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      mid = min + ( ( max - min ) >> 1 );
396adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
397aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      if ( mid->unicode == unicode )
398adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      {
399adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        result = mid;
400adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        break;
401adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      }
402adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
403adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      base_glyph = BASE_GLYPH( mid->unicode );
404adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
405adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      if ( base_glyph == unicode )
406adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        result = mid; /* remember match but continue search for base glyph */
407aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
408a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg      if ( min == max )
409aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner        break;
410aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
411adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      if ( base_glyph < unicode )
412a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        min = mid + 1;
413a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg      else
414a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg        max = mid - 1;
415aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    }
416aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
417adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    if ( result )
418adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      return result->glyph_index;
419adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    else
420adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      return 0;
421aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  }
422aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
423aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
4240f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg  static FT_ULong
4258ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg  ps_unicodes_char_next( PS_Unicodes  table,
4268ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg                         FT_UInt32   *unicode )
4270f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg  {
428adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    FT_UInt    result    = 0;
429adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    FT_UInt32  char_code = *unicode + 1;
4300f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
4310f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
432adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    {
433adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      FT_UInt     min = 0;
434adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      FT_UInt     max = table->num_maps;
435adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      FT_UInt     mid;
436adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      PS_UniMap*  map;
437adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      FT_UInt32   base_glyph;
4380f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
4390f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
440adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      while ( min < max )
441adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      {
442adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        mid = min + ( ( max - min ) >> 1 );
443adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        map = table->maps + mid;
4440f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
445adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( map->unicode == char_code )
446adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        {
447adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          result = map->glyph_index;
448adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          goto Exit;
449adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        }
4500f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
451adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        base_glyph = BASE_GLYPH( map->unicode );
4520f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
453adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( base_glyph == char_code )
454adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          result = map->glyph_index;
455b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner
456adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        if ( base_glyph < char_code )
457adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          min = mid + 1;
458adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        else
459adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg          max = mid;
460adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      }
461adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
462adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      if ( result )
463adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg        goto Exit;               /* we have a variant glyph */
464adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
465adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      /* we didn't find it; check whether we have a map just above it */
466adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      char_code = 0;
467adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg
468adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      if ( min < table->num_maps )
469adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      {
47047bf95dd705962679ba50aace24361066db777a1Werner Lemberg        map       = table->maps + min;
47147bf95dd705962679ba50aace24361066db777a1Werner Lemberg        result    = map->glyph_index;
47247bf95dd705962679ba50aace24361066db777a1Werner Lemberg        char_code = BASE_GLYPH( map->unicode );
473adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg      }
4740f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg    }
4750f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
476adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg  Exit:
477adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    *unicode = char_code;
478adf828ff953b0db3492ddf7678fdcefe34a5058bWerner Lemberg    return result;
4790f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg  }
4800f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
4810f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
482a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
483aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
484aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
48552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg  static const char*
486b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner  ps_get_macintosh_name( FT_UInt  name_index )
487aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
48812e51f16857feeae87327b5ccf0e519373f6ae59David Turner    if ( name_index >= FT_NUM_MAC_NAMES )
489aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner      name_index = 0;
490aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
49112e51f16857feeae87327b5ccf0e519373f6ae59David Turner    return ft_standard_glyph_names + ft_mac_names[name_index];
492aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  }
493aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
494aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
49552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg  static const char*
496b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner  ps_get_standard_strings( FT_UInt  sid )
497aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
49812e51f16857feeae87327b5ccf0e519373f6ae59David Turner    if ( sid >= FT_NUM_SID_NAMES )
49912e51f16857feeae87327b5ccf0e519373f6ae59David Turner      return 0;
50012e51f16857feeae87327b5ccf0e519373f6ae59David Turner
50112e51f16857feeae87327b5ccf0e519373f6ae59David Turner    return ft_standard_glyph_names + ft_sid_names[sid];
502aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  }
503aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
504aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
505ddbb8e7b6a554bc56a9c5eae88d006fedbc0fa25Werner Lemberg  static
5067760595f84a8edc365f280a9358d4075d42d51eaDavid Turner  const FT_Service_PsCMapsRec  pscmaps_interface =
507aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
508aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
509a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
510f4c0b921a18ad421a022ee7c1d2449daae502ae0Werner Lemberg    (PS_Unicode_ValueFunc)     ps_unicode_value,
511f4c0b921a18ad421a022ee7c1d2449daae502ae0Werner Lemberg    (PS_Unicodes_InitFunc)     ps_unicodes_init,
512f4c0b921a18ad421a022ee7c1d2449daae502ae0Werner Lemberg    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
513f4c0b921a18ad421a022ee7c1d2449daae502ae0Werner Lemberg    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
514a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
515aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner#else
516a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
517aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    0,
518aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    0,
519aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    0,
520b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    0,
521aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
522a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
523a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
5248ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
5258ab0979d6e2d29fe5d489d55ff4adc6a55744308Werner Lemberg    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
526aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
527aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    t1_standard_encoding,
528b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    t1_expert_encoding
529b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner  };
5300f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
5310f7c2f1aa58c2251d6c1a3f388a50bfa97cb097fWerner Lemberg
5327760595f84a8edc365f280a9358d4075d42d51eaDavid Turner  static const FT_ServiceDescRec  pscmaps_services[] =
533b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner  {
5347760595f84a8edc365f280a9358d4075d42d51eaDavid Turner    { FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface },
535b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    { NULL, NULL }
536aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  };
537aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
538f4c0b921a18ad421a022ee7c1d2449daae502ae0Werner Lemberg
539b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner  static FT_Pointer
540b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner  psnames_get_service( FT_Module    module,
541b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner                       const char*  service_id )
542b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner  {
543b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    FT_UNUSED( module );
544b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner
5457760595f84a8edc365f280a9358d4075d42d51eaDavid Turner    return ft_service_list_lookup( pscmaps_services, service_id );
546b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner  }
547aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
548d6752a6bfbda66cfb3040ea7c7138edc6d3e68ffWerner Lemberg#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
549aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
550aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
551b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner
55276a5f62323d4fe3319d3d5410ded0ff9cab1f8c5David Turner  FT_CALLBACK_TABLE_DEF
55376a5f62323d4fe3319d3d5410ded0ff9cab1f8c5David Turner  const FT_Module_Class  psnames_module_class =
554aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  {
555aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    0,  /* this is not a font driver, nor a renderer */
556c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg    sizeof ( FT_ModuleRec ),
557aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
558aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    "psnames",  /* driver name                         */
559a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg    0x10000L,   /* driver version                      */
560a8bbc267a20c62806a87c8755e2c4bf58acfc7b5Werner Lemberg    0x20000L,   /* driver requires FreeType 2 or above */
561aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
562d6752a6bfbda66cfb3040ea7c7138edc6d3e68ffWerner Lemberg#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
563aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner    0,
564b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    (FT_Module_Constructor)0,
565b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    (FT_Module_Destructor) 0,
566b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    (FT_Module_Requester)  0
567aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner#else
5687760595f84a8edc365f280a9358d4075d42d51eaDavid Turner    (void*)&pscmaps_interface,   /* module specific interface */
569a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg    (FT_Module_Constructor)0,
570a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg    (FT_Module_Destructor) 0,
571b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner    (FT_Module_Requester)  psnames_get_service
572b72d8a85212e1dc2dc103c28e19a4f4a2d71767eDavid Turner#endif
573aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner  };
574aa4c28f9fe5debca5822217eb3cf8dcebe7dd6a7David Turner
575a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg
576a929ba9b205c9756f1c0d3c261185e3bacf7fdadWerner Lemberg/* END */
577