blob: 9c8f9ed8eb3318db80830bf841cb58a9469a250b [file] [log] [blame]
Werner Lembergfadb6be2002-04-20 05:38:33 +00001/***************************************************************************/
2/* */
3/* pfrcmap.c */
4/* */
5/* FreeType PFR cmap handling (body). */
6/* */
Werner Lemberg86e041b2009-03-21 08:51:44 +01007/* Copyright 2002, 2007, 2009 by */
Werner Lembergfadb6be2002-04-20 05:38:33 +00008/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
10/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
12/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13/* this file you indicate that you have read the license and */
14/* understand and accept it fully. */
15/* */
16/***************************************************************************/
17
18
Werner Lemberg9b774e22007-01-16 06:11:27 +000019#include "pfrcmap.h"
David Turner609e28c2002-04-19 15:13:47 +000020#include "pfrobjs.h"
David Turner609e28c2002-04-19 15:13:47 +000021
Werner Lemberg1e1b6df2007-07-07 07:30:40 +000022#include "pfrerror.h"
23
Werner Lembergfadb6be2002-04-20 05:38:33 +000024
David Turner609e28c2002-04-19 15:13:47 +000025 FT_CALLBACK_DEF( FT_Error )
26 pfr_cmap_init( PFR_CMap cmap )
27 {
Werner Lemberga8d65492007-06-06 04:47:49 +000028 FT_Error error = PFR_Err_Ok;
29 PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap );
David Turner609e28c2002-04-19 15:13:47 +000030
31
32 cmap->num_chars = face->phy_font.num_chars;
33 cmap->chars = face->phy_font.chars;
Werner Lemberg9b774e22007-01-16 06:11:27 +000034
David Turner609e28c2002-04-19 15:13:47 +000035 /* just for safety, check that the character entries are correctly */
Werner Lembergfadb6be2002-04-20 05:38:33 +000036 /* sorted in increasing character code order */
David Turner609e28c2002-04-19 15:13:47 +000037 {
38 FT_UInt n;
Werner Lemberg9b774e22007-01-16 06:11:27 +000039
Werner Lembergfadb6be2002-04-20 05:38:33 +000040
David Turner609e28c2002-04-19 15:13:47 +000041 for ( n = 1; n < cmap->num_chars; n++ )
42 {
Werner Lembergfadb6be2002-04-20 05:38:33 +000043 if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
Werner Lemberga8d65492007-06-06 04:47:49 +000044 {
45 error = PFR_Err_Invalid_Table;
46 goto Exit;
47 }
David Turner609e28c2002-04-19 15:13:47 +000048 }
49 }
Werner Lemberg9b774e22007-01-16 06:11:27 +000050
Werner Lemberga8d65492007-06-06 04:47:49 +000051 Exit:
52 return error;
David Turner609e28c2002-04-19 15:13:47 +000053 }
54
55
56 FT_CALLBACK_DEF( void )
57 pfr_cmap_done( PFR_CMap cmap )
58 {
59 cmap->chars = NULL;
60 cmap->num_chars = 0;
61 }
62
63
64 FT_CALLBACK_DEF( FT_UInt )
65 pfr_cmap_char_index( PFR_CMap cmap,
66 FT_UInt32 char_code )
67 {
68 FT_UInt min = 0;
69 FT_UInt max = cmap->num_chars;
70 FT_UInt mid;
71 PFR_Char gchar;
72
73
74 while ( min < max )
75 {
76 mid = min + ( max - min ) / 2;
77 gchar = cmap->chars + mid;
78
79 if ( gchar->char_code == char_code )
Werner Lemberg0270c362002-06-17 08:01:32 +000080 return mid + 1;
David Turner609e28c2002-04-19 15:13:47 +000081
82 if ( gchar->char_code < char_code )
83 min = mid + 1;
84 else
85 max = mid;
86 }
87 return 0;
88 }
89
90
suzuki toshiya3f0f2e42009-08-01 00:32:09 +090091 FT_CALLBACK_DEF( FT_UInt32 )
Werner Lembergfadb6be2002-04-20 05:38:33 +000092 pfr_cmap_char_next( PFR_CMap cmap,
93 FT_UInt32 *pchar_code )
David Turner609e28c2002-04-19 15:13:47 +000094 {
95 FT_UInt result = 0;
96 FT_UInt32 char_code = *pchar_code + 1;
97
98
99 Restart:
100 {
101 FT_UInt min = 0;
102 FT_UInt max = cmap->num_chars;
103 FT_UInt mid;
104 PFR_Char gchar;
105
106
107 while ( min < max )
108 {
109 mid = min + ( ( max - min ) >> 1 );
110 gchar = cmap->chars + mid;
111
112 if ( gchar->char_code == char_code )
113 {
114 result = mid;
115 if ( result != 0 )
Werner Lemberg0270c362002-06-17 08:01:32 +0000116 {
117 result++;
David Turner609e28c2002-04-19 15:13:47 +0000118 goto Exit;
Werner Lemberg0270c362002-06-17 08:01:32 +0000119 }
David Turner609e28c2002-04-19 15:13:47 +0000120
121 char_code++;
122 goto Restart;
123 }
124
125 if ( gchar->char_code < char_code )
126 min = mid+1;
127 else
128 max = mid;
129 }
130
131 /* we didn't find it, but we have a pair just above it */
132 char_code = 0;
133
134 if ( min < cmap->num_chars )
135 {
136 gchar = cmap->chars + min;
137 result = min;
138 if ( result != 0 )
Werner Lemberg0270c362002-06-17 08:01:32 +0000139 {
140 result++;
David Turner609e28c2002-04-19 15:13:47 +0000141 char_code = gchar->char_code;
Werner Lemberg0270c362002-06-17 08:01:32 +0000142 }
David Turner609e28c2002-04-19 15:13:47 +0000143 }
144 }
145
146 Exit:
147 *pchar_code = char_code;
148 return result;
149 }
150
151
152 FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
153 pfr_cmap_class_rec =
154 {
155 sizeof ( PFR_CMapRec ),
156
Werner Lembergfadb6be2002-04-20 05:38:33 +0000157 (FT_CMap_InitFunc) pfr_cmap_init,
158 (FT_CMap_DoneFunc) pfr_cmap_done,
159 (FT_CMap_CharIndexFunc)pfr_cmap_char_index,
Werner Lemberg9a966b72007-10-15 17:21:32 +0000160 (FT_CMap_CharNextFunc) pfr_cmap_char_next,
161
162 NULL, NULL, NULL, NULL, NULL
David Turner609e28c2002-04-19 15:13:47 +0000163 };
Werner Lembergfadb6be2002-04-20 05:38:33 +0000164
165
166/* END */