Sun Nov 1 10:24:51 2020 UTC ()
merge font-alias 1.0.4 and fonttosfnt 1.2.0.


(mrg)
diff -r1.1.1.2 -r0 xsrc/external/mit/font-alias/dist/README
diff -r1.3 -r1.4 xsrc/external/mit/fonttosfnt/dist/struct.c

File Deleted: xsrc/external/mit/font-alias/dist/Attic/README

cvs diff -r1.3 -r1.4 xsrc/external/mit/fonttosfnt/dist/struct.c (switch to unified diff)

--- xsrc/external/mit/fonttosfnt/dist/struct.c 2018/12/30 08:51:05 1.3
+++ xsrc/external/mit/fonttosfnt/dist/struct.c 2020/11/01 10:24:51 1.4
@@ -1,514 +1,485 @@ @@ -1,514 +1,485 @@
1/* 1/*
2Copyright (c) 2002-2003 by Juliusz Chroboczek 2Copyright (c) 2002-2003 by Juliusz Chroboczek
3 3
4Permission is hereby granted, free of charge, to any person obtaining a copy 4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal 5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights 6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is 8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions: 9furnished to do so, subject to the following conditions:
10 10
11The above copyright notice and this permission notice shall be included in 11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software. 12all copies or substantial portions of the Software.
13 13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE. 20THE SOFTWARE.
21*/ 21*/
22/* $XFree86: xc/programs/fonttosfnt/struct.c,v 1.3 2003/10/24 20:38:11 tsi Exp $ */ 22/* $XFree86: xc/programs/fonttosfnt/struct.c,v 1.3 2003/10/24 20:38:11 tsi Exp $ */
23 23
24#include <stdlib.h> 24#include <stdlib.h>
25#include <stdio.h> 25#include <stdio.h>
26#include <ft2build.h> 26#include <ft2build.h>
27#include FT_FREETYPE_H 27#include FT_FREETYPE_H
28#include "fonttosfnt.h" 28#include "fonttosfnt.h"
29 29
30FontPtr 30FontPtr
31makeFont(void) 31makeFont(void)
32{ 32{
33 FontPtr font; 33 FontPtr font;
34 34
35 font = malloc(sizeof(FontRec)); 35 font = malloc(sizeof(FontRec));
36 if(font == NULL) 36 if(font == NULL)
37 return NULL; 37 return NULL;
38 38
39 font->numNames = 0; 39 font->numNames = 0;
40 font->names = NULL; 40 font->names = NULL;
41 font->flags = 0; 41 font->flags = 0;
42 font->weight = 500; 42 font->weight = 500;
43 font->width = 5; 43 font->width = 5;
44 font->italicAngle = 0; 44 font->italicAngle = 0;
45 font->underlinePosition = - TWO_SIXTEENTH; 45 font->pxMetrics.height = UNDEF;
46 font->underlineThickness = TWO_SIXTEENTH; 46 font->pxMetrics.maxX = UNDEF;
 47 font->pxMetrics.minX = UNDEF;
 48 font->pxMetrics.maxY = UNDEF;
 49 font->pxMetrics.minY = UNDEF;
 50 font->pxMetrics.xHeight = UNDEF;
 51 font->pxMetrics.capHeight = UNDEF;
 52 font->pxMetrics.maxAwidth = UNDEF;
 53 font->pxMetrics.awidth = UNDEF;
 54 font->pxMetrics.ascent = UNDEF;
 55 font->pxMetrics.descent = UNDEF;
 56 font->pxMetrics.underlinePosition = UNDEF;
 57 font->pxMetrics.underlineThickness = UNDEF;
 58 font->metrics.height = UNDEF;
 59 font->metrics.maxX = UNDEF;
 60 font->metrics.minX = UNDEF;
 61 font->metrics.maxY = UNDEF;
 62 font->metrics.minY = UNDEF;
 63 font->metrics.xHeight = UNDEF;
 64 font->metrics.capHeight = UNDEF;
 65 font->metrics.maxAwidth = UNDEF;
 66 font->metrics.awidth = UNDEF;
 67 font->metrics.ascent = UNDEF;
 68 font->metrics.descent = UNDEF;
 69 font->metrics.underlinePosition = UNDEF;
 70 font->metrics.underlineThickness = UNDEF;
47 font->foundry = makeName("UNKN"); 71 font->foundry = makeName("UNKN");
48 font->strikes = NULL; 72 font->strikes = NULL;
49 return font; 73 return font;
50} 74}
51 75
52StrikePtr 76StrikePtr
53makeStrike(FontPtr font, int sizeX, int sizeY) 77makeStrike(FontPtr font, int sizeX, int sizeY)
54{ 78{
55 StrikePtr strike, last_strike; 79 StrikePtr strike, last_strike;
56 80
57 strike = font->strikes; 81 strike = font->strikes;
58 last_strike = NULL; 82 last_strike = NULL;
59 while(strike) { 83 while(strike) {
60 if(strike->sizeX == sizeX && strike->sizeY == sizeY) 84 if(strike->sizeX == sizeX && strike->sizeY == sizeY)
61 return strike; 85 return strike;
62 last_strike = strike; 86 last_strike = strike;
63 strike = strike->next; 87 strike = strike->next;
64 } 88 }
65 89
66 strike = malloc(sizeof(StrikeRec)); 90 strike = malloc(sizeof(StrikeRec));
67 if(strike == NULL) 91 if(strike == NULL)
68 return NULL; 92 return NULL;
69 strike->sizeX = sizeX; 93 strike->sizeX = sizeX;
70 strike->sizeY = sizeY; 94 strike->sizeY = sizeY;
71 strike->bitmaps =  95 strike->bitmaps =
72 calloc(FONT_CODES / FONT_SEGMENT_SIZE, sizeof(BitmapPtr*)); 96 calloc(FONT_CODES / FONT_SEGMENT_SIZE, sizeof(BitmapPtr*));
73 if(strike->bitmaps == NULL) { 97 if(strike->bitmaps == NULL) {
74 free(strike); 98 free(strike);
75 return NULL; 99 return NULL;
76 } 100 }
77 strike->numSbits = 0; 101 strike->numSbits = 0;
78 strike->next = NULL; 102 strike->next = NULL;
79 strike->bitmapSizeTableLocation = 0xDEADFACE; 103 strike->bitmapSizeTableLocation = 0xDEADFACE;
80 strike->indexSubTables = NULL; 104 strike->indexSubTables = NULL;
81 if(last_strike) 105 if(last_strike)
82 last_strike->next = strike; 106 last_strike->next = strike;
83 else 107 else
84 font->strikes = strike; 108 font->strikes = strike;
85 return strike; 109 return strike;
86} 110}
87 111
88BitmapPtr 112BitmapPtr
89makeBitmap(StrikePtr strike, int code, 113makeBitmap(StrikePtr strike, int code,
90 int advanceWidth, int horiBearingX, int horiBearingY, 114 int advanceWidth, int horiBearingX, int horiBearingY,
91 int width, int height, int stride, unsigned char *raster, int crop) 115 int width, int height, int stride, unsigned char *raster, int crop)
92{ 116{
93 BitmapPtr bitmap; 117 BitmapPtr bitmap;
94 int i, j, x, y; 118 int i, j, x, y;
95 int dx, dy, new_width, new_height; 119 int dx, dy, new_width, new_height;
96 120
97 bitmap = malloc(sizeof(BitmapRec)); 121 bitmap = malloc(sizeof(BitmapRec));
98 if(bitmap == NULL)  122 if(bitmap == NULL)
99 return NULL; 123 return NULL;
100 124
101 bitmap->index = -1; 125 bitmap->index = -1;
102 bitmap->width = 0; 126 bitmap->width = 0;
103 bitmap->height = 0; 127 bitmap->height = 0;
104 bitmap->stride = 0; 128 bitmap->stride = 0;
105 bitmap->raster = NULL; 129 bitmap->raster = NULL;
106 bitmap->location = 0xDEADFACE; 130 bitmap->location = 0xDEADFACE;
107 131
108 i = code / FONT_SEGMENT_SIZE; 132 i = code / FONT_SEGMENT_SIZE;
109 j = code % FONT_SEGMENT_SIZE; 133 j = code % FONT_SEGMENT_SIZE;
110 134
111 if(strike->bitmaps[i] == NULL) { 135 if(strike->bitmaps[i] == NULL) {
112 strike->bitmaps[i] = calloc(FONT_SEGMENT_SIZE, sizeof(BitmapPtr)); 136 strike->bitmaps[i] = calloc(FONT_SEGMENT_SIZE, sizeof(BitmapPtr));
113 } 137 }
114 if(strike->bitmaps[i] == NULL) { 138 if(strike->bitmaps[i] == NULL) {
115 free(bitmap); 139 free(bitmap);
116 return NULL; 140 return NULL;
117 } 141 }
118 if(strike->bitmaps[i][j] != NULL) { 142 if(strike->bitmaps[i][j] != NULL) {
119 if(verbose_flag) 143 if(verbose_flag)
120 fprintf(stderr, "Duplicate bitmap %d.\n", code); 144 fprintf(stderr, "Duplicate bitmap %d.\n", code);
121 free(bitmap); 145 free(bitmap);
122 return strike->bitmaps[i][j]; 146 return strike->bitmaps[i][j];
123 } 147 }
124 148
125 dx = 0; 149 dx = 0;
126 dy = 0; 150 dy = 0;
127 new_width = width; 151 new_width = width;
128 new_height = height; 152 new_height = height;
129 153
130 if(crop) { 154 if(crop) {
131 int empty; 155 int empty;
132 while(new_width > 0) { 156 while(new_width > 0) {
133 empty = 1; 157 empty = 1;
134 x = new_width - 1; 158 x = new_width - 1;
135 for(y = 0; y < new_height; y++) { 159 for(y = 0; y < new_height; y++) {
136 if(BITREF(raster, stride, x + dx, y + dy)) { 160 if(BITREF(raster, stride, x + dx, y + dy)) {
137 empty = 0; 161 empty = 0;
138 break; 162 break;
139 } 163 }
140 } 164 }
141 if(empty) 165 if(empty)
142 new_width--; 166 new_width--;
143 else 167 else
144 break; 168 break;
145 } 169 }
146 while(new_height > 0) { 170 while(new_height > 0) {
147 empty = 1; 171 empty = 1;
148 y = new_height - 1; 172 y = new_height - 1;
149 for(x = 0; x < new_width; x++) { 173 for(x = 0; x < new_width; x++) {
150 if(BITREF(raster, stride, x + dx, y + dy)) { 174 if(BITREF(raster, stride, x + dx, y + dy)) {
151 empty = 0; 175 empty = 0;
152 break; 176 break;
153 } 177 }
154 } 178 }
155 if(empty) 179 if(empty)
156 new_height--; 180 new_height--;
157 else 181 else
158 break; 182 break;
159 } 183 }
160 while(new_width > 0) { 184 while(new_width > 0) {
161 empty = 1; 185 empty = 1;
162 x = 0; 186 x = 0;
163 for(y = 0; y < new_height; y++) { 187 for(y = 0; y < new_height; y++) {
164 if(BITREF(raster, stride, x + dx, y + dy)) { 188 if(BITREF(raster, stride, x + dx, y + dy)) {
165 empty = 0; 189 empty = 0;
166 break; 190 break;
167 } 191 }
168 } 192 }
169 if(empty) { 193 if(empty) {
170 dx++; 194 dx++;
171 new_width--; 195 new_width--;
172 } else 196 } else
173 break; 197 break;
174 } 198 }
175 while(new_height > 0) { 199 while(new_height > 0) {
176 empty = 1; 200 empty = 1;
177 y = 0; 201 y = 0;
178 for(x = 0; x < new_width; x++) { 202 for(x = 0; x < new_width; x++) {
179 if(BITREF(raster, stride, x + dx, y + dy)) { 203 if(BITREF(raster, stride, x + dx, y + dy)) {
180 empty = 0; 204 empty = 0;
181 break; 205 break;
182 } 206 }
183 } 207 }
184 if(empty) { 208 if(empty) {
185 dy++; 209 dy++;
186 new_height--; 210 new_height--;
187 } else 211 } else
188 break; 212 break;
189 } 213 }
190 } 214 }
191 215
192 216
193 bitmap->advanceWidth = advanceWidth; 217 bitmap->advanceWidth = advanceWidth;
194 bitmap->horiBearingX = horiBearingX + dx; 218 bitmap->horiBearingX = horiBearingX + dx;
195 bitmap->horiBearingY = horiBearingY - dy; 219 bitmap->horiBearingY = horiBearingY - dy;
196 bitmap->width = new_width; 220 bitmap->width = new_width;
197 bitmap->height = new_height; 221 bitmap->height = new_height;
198 bitmap->stride = (new_width + 7) / 8; 222 bitmap->stride = (new_width + 7) / 8;
199 223
200 bitmap->raster = malloc(bitmap->height * bitmap->stride); 224 bitmap->raster = malloc(bitmap->height * bitmap->stride);
201 if(bitmap->raster == NULL) { 225 if(bitmap->raster == NULL) {
202 free(bitmap); 226 free(bitmap);
203 return NULL; 227 return NULL;
204 } 228 }
205 memset(bitmap->raster, 0, bitmap->height * bitmap->stride); 229 memset(bitmap->raster, 0, bitmap->height * bitmap->stride);
206 for(y = 0; y < new_height; y++) { 230 for(y = 0; y < new_height; y++) {
207 for(x = 0; x < new_width; x++) { 231 for(x = 0; x < new_width; x++) {
208 if(BITREF(raster, stride, x + dx, y + dy)) 232 if(BITREF(raster, stride, x + dx, y + dy))
209 bitmap->raster[y * bitmap->stride + x / 8] |= 233 bitmap->raster[y * bitmap->stride + x / 8] |=
210 1 << (7 - (x % 8)); 234 1 << (7 - (x % 8));
211 } 235 }
212 } 236 }
213 strike->bitmaps[i][j] = bitmap; 237 strike->bitmaps[i][j] = bitmap;
214 strike->numSbits++; 238 strike->numSbits++;
215 239
216 return bitmap; 240 return bitmap;
217} 241}
218 242
219IndexSubTablePtr 243IndexSubTablePtr
220makeIndexSubTables(StrikePtr strike, CmapPtr cmap) 244makeIndexSubTables(StrikePtr strike, CmapPtr cmap)
221{ 245{
222 IndexSubTablePtr table, first, last; 246 IndexSubTablePtr table, first, last;
223 BitmapPtr bitmap0, bitmap; 247 BitmapPtr bitmap0, bitmap;
224 int index, n; 248 int index, n;
225 249
226 first = NULL; 250 first = NULL;
227 last = NULL; 251 last = NULL;
228 252
229 /* Assuming that we're writing bit-aligned data, small metrics 253 /* Assuming that we're writing bit-aligned data, small metrics
230 and short offsets, a constant metrics segment saves 5 bytes  254 and short offsets, a constant metrics segment saves 5 bytes
231 per glyph in the EBDT table, and 2 bytes per glyph in the EBLC 255 per glyph in the EBDT table, and 2 bytes per glyph in the EBLC
232 table. On the other hand, the overhead for a supplementary 256 table. On the other hand, the overhead for a supplementary
233 type 2 indexSubTable is 8 bytes for the indexSubTableArray 257 type 2 indexSubTable is 8 bytes for the indexSubTableArray
234 entry and 20 bytes for the subtable itself. It's worth 258 entry and 20 bytes for the subtable itself. It's worth
235 splitting at 5 glyphs. There's no analogue of a type 2 259 splitting at 5 glyphs. There's no analogue of a type 2
236 indexSubTable with byte-aligned data, so we don't bother 260 indexSubTable with byte-aligned data, so we don't bother
237 splitting when byte-aligning. */ 261 splitting when byte-aligning. */
238 index = 0; 262 index = 0;
239 while(index < 0xFFFF) { 263 while(index < 0xFFFF) {
240 int constantMetrics = 1; 264 int constantMetrics = 1;
241 bitmap0 = strikeBitmapIndex(strike, cmap, index); 265 bitmap0 = strikeBitmapIndex(strike, cmap, index);
242 if(bitmap0 == NULL) { 266 if(bitmap0 == NULL) {
243 index++; 267 index++;
244 continue; 268 continue;
245 } 269 }
246 n = 1; 270 n = 1;
247 while((bitmap = strikeBitmapIndex(strike, cmap, index + n)) != NULL) { 271 while((bitmap = strikeBitmapIndex(strike, cmap, index + n)) != NULL) {
248 if(constantMetrics) { 272 if(constantMetrics) {
249 if(!SAME_METRICS(bitmap0, bitmap)) { 273 if(!SAME_METRICS(bitmap0, bitmap)) {
250 if(bit_aligned_flag && n >= 4) 274 if(bit_aligned_flag && n >= 4)
251 break; 275 break;
252 else 276 else
253 constantMetrics = 0; 277 constantMetrics = 0;
254 } 278 }
255 } else if(bit_aligned_flag) { 279 } else if(bit_aligned_flag) {
256 BitmapPtr b1 = strikeBitmapIndex(strike, cmap, index + n + 1); 280 BitmapPtr b1 = strikeBitmapIndex(strike, cmap, index + n + 1);
257 BitmapPtr b2 = strikeBitmapIndex(strike, cmap, index + n + 2); 281 BitmapPtr b2 = strikeBitmapIndex(strike, cmap, index + n + 2);
258 BitmapPtr b3 = strikeBitmapIndex(strike, cmap, index + n + 3); 282 BitmapPtr b3 = strikeBitmapIndex(strike, cmap, index + n + 3);
259 BitmapPtr b4 = strikeBitmapIndex(strike, cmap, index + n + 4); 283 BitmapPtr b4 = strikeBitmapIndex(strike, cmap, index + n + 4);
260 if(b1 && b2 && b3 && b4 && 284 if(b1 && b2 && b3 && b4 &&
261 SAME_METRICS(bitmap, b1) &&  285 SAME_METRICS(bitmap, b1) &&
262 SAME_METRICS(bitmap, b2) &&  286 SAME_METRICS(bitmap, b2) &&
263 SAME_METRICS(bitmap, b3) &&  287 SAME_METRICS(bitmap, b3) &&
264 SAME_METRICS(bitmap, b4)) { 288 SAME_METRICS(bitmap, b4)) {
265 break; 289 break;
266 } 290 }
267 } 291 }
268 n++; 292 n++;
269 } 293 }
270 if(n <= 1) 294 if(n <= 1)
271 constantMetrics = 0; 295 constantMetrics = 0;
272 296
273 table = malloc(sizeof(IndexSubTableRec)); 297 table = malloc(sizeof(IndexSubTableRec));
274 table->firstGlyphIndex = index; 298 table->firstGlyphIndex = index;
275 table->lastGlyphIndex = index + n - 1; 299 table->lastGlyphIndex = index + n - 1;
276 table->constantMetrics = constantMetrics; 300 table->constantMetrics = constantMetrics;
277 table->location = 0xDEADFACE; 301 table->location = 0xDEADFACE;
278 table->lastLocation = 0xDEADFACE; 302 table->lastLocation = 0xDEADFACE;
279 table->next = NULL; 303 table->next = NULL;
280 304
281 if(first == NULL) { 305 if(first == NULL) {
282 first = table; 306 first = table;
283 last = table; 307 last = table;
284 } else { 308 } else {
285 last->next = table; 309 last->next = table;
286 last = table; 310 last = table;
287 } 311 }
288 index += n; 312 index += n;
289 } 313 }
290 return first; 314 return first;
291} 315}
292 316
293int 317int
294fontIndex(FontPtr font, int code) 318fontIndex(FontPtr font, int code)
295{ 319{
296 StrikePtr strike; 320 StrikePtr strike;
297 BitmapPtr bitmap; 321 BitmapPtr bitmap;
298 322
299 if(code == 0) 323 if(code == 0)
300 return 0; 324 return 0;
301 strike = font->strikes; 325 strike = font->strikes;
302 while(strike) { 326 while(strike) {
303 bitmap = STRIKE_BITMAP(strike, code); 327 bitmap = STRIKE_BITMAP(strike, code);
304 if(bitmap) 328 if(bitmap)
305 return bitmap->index; 329 return bitmap->index;
306 strike = strike->next; 330 strike = strike->next;
307 } 331 }
308 return -1; 332 return -1;
309} 333}
310 334
311CmapPtr 335CmapPtr
312makeCmap(FontPtr font) 336makeCmap(FontPtr font)
313{ 337{
314 CmapPtr cmap_head = NULL; 338 CmapPtr cmap_head = NULL;
315 CmapPtr cmap_last = NULL; 339 CmapPtr cmap_last = NULL;
316 CmapPtr cmap; 340 CmapPtr cmap;
317 int code, i, index, maxindex = 0; 341 int code, i, index, maxindex = 0;
318 342
319 code = 0; 343 code = 0;
320 while(code < FONT_CODES) { 344 while(code < FONT_CODES) {
321 index = fontIndex(font, code); 345 index = fontIndex(font, code);
322 if(index < 0) { 346 if(index < 0) {
323 code++; 347 code++;
324 continue; 348 continue;
325 } 349 }
326 i = 1; 350 i = 1;
327 while(code + i < FONT_CODES &&  351 while(code + i < FONT_CODES &&
328 fontIndex(font, code + i) == index + i) { 352 fontIndex(font, code + i) == index + i) {
329 i++; 353 i++;
330 } 354 }
331 cmap = malloc(sizeof(CmapRec)); 355 cmap = malloc(sizeof(CmapRec));
332 if(cmap == NULL) 356 if(cmap == NULL)
333 return NULL; 357 return NULL;
334 cmap->startCode = code; 358 cmap->startCode = code;
335 cmap->endCode = code + i - 1; 359 cmap->endCode = code + i - 1;
336 cmap->index = index; 360 cmap->index = index;
337 cmap->next = NULL; 361 cmap->next = NULL;
338 cmap->maxindex = 0; 362 cmap->maxindex = 0;
339 if(maxindex < index + i - 1) 363 if(maxindex < index + i - 1)
340 maxindex = index + i - 1; 364 maxindex = index + i - 1;
341 if(cmap_head == NULL) 365 if(cmap_head == NULL)
342 cmap_head = cmap; 366 cmap_head = cmap;
343 else 367 else
344 cmap_last->next = cmap; 368 cmap_last->next = cmap;
345 cmap_last = cmap; 369 cmap_last = cmap;
346 370
347 code += i; 371 code += i;
348 } 372 }
349 cmap_head->maxindex = maxindex; 373 cmap_head->maxindex = maxindex;
350 cmap_head->inverse = calloc(maxindex + 1, sizeof(int)); 374 cmap_head->inverse = calloc(maxindex + 1, sizeof(int));
351 cmap = cmap_head; 375 cmap = cmap_head;
352 while(cmap) { 376 while(cmap) {
353 for(i = cmap->index;  377 for(i = cmap->index;
354 i <= cmap->endCode - cmap->startCode + cmap->index; i++) { 378 i <= cmap->endCode - cmap->startCode + cmap->index; i++) {
355 cmap_head->inverse[i] = 379 cmap_head->inverse[i] =
356 i - cmap->index + cmap->startCode; 380 i - cmap->index + cmap->startCode;
357 } 381 }
358 cmap = cmap->next; 382 cmap = cmap->next;
359 } 383 }
360 384
361 return cmap_head; 385 return cmap_head;
362} 386}
363 387
364int 388int
365findIndex(CmapPtr cmap_head, int code) 389findIndex(CmapPtr cmap_head, int code)
366{ 390{
367 CmapPtr cmap; 391 CmapPtr cmap;
368 cmap = cmap_head; 392 cmap = cmap_head;
369 while(cmap) { 393 while(cmap) {
370 if(cmap->endCode > code) 394 if(cmap->endCode > code)
371 return -1; 395 return -1;
372 if(cmap->startCode <= code) 396 if(cmap->startCode <= code)
373 return cmap->index + code - cmap->startCode; 397 return cmap->index + code - cmap->startCode;
374 cmap = cmap->next; 398 cmap = cmap->next;
375 } 399 }
376 return -1; 400 return -1;
377} 401}
378 402
379int 403int
380findCode(CmapPtr cmap_head, int index) 404findCode(CmapPtr cmap_head, int index)
381{ 405{
382 if(index < 0 || index > cmap_head->maxindex) 406 if(index < 0 || index > cmap_head->maxindex)
383 return -1; 407 return -1;
384 return cmap_head->inverse[index]; 408 return cmap_head->inverse[index];
385 409
386} 410}
387 411
388int 412int
389maxIndex(CmapPtr cmap_head) 413maxIndex(CmapPtr cmap_head)
390{ 414{
391 return cmap_head->maxindex; 415 return cmap_head->maxindex;
392} 416}
393 417
394BitmapPtr 418BitmapPtr
395strikeBitmapIndex(StrikePtr strike, CmapPtr cmap, int index) 419strikeBitmapIndex(StrikePtr strike, CmapPtr cmap, int index)
396{ 420{
397 int code = findCode(cmap, index); 421 int code = findCode(cmap, index);
398 if(code < 0) 422 if(code < 0)
399 return NULL; 423 return NULL;
400 424
401 return STRIKE_BITMAP(strike, code); 425 return STRIKE_BITMAP(strike, code);
402} 426}
403 427
404void 428int
405strikeMetrics(StrikePtr strike, 429strikeMaxWidth(StrikePtr strike)
406 int *width_max_return,  
407 int *x_min_return, int *y_min_return, 
408 int *x_max_return, int *y_max_return) 
409{ 430{
410 BitmapPtr bitmap; 431 BitmapPtr bitmap;
411 int i; 432 int i;
412 int width_max = 0; 433 int width_max = 0;
413 int x_min = 10000; 
414 int y_min = 10000; 
415 int x_max = -10000; 
416 int y_max = -10000; 
417 434
418 for(i = 0; i < FONT_CODES; i++) { 435 for(i = 0; i < FONT_CODES; i++) {
419 bitmap = STRIKE_BITMAP(strike, i); 436 bitmap = STRIKE_BITMAP(strike, i);
420 if(!bitmap) 437 if(!bitmap)
421 continue; 438 continue;
422 if(bitmap->advanceWidth > width_max) 439 if(bitmap->advanceWidth > width_max)
423 width_max = bitmap->advanceWidth; 440 width_max = bitmap->advanceWidth;
424 if(bitmap->horiBearingX < x_min) 
425 x_min = bitmap->horiBearingX; 
426 if(bitmap->horiBearingY > y_max) 
427 y_max = bitmap->horiBearingY; 
428 if(bitmap->horiBearingX + bitmap->width > x_max) 
429 x_max = bitmap->horiBearingX + bitmap->width; 
430 if(bitmap->horiBearingY - bitmap->height < y_min) 
431 y_min = bitmap->horiBearingY - bitmap->height; 
432 } 441 }
433 442
434 if(width_max_return) *width_max_return = width_max; 443 return width_max;
435 if(x_min_return) *x_min_return = x_min; 
436 if(y_min_return) *y_min_return = y_min; 
437 if(x_max_return) *x_max_return = x_max; 
438 if(y_max_return) *y_max_return = y_max; 
439} 444}
440 445
441int 446int
442glyphMetrics(FontPtr font, int code, 447glyphMetrics(FontPtr font, int code,
443 int *width_return, 448 int *width_return,
444 int *x_min_return, int *y_min_return, 449 int *x_min_return, int *y_min_return,
445 int *x_max_return, int *y_max_return) 450 int *x_max_return, int *y_max_return)
446{ 451{
447 StrikePtr strike; 452 StrikePtr strike;
448 BitmapPtr bitmap; 453 BitmapPtr bitmap;
449 454
450 strike = font->strikes; 455 strike = font->strikes;
451 while(strike) { 456 while(strike) {
452 bitmap = STRIKE_BITMAP(strike, code); 457 bitmap = STRIKE_BITMAP(strike, code);
453 if(bitmap) { 458 if(bitmap) {
454 if(width_return) 459 if(width_return)
455 *width_return =  460 *width_return =
456 (((float)bitmap->advanceWidth + 0.5) / strike->sizeX) * 461 (((float)bitmap->advanceWidth) / strike->sizeX) *
457 TWO_SIXTEENTH; 462 TWO_SIXTEENTH;
458 if(x_min_return) 463 if(x_min_return)
459 *x_min_return = 464 *x_min_return =
460 ((float)bitmap->horiBearingX / strike->sizeX) *  465 ((float)bitmap->horiBearingX / strike->sizeX) *
461 TWO_SIXTEENTH; 466 TWO_SIXTEENTH;
462 if(y_min_return) 467 if(y_min_return)
463 *y_min_return = 468 *y_min_return =
464 (((float)bitmap->horiBearingY - bitmap->height)  469 (((float)bitmap->horiBearingY - bitmap->height)
465 / strike->sizeY) * TWO_SIXTEENTH; 470 / strike->sizeY) * TWO_SIXTEENTH;
466 /* For the following two, 0.9 instead of 0.5 might make 
467 more sense. However, using different rounding rules 
468 for x_max and awidth causes problems for detecting 
469 charcell fonts. */ 
470 if(x_max_return) 471 if(x_max_return)
471 *x_max_return = 472 *x_max_return =
472 (((float)bitmap->horiBearingX + bitmap->width + 0.5) 473 (((float)bitmap->horiBearingX + bitmap->width)
473 / strike->sizeX) * TWO_SIXTEENTH; 474 / strike->sizeX) * TWO_SIXTEENTH;
474 if(y_max_return) 475 if(y_max_return)
475 *y_max_return = 476 *y_max_return =
476 (((float)bitmap->horiBearingY + 0.5) / strike->sizeY) * 477 (((float)bitmap->horiBearingY) / strike->sizeY) *
477 TWO_SIXTEENTH; 478 TWO_SIXTEENTH;
478 return 1; 479 return 1;
479 } 480 }
480 strike = strike->next; 481 strike = strike->next;
481 } 482 }
482 483
483 return -1; 484 return -1;
484} 485}
485 
486void 
487fontMetrics(FontPtr font, 
488 int *max_awidth_return, 
489 int *min_x_return, int *min_y_return, 
490 int *max_x_return, int *max_y_return) 
491{ 
492 int i, rc; 
493 int max_awidth = 0; 
494 int min_x = 10000 * 65536, min_y = 10000 * 65536; 
495 int max_x = -10000 * 65536, max_y = -10000 * 65536; 
496 for(i = 0; i < FONT_CODES; i++) { 
497 int awidth, x0, y0, x1, y1; 
498 rc = glyphMetrics(font, i, &awidth, &x0, &y0, &x1, &y1); 
499 if(rc < 0) 
500 continue; 
501 if(awidth > max_awidth) 
502 max_awidth = awidth; 
503 if(x0 < min_x) min_x = x0; 
504 if(y0 < min_y) min_y = y0; 
505 if(x1 > max_x) max_x = x1; 
506 if(y1 > max_y) max_y = y1; 
507 } 
508 if(max_awidth_return) *max_awidth_return = max_awidth; 
509 if(min_x_return) *min_x_return = min_x; 
510 if(min_y_return) *min_y_return = min_y; 
511 if(max_x_return) *max_x_return = max_x; 
512 if(max_y_return) *max_y_return = max_y; 
513} 
514