Bug Summary

File:FreeType/ftfuncs.c
Location:line 625, column 33
Description:Result of 'calloc' is converted to a pointer of type 'int', which is incompatible with sizeof operand type 'int *'

Annotated Source Code

1/*
2Copyright (c) 1997 by Mark Leisher
3Copyright (c) 1998-2003 by Juliusz Chroboczek
4Copyright (c) 1998 Go Watanabe, All rights reserved.
5Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
6Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
7Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
8Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in
18all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26THE SOFTWARE.
27*/
28
29#ifdef HAVE_CONFIG_H1
30#include <config.h>
31#endif
32#include <X11/fonts/fontmisc.h>
33
34#include <string.h>
35#include <math.h>
36#include <ctype.h>
37
38#include <X11/fonts/fntfilst.h>
39#include <X11/fonts/fontutil.h>
40#include <X11/fonts/FSproto.h>
41#include <ft2build.h>
42#include FT_FREETYPE_H<freetype/freetype.h>
43#include FT_SIZES_H<freetype/ftsizes.h>
44#include FT_TRUETYPE_IDS_H<freetype/ttnameid.h>
45#include FT_TRUETYPE_TABLES_H<freetype/tttables.h>
46#include FT_TYPE1_TABLES_H<freetype/t1tables.h>
47#include FT_XFREE86_H<freetype/ftxf86.h>
48#include FT_BBOX_H<freetype/ftbbox.h>
49#include FT_TRUETYPE_TAGS_H<freetype/tttags.h>
50/*
51 * If you want to use FT_Outline_Get_CBox instead of
52 * FT_Outline_Get_BBox, define here.
53 */
54/* #define USE_GET_CBOX */
55#ifdef USE_GET_CBOX
56#include FT_OUTLINE_H<freetype/ftoutln.h>
57#endif
58
59#include <X11/fonts/fontenc.h>
60#include "ft.h"
61#include "ftfuncs.h"
62#include "xttcap.h"
63
64/* Work around FreeType bug */
65#define WORK_AROUND_UPM2048 2048
66
67#ifndef True(-1)
68#define True(-1) (-1)
69#endif /* True */
70#ifndef False(0)
71#define False(0) (0)
72#endif /* False */
73
74#define FLOOR64(x)((x) & -64) ((x) & -64)
75#define CEIL64(x)(((x) + 64 - 1) & -64) (((x) + 64 - 1) & -64)
76
77/*
78 * If you want very lazy method(vl=y) AS DEFAULT when
79 * handling large charset, define here.
80 */
81/* #define DEFAULT_VERY_LAZY 1 */ /* Always */
82#define DEFAULT_VERY_LAZY2 2 /* Multi-byte only */
83/* #define DEFAULT_VERY_LAZY 256 */ /* Unicode only */
84
85/* Does the X accept noSuchChar? */
86#define X_ACCEPTS_NO_SUCH_CHAR
87/* Does the XAA accept NULL noSuchChar.bits?(dangerous) */
88/* #define XAA_ACCEPTS_NULL_BITS */
89
90#ifdef X_ACCEPTS_NO_SUCH_CHAR
91static CharInfoRec noSuchChar = { /* metrics */{0,0,0,0,0,0},
92 /* bits */ NULL((void*)0) };
93#endif
94
95/* The propery names for all the XLFD properties. */
96
97static const char *xlfd_props[] = {
98 "FOUNDRY",
99 "FAMILY_NAME",
100 "WEIGHT_NAME",
101 "SLANT",
102 "SETWIDTH_NAME",
103 "ADD_STYLE_NAME",
104 "PIXEL_SIZE",
105 "POINT_SIZE",
106 "RESOLUTION_X",
107 "RESOLUTION_Y",
108 "SPACING",
109 "AVERAGE_WIDTH",
110 "CHARSET_REGISTRY",
111 "CHARSET_ENCODING",
112};
113
114
115/* read 2-byte value from a SFNT table */
116static FT_UShort
117sfnt_get_ushort( FT_Face face,
118 FT_ULong table_tag,
119 FT_ULong table_offset )
120{
121 FT_Byte buff[2];
122 FT_ULong len = sizeof(buff);
123 FT_UShort result = 0;
124
125 if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) )
126 result = (FT_UShort)( (buff[0] << 8) | buff[1] );
127
128 return result;
129}
130
131#define sfnt_get_short(f,t,o)((FT_Short)sfnt_get_ushort((f),(t),(o))) ((FT_Short)sfnt_get_ushort((f),(t),(o)))
132
133
134static int ftypeInitP = 0; /* is the engine initialised? */
135FT_Library ftypeLibrary;
136
137static FTFacePtr faceTable[NUMFACEBUCKETS32];
138
139static unsigned
140hash(char *string)
141{
142 int i;
143 unsigned u = 0;
144 for(i = 0; string[i] != '\0'; i++)
145 u = (u<<5) + (u >> (NUMFACEBUCKETS32 - 5)) + (unsigned char)string[i];
146 return u;
147}
148
149static int
150ifloor(int x, int y)
151{
152 if(x >= 0)
153 return x/y;
154 else
155 return x/y - 1;
156}
157
158static int
159iceil(int x, int y)
160{
161 return ifloor(x + y - 1, y);
162}
163
164static int
165FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber)
166{
167 FT_Error ftrc;
168 int bucket;
169 FTFacePtr face, otherFace;
170
171 if (!ftypeInitP) {
172 ftrc = FT_Init_FreeType(&ftypeLibrary);
173 if (ftrc != 0) {
174 ErrorF("FreeType: error initializing ftypeEngine: %d\n", ftrc);
175 return AllocError80;
176 }
177 ftypeInitP = 1;
178 }
179
180 /* Try to find a matching face in the hashtable */
181 bucket = hash(FTFileName)%NUMFACEBUCKETS32;
182 otherFace = faceTable[bucket];
183 while(otherFace) {
184 if( strcmp(otherFace->filename, FTFileName) == 0 ) break;
185 otherFace = otherFace->next;
186 }
187 if(otherFace) {
188 MUMBLE("Returning cached face: %s\n", otherFace->filename);
189 *facep = otherFace;
190 return Successful85;
191 }
192
193 /* No cached match; need to make a new one */
194 face = calloc(1, sizeof(FTFaceRec));
195 if (face == NULL((void*)0)) {
196 return AllocError80;
197 }
198
199 face->filename = strdup(FTFileName);
200 if (face->filename == NULL((void*)0)) {
201 free(face);
202 return AllocError80;
203 }
204
205 ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face);
206 if(ftrc != 0) {
207 ErrorF("FreeType: couldn't open face %s: %d\n", FTFileName, ftrc);
208 free(face->filename);
209 free(face);
210 return BadFontName83;
211 }
212
213 face->bitmap = ((face->face->face_flags & FT_FACE_FLAG_SCALABLE( 1L << 0 )) == 0);
214 if(!face->bitmap) {
215 TT_MaxProfile *maxp;
216 maxp = FT_Get_Sfnt_Table(face->face, ft_sfnt_maxp);
217 if(maxp && maxp->maxContours == 0)
218 face->bitmap = 1;
219 }
220
221 face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face,
222 TTAG_hhea(FT_Tag) ( ( (FT_ULong)'h' << 24 ) | ( (FT_ULong)'h' <<
16 ) | ( (FT_ULong)'e' << 8 ) | (FT_ULong)'a' )
, 34 );
223
224 /* Insert face in hashtable and return it */
225 face->next = faceTable[bucket];
226 faceTable[bucket] = face;
227 *facep = face;
228 return Successful85;
229}
230
231static void
232FreeTypeFreeFace(FTFacePtr face)
233{
234 int bucket;
235 FTFacePtr otherFace;
236
237 if(!face->instances) {
238 bucket = hash(face->filename) % NUMFACEBUCKETS32;
239 if(faceTable[bucket] == face)
240 faceTable[bucket] = face->next;
241 else {
242 otherFace = faceTable[bucket];
243 while(otherFace) {
244 if(otherFace->next == face)
245 break;
246 otherFace = otherFace->next;
247 }
248 if(otherFace && otherFace->next)
249 otherFace->next = otherFace->next->next;
250 else
251 ErrorF("FreeType: freeing unknown face\n");
252 }
253 MUMBLE("Closing face: %s\n", face->filename);
254 FT_Done_Face(face->face);
255 free(face->filename);
256 free(face);
257 }
258}
259
260static int
261TransEqual(FTNormalisedTransformationPtr t1, FTNormalisedTransformationPtr t2)
262{
263 if(t1->scale != t2->scale)
264 return 0;
265 else if(t1->xres != t2->xres || t1->yres != t2->yres)
266 return 0;
267 else if(t1->nonIdentity != t2->nonIdentity)
268 return 0;
269 else if(t1->nonIdentity && t2->nonIdentity) {
270 return
271 t1->matrix.xx == t2->matrix.xx &&
272 t1->matrix.yx == t2->matrix.yx &&
273 t1->matrix.yy == t2->matrix.yy &&
274 t1->matrix.xy == t2->matrix.xy;
275 } else
276 return 1;
277}
278
279static int
280BitmapFormatEqual(FontBitmapFormatPtr f1, FontBitmapFormatPtr f2)
281{
282 return
283 f1->bit == f2->bit &&
284 f1->byte == f2->byte &&
285 f1->glyph == f2->glyph;
286}
287
288static int
289TTCapEqual(struct TTCapInfo *t1, struct TTCapInfo *t2)
290{
291 return
292 t1->autoItalic == t2->autoItalic &&
293 t1->scaleWidth == t2->scaleWidth &&
294 t1->scaleBBoxWidth == t2->scaleBBoxWidth &&
295 t1->scaleBBoxHeight == t2->scaleBBoxHeight &&
296 t1->doubleStrikeShift == t2->doubleStrikeShift &&
297 t1->adjustBBoxWidthByPixel == t2->adjustBBoxWidthByPixel &&
298 t1->adjustLeftSideBearingByPixel == t2->adjustLeftSideBearingByPixel &&
299 t1->adjustRightSideBearingByPixel == t2->adjustRightSideBearingByPixel &&
300 t1->flags == t2->flags &&
301 t1->scaleBitmap == t2->scaleBitmap &&
302 /*
303 If we use forceConstantSpacing,
304 we *MUST* allocate new instance.
305 */
306 t1->forceConstantSpacingEnd < 0 &&
307 t2->forceConstantSpacingEnd < 0;
308}
309
310static int
311FTInstanceMatch(FTInstancePtr instance,
312 char *FTFileName, FTNormalisedTransformationPtr trans,
313 int spacing, FontBitmapFormatPtr bmfmt,
314 struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
315{
316 if(strcmp(instance->face->filename, FTFileName) != 0) {
317 return 0;
318 } else if(!TransEqual(&instance->transformation, trans)) {
319 return 0;
320 } else if( spacing != instance->spacing ) {
321 return 0;
322 } else if( load_flags != instance->load_flags ) {
323 return 0;
324 } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) {
325 return 0;
326 } else if(!TTCapEqual(&instance->ttcap, tmp_ttcap)) {
327 return 0;
328 } else {
329 return 1;
330 }
331}
332
333static int
334FreeTypeActivateInstance(FTInstancePtr instance)
335{
336 FT_Error ftrc;
337 if(instance->face->active_instance == instance)
338 return Successful85;
339
340 ftrc = FT_Activate_Size(instance->size);
341 if(ftrc != 0) {
342 instance->face->active_instance = NULL((void*)0);
343 ErrorF("FreeType: couldn't activate instance: %d\n", ftrc);
344 return FTtoXReturnCode(ftrc);
345 }
346 FT_Set_Transform(instance->face->face,
347 instance->transformation.nonIdentity ?
348 &instance->transformation.matrix : 0,
349 0);
350
351 instance->face->active_instance = instance;
352 return Successful85;
353}
354
355static int
356FTFindSize(FT_Face face, FTNormalisedTransformationPtr trans,
357 int *x_return, int *y_return)
358{
359 int tx, ty, x, y;
360 int i, j;
361 int d, dd;
362
363 if(trans->nonIdentity)
364 return BadFontName83;
365
366 tx = (int)(trans->scale * trans->xres / 72.0 + 0.5);
367 ty = (int)(trans->scale * trans->yres / 72.0 + 0.5);
368
369 d = 100;
370 j = -1;
371 for(i = 0; i < face->num_fixed_sizes; i++) {
372 x = face->available_sizes[i].width;
373 y = face->available_sizes[i].height;
374 if(ABS(x - tx)((x - tx) >= 0 ? (x - tx) : -(x - tx)) <= 1 && ABS(y - ty)((y - ty) >= 0 ? (y - ty) : -(y - ty)) <= 1) {
375 dd = ABS(x - tx)((x - tx) >= 0 ? (x - tx) : -(x - tx)) * ABS(x - tx)((x - tx) >= 0 ? (x - tx) : -(x - tx)) + ABS(y - ty)((y - ty) >= 0 ? (y - ty) : -(y - ty)) * ABS(y - ty)((y - ty) >= 0 ? (y - ty) : -(y - ty));
376 if(dd < d) {
377 j = i;
378 d = dd;
379 }
380 }
381 }
382 if(j < 0)
383 return BadFontName83;
384
385 *x_return = face->available_sizes[j].width;
386 *y_return = face->available_sizes[j].height;
387 return Successful85;
388}
389
390static int
391FreeTypeOpenInstance(FTInstancePtr *instance_return, FTFacePtr face,
392 char *FTFileName, FTNormalisedTransformationPtr trans,
393 int spacing, FontBitmapFormatPtr bmfmt,
394 struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
395{
396 FT_Error ftrc;
397 int xrc;
398 FTInstancePtr instance, otherInstance;
399
400 /* Search for a matching instance */
401 for(otherInstance = face->instances;
402 otherInstance;
403 otherInstance = otherInstance->next) {
404 if(FTInstanceMatch(otherInstance, FTFileName, trans, spacing, bmfmt,
405 tmp_ttcap, load_flags)) break;
406 }
407 if(otherInstance) {
408 MUMBLE("Returning cached instance\n");
409 otherInstance->refcount++;
410 *instance_return = otherInstance;
411 return Successful85;
412 }
413
414 /* None matching found */
415 instance = malloc(sizeof(FTInstanceRec));
416 if(instance == NULL((void*)0)) {
417 return AllocError80;
418 }
419
420 instance->refcount = 1;
421 instance->face = face;
422
423 instance->load_flags = load_flags;
424 instance->spacing = spacing; /* Actual spacing */
425 instance->pixel_size =0;
426 instance->pixel_width_unit_x =0;
427 instance->pixel_width_unit_y =0;
428 instance->charcellMetrics = NULL((void*)0);
429 instance->averageWidth = 0;
430 instance->rawAverageWidth = 0;
431 instance->forceConstantMetrics = NULL((void*)0);
432
433 instance->transformation = *trans;
434 instance->bmfmt = *bmfmt;
435 instance->glyphs = NULL((void*)0);
436 instance->available = NULL((void*)0);
437
438 if( 0 <= tmp_ttcap->forceConstantSpacingEnd )
439 instance->nglyphs = 2 * instance->face->face->num_glyphs;
440 else
441 instance->nglyphs = instance->face->face->num_glyphs;
442
443 /* Store the TTCap info. */
444 memcpy((char*)&instance->ttcap, (char*)tmp_ttcap,__builtin___memcpy_chk ((char*)&instance->ttcap, (char
*)tmp_ttcap, sizeof(struct TTCapInfo), __builtin_object_size (
(char*)&instance->ttcap, 0))
445 sizeof(struct TTCapInfo))__builtin___memcpy_chk ((char*)&instance->ttcap, (char
*)tmp_ttcap, sizeof(struct TTCapInfo), __builtin_object_size (
(char*)&instance->ttcap, 0))
;
446
447 ftrc = FT_New_Size(instance->face->face, &instance->size);
448 if(ftrc != 0) {
449 ErrorF("FreeType: couldn't create size object: %d\n", ftrc);
450 free(instance);
451 return FTtoXReturnCode(ftrc);
452 }
453 FreeTypeActivateInstance(instance);
454 if(!face->bitmap) {
455 ftrc = FT_Set_Char_Size(instance->face->face,
456 (int)(trans->scale*(1<<6) + 0.5),
457 (int)(trans->scale*(1<<6) + 0.5),
458 trans->xres, trans->yres);
459 } else {
460 int xsize, ysize;
461 xrc = FTFindSize(face->face, trans, &xsize, &ysize);
462 if(xrc != Successful85) {
463 free(instance);
464 return xrc;
465 }
466 ftrc = FT_Set_Pixel_Sizes(instance->face->face, xsize, ysize);
467 }
468 if(ftrc != 0) {
469 FT_Done_Size(instance->size);
470 free(instance);
471 return FTtoXReturnCode(ftrc);
472 }
473
474 if( FT_IS_SFNT( face->face )( face->face->face_flags & ( 1L << 3 ) ) ) {
475#if 1
476 FT_F26Dot6 tt_char_width, tt_char_height, tt_dim_x, tt_dim_y;
477 FT_UInt nn;
478
479 instance->strike_index=0xFFFFU;
480
481 tt_char_width = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
482 tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
483
484 tt_dim_x = FLOOR64( ( tt_char_width * trans->xres + 36 ) / 72 + 32 )((( tt_char_width * trans->xres + 36 ) / 72 + 32) & -64
)
;
485 tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 )((( tt_char_height * trans->yres + 36 ) / 72 + 32) & -
64)
;
486
487 if ( tt_dim_x && !tt_dim_y )
488 tt_dim_y = tt_dim_x;
489 else if ( !tt_dim_x && tt_dim_y )
490 tt_dim_x = tt_dim_y;
491
492 for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ )
493 {
494 FT_Bitmap_Size* sz = &face->face->available_sizes[nn];
495
496 if ( tt_dim_x == FLOOR64(sz->x_ppem + 32)((sz->x_ppem + 32) & -64) && tt_dim_y == FLOOR64(sz->y_ppem + 32)((sz->y_ppem + 32) & -64) )
497 {
498 instance->strike_index = nn;
499 break;
500 }
501 }
502#else
503 /* See Set_Char_Sizes() in ttdriver.c */
504 FT_Error err;
505 TT_Face tt_face;
506 FT_Long tt_dim_x, tt_dim_y;
507 FT_UShort tt_x_ppem, tt_y_ppem;
508 FT_F26Dot6 tt_char_width, tt_char_height;
509 SFNT_Service sfnt;
510 tt_face=(TT_Face)face->face;
511 tt_char_width = (int)(trans->scale*(1<<6) + 0.5);
512 tt_char_height = (int)(trans->scale*(1<<6) + 0.5);
513 if ( ( tt_face->header.Flags & 8 ) != 0 ) {
514 tt_dim_x = ( ( tt_char_width * trans->xres + (36+32*72) ) / 72 ) & -64;
515 tt_dim_y = ( ( tt_char_height * trans->yres + (36+32*72) ) / 72 ) & -64;
516 }
517 else{
518 tt_dim_x = ( ( tt_char_width * trans->xres + 36 ) / 72 );
519 tt_dim_y = ( ( tt_char_height * trans->yres + 36 ) / 72 );
520 }
521 tt_x_ppem = (FT_UShort)( tt_dim_x >> 6 );
522 tt_y_ppem = (FT_UShort)( tt_dim_y >> 6 );
523 /* See Reset_SBit_Size() in ttobjs.c */
524 sfnt = (SFNT_Service)tt_face->sfnt;
525 err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index);
526 if ( err ) instance->strike_index=0xFFFFU;
527#endif
528 }
529
530 /* maintain a linked list of instances */
531 instance->next = instance->face->instances;
532 instance->face->instances = instance;
533
534 *instance_return = instance;
535 return Successful85;
536}
537
538static void
539FreeTypeFreeInstance(FTInstancePtr instance)
540{
541 FTInstancePtr otherInstance;
542
543 if( instance == NULL((void*)0) ) return;
544
545 if(instance->face->active_instance == instance)
546 instance->face->active_instance = NULL((void*)0);
547 instance->refcount--;
548 if(instance->refcount <= 0) {
549 int i,j;
550
551 if(instance->face->instances == instance)
552 instance->face->instances = instance->next;
553 else {
554 for(otherInstance = instance->face->instances;
555 otherInstance;
556 otherInstance = otherInstance->next)
557 if(otherInstance->next == instance) {
558 otherInstance->next = instance->next;
559 break;
560 }
561 }
562
563 FT_Done_Size(instance->size);
564 FreeTypeFreeFace(instance->face);
565
566 if(instance->charcellMetrics) {
567 free(instance->charcellMetrics);
568 }
569 if(instance->forceConstantMetrics) {
570 free(instance->forceConstantMetrics);
571 }
572 if(instance->glyphs) {
573 for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE16); i++) {
574 if(instance->glyphs[i]) {
575 for(j = 0; j < FONTSEGMENTSIZE16; j++) {
576 if(instance->available[i][j] ==
577 FT_AVAILABLE_RASTERISED3)
578 free(instance->glyphs[i][j].bits);
579 }
580 free(instance->glyphs[i]);
581 }
582 }
583 free(instance->glyphs);
584 }
585 if(instance->available) {
586 for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE16); i++) {
587 if(instance->available[i])
588 free(instance->available[i]);
589 }
590 free(instance->available);
591 }
592 free(instance);
593 }
594}
595
596static int
597FreeTypeInstanceFindGlyph(unsigned idx_in, int flags, FTInstancePtr instance,
598 CharInfoPtr **glyphs, int ***available,
599 int *found, int *segmentP, int *offsetP)
600{
601 int segment, offset;
602 unsigned idx = idx_in;
603
604 if( 0 <= instance->ttcap.forceConstantSpacingEnd ){
605 if( (flags & FT_FORCE_CONSTANT_SPACING0x08) )
606 idx += instance->nglyphs / 2 ;
607 }
608
609 if(idx > instance->nglyphs) {
610 *found = 0;
611 return Successful85;
612 }
613
614 if(*available == NULL((void*)0)) {
615 *available = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE16),
616 sizeof(int *));
617 if(*available == NULL((void*)0))
618 return AllocError80;
619 }
620
621 segment = ifloor(idx, FONTSEGMENTSIZE16);
622 offset = idx - segment * FONTSEGMENTSIZE16;
623
624 if((*available)[segment] == NULL((void*)0)) {
625 (*available)[segment] = calloc(FONTSEGMENTSIZE16, sizeof(int *));
Result of 'calloc' is converted to a pointer of type 'int', which is incompatible with sizeof operand type 'int *'
626 if((*available)[segment] == NULL((void*)0))
627 return AllocError80;
628 }
629
630 if(*glyphs == NULL((void*)0)) {
631 *glyphs = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE16),
632 sizeof(CharInfoPtr));
633 if(*glyphs == NULL((void*)0))
634 return AllocError80;
635 }
636
637 if((*glyphs)[segment] == NULL((void*)0)) {
638 (*glyphs)[segment] = malloc(sizeof(CharInfoRec) * FONTSEGMENTSIZE16);
639 if((*glyphs)[segment] == NULL((void*)0))
640 return AllocError80;
641 }
642
643 *found = 1;
644 *segmentP = segment;
645 *offsetP = offset;
646 return Successful85;
647}
648
649static int
650FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance)
651{
652 int found, segment, offset;
653 int xrc;
654 int ***available;
655 CharInfoPtr **glyphs;
656
657 available = &instance->available;
658 glyphs = &instance->glyphs;
659
660 xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, glyphs, available,
661 &found, &segment, &offset);
662 if(xrc != Successful85)
663 return xrc;
664
665 if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO1) {
666 *g = NULL((void*)0);
667 return Successful85;
668 }
669
670 if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED3) {
671 *g = &(*glyphs)[segment][offset];
672 return Successful85;
673 }
674
675 flags |= FT_GET_GLYPH_BOTH0x01;
676
677 xrc = FreeTypeRasteriseGlyph(idx, flags,
678 &(*glyphs)[segment][offset], instance,
679 (*available)[segment][offset] >= FT_AVAILABLE_METRICS2);
680 if(xrc != Successful85 && (*available)[segment][offset] >= FT_AVAILABLE_METRICS2) {
681 ErrorF("Warning: FreeTypeRasteriseGlyph() returns an error,\n");
682 ErrorF("\tso the backend tries to set a white space.\n");
683 xrc = FreeTypeRasteriseGlyph(idx, flags | FT_GET_DUMMY0x04,
684 &(*glyphs)[segment][offset], instance,
685 (*available)[segment][offset] >= FT_AVAILABLE_METRICS2);
686 }
687 if(xrc == Successful85) {
688 (*available)[segment][offset] = FT_AVAILABLE_RASTERISED3;
689 /* return the glyph */
690 *g = &(*glyphs)[segment][offset];
691 }
692 return xrc;
693}
694
695static int
696FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
697 xCharInfo **metrics, FTInstancePtr instance )
698{
699 int xrc;
700 int found, segment, offset;
701
702 /* Char cell */
703 if(instance->spacing == FT_CHARCELL2) {
704 *metrics = instance->charcellMetrics;
705 return Successful85;
706 }
707 /* Force constant metrics */
708 if( flags & FT_FORCE_CONSTANT_SPACING0x08) {
709 *metrics = instance->forceConstantMetrics;
710 return Successful85;
711 }
712
713 /* Not char cell */
714
715 xrc = FreeTypeInstanceFindGlyph(idx, flags, instance,
716 &instance->glyphs, &instance->available,
717 &found, &segment, &offset);
718 if(xrc != Successful85)
719 return xrc;
720 if(!found) {
721 *metrics = NULL((void*)0);
722 return Successful85;
723 }
724 if( instance->available[segment][offset] == FT_AVAILABLE_NO1 ) {
725 *metrics = NULL((void*)0);
726 return Successful85;
727 }
728
729 if( instance->available[segment][offset] >= FT_AVAILABLE_METRICS2 ) {
730 *metrics = &instance->glyphs[segment][offset].metrics;
731 return Successful85;
732 }
733
734 flags |= FT_GET_GLYPH_METRICS_ONLY0x02;
735
736 xrc = FreeTypeRasteriseGlyph(idx, flags,
737 &instance->glyphs[segment][offset],
738 instance, 0);
739 if(xrc == Successful85) {
740 instance->available[segment][offset] = FT_AVAILABLE_METRICS2;
741 *metrics = &instance->glyphs[segment][offset].metrics;
742 }
743 return xrc;
744}
745
746/*
747 * Pseudo enbolding similar as Microsoft Windows.
748 * It is useful but poor.
749 */
750static void
751ft_make_up_bold_bitmap( char *raster, int bpr, int ht, int ds_mode)
752{
753 int x, y;
754 unsigned char *p = (unsigned char *)raster;
755 if ( ds_mode & TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT0x0002 ) {
756 for (y=0; y<ht; y++) {
757 unsigned char rev_pat=0;
758 unsigned char lsb = 0;
759 for (x=0; x<bpr; x++) {
760 unsigned char tmp = *p<<7;
761 if ( (rev_pat & 0x01) && (*p & 0x80) ) p[-1] &= 0xfe;
762 rev_pat = ~(*p);
763 *p |= (*p>>1) | lsb;
764 *p &= ~(rev_pat & (*p << 1));
765 lsb = tmp;
766 p++;
767 }
768 }
769 }
770 else {
771 for (y=0; y<ht; y++) {
772 unsigned char lsb = 0;
773 for (x=0; x<bpr; x++) {
774 unsigned char tmp = *p<<7;
775 *p |= (*p>>1) | lsb;
776 lsb = tmp;
777 p++;
778 }
779 }
780 }
781}
782
783static void
784ft_make_up_italic_bitmap( char *raster, int bpr, int ht, int shift,
785 int h_total, int h_offset, double a_italic)
786{
787 int x, y;
788 unsigned char *p = (unsigned char *)raster;
789 if ( a_italic < 0 ) shift = -shift;
790 for (y=0; y<ht; y++) {
791 unsigned char *tmp_p = p + y*bpr;
792 int tmp_shift = shift * (h_total -1 -(y+h_offset)) / h_total;
793 int tmp_byte_shift;
794 if ( 0 <= tmp_shift ) {
795 tmp_byte_shift = tmp_shift/8;
796 tmp_shift %= 8;
797 if ( tmp_shift ) {
798 for (x=bpr-1;0<=x;x--) {
799 if ( x != bpr-1 )
800 tmp_p[x+1] |= tmp_p[x]<<(8-tmp_shift);
801 tmp_p[x]>>=tmp_shift;
802 }
803 }
804 if ( tmp_byte_shift ) {
805 for (x=bpr-1;0<x;x--) {
806 tmp_p[x] = tmp_p[x-1];
807 }
808 tmp_p[x]=0;
809 }
810 }
811 else {
812 tmp_shift = -tmp_shift;
813 tmp_byte_shift = tmp_shift/8;
814 tmp_shift %= 8;
815 if ( tmp_shift ) {
816 for (x=0;x<bpr;x++) {
817 if ( x != 0 )
818 tmp_p[x-1] |= tmp_p[x]>>(8-tmp_shift);
819 tmp_p[x]<<=tmp_shift;
820 }
821 }
822 if ( tmp_byte_shift ) {
823 for (x=0;x<bpr-1;x++) {
824 tmp_p[x] = tmp_p[x+1];
825 }
826 tmp_p[x]=0;
827 }
828 }
829 }
830}
831
832/*
833 * The very lazy method,
834 * parse the htmx field in TrueType font.
835 */
836
837static void
838tt_get_metrics( FT_Face face,
839 FT_UInt idx,
840 FT_UInt num_hmetrics,
841 FT_Short* bearing,
842 FT_UShort* advance )
843{
844 /* read the metrics directly from the horizontal header, we
845 * parse the SFNT table directly through the standard FreeType API.
846 * this works with any version of the library and doesn't need to
847 * peek at its internals. Maybe a bit less
848 */
849 FT_UInt count = num_hmetrics;
850 FT_ULong length = 0;
851 FT_ULong offset = 0;
852 FT_Error error;
853
854 error = FT_Load_Sfnt_Table( face, TTAG_hmtx(FT_Tag) ( ( (FT_ULong)'h' << 24 ) | ( (FT_ULong)'m' <<
16 ) | ( (FT_ULong)'t' << 8 ) | (FT_ULong)'x' )
, 0, NULL((void*)0), &length );
855
856 if ( count == 0 || error )
857 {
858 *advance = 0;
859 *bearing = 0;
860 }
861 else if ( idx < count )
862 {
863 offset = idx * 4L;
864 if ( offset + 4 > length )
865 {
866 *advance = 0;
867 *bearing = 0;
868 }
869 else
870 {
871 *advance = sfnt_get_ushort( face, TTAG_hmtx(FT_Tag) ( ( (FT_ULong)'h' << 24 ) | ( (FT_ULong)'m' <<
16 ) | ( (FT_ULong)'t' << 8 ) | (FT_ULong)'x' )
, offset );
872 *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 )((FT_Short)sfnt_get_ushort((face),((FT_Tag) ( ( (FT_ULong)'h'
<< 24 ) | ( (FT_ULong)'m' << 16 ) | ( (FT_ULong)
't' << 8 ) | (FT_ULong)'x' )),(offset+2)))
;
873 }
874 }
875 else
876 {
877 offset = 4L * (count - 1);
878 if ( offset + 4 > length )
879 {
880 *advance = 0;
881 *bearing = 0;
882 }
883 else
884 {
885 *advance = sfnt_get_ushort ( face, TTAG_hmtx(FT_Tag) ( ( (FT_ULong)'h' << 24 ) | ( (FT_ULong)'m' <<
16 ) | ( (FT_ULong)'t' << 8 ) | (FT_ULong)'x' )
, offset );
886 offset += 4 + 2 * ( idx - count );
887 if ( offset + 2 > length)
888 *bearing = 0;
889 else
890 *bearing = sfnt_get_short ( face, TTAG_hmtx, offset )((FT_Short)sfnt_get_ushort((face),((FT_Tag) ( ( (FT_ULong)'h'
<< 24 ) | ( (FT_ULong)'m' << 16 ) | ( (FT_ULong)
't' << 8 ) | (FT_ULong)'x' )),(offset)))
;
891 }
892 }
893}
894
895static int
896ft_get_very_lazy_bbox( FT_UInt index,
897 FT_Face face,
898 FT_Size size,
899 FT_UInt num_hmetrics,
900 double slant,
901 FT_Matrix *matrix,
902 FT_BBox *bbox,
903 FT_Long *horiAdvance,
904 FT_Long *vertAdvance)
905{
906 if ( FT_IS_SFNT( face )( face->face_flags & ( 1L << 3 ) ) ) {
907 FT_Size_Metrics *smetrics = &size->metrics;
908 FT_Short leftBearing = 0;
909 FT_UShort advance = 0;
910 FT_Vector p0, p1, p2, p3;
911
912 /* horizontal */
913 tt_get_metrics( face, index, num_hmetrics,
914 &leftBearing, &advance );
915
916#if 0
917 fprintf(stderr__stderrp,"x_scale=%f y_scale=%f\n",
918 (double)smetrics->x_scale,(double)smetrics->y_scale);
919#endif
920 bbox->xMax = *horiAdvance =
921 FT_MulFix( advance, smetrics->x_scale );
922 bbox->xMin =
923 FT_MulFix( leftBearing, smetrics->x_scale );
924 /* vertical */
925 bbox->yMin = FT_MulFix( face->bbox.yMin,
926 smetrics->y_scale );
927 bbox->yMax = FT_MulFix( face->bbox.yMax,
928 smetrics->y_scale );
929 /* slant */
930 if( 0 < slant ) {
931 bbox->xMax += slant * bbox->yMax;
932 bbox->xMin += slant * bbox->yMin;
933 }
934 else if( slant < 0 ) {
935 bbox->xMax += slant * bbox->yMin;
936 bbox->xMin += slant * bbox->yMax;
937 }
938
939 *vertAdvance = -1; /* We don't support */
940
941 p0.x = p2.x = bbox->xMin;
942 p1.x = p3.x = bbox->xMax;
943 p0.y = p1.y = bbox->yMin;
944 p2.y = p3.y = bbox->yMax;
945
946 FT_Vector_Transform(&p0, matrix);
947 FT_Vector_Transform(&p1, matrix);
948 FT_Vector_Transform(&p2, matrix);
949 FT_Vector_Transform(&p3, matrix);
950
951#if 0
952 fprintf(stderr__stderrp,
953 "->(%.1f %.1f) (%.1f %.1f)"
954 " (%.1f %.1f) (%.1f %.1f)\n",
955 p0.x / 64.0, p0.y / 64.0,
956 p1.x / 64.0, p1.y / 64.0,
957 p2.x / 64.0, p2.y / 64.0,
958 p3.x / 64.0, p3.y / 64.0);
959#endif
960 bbox->xMin = MIN(p0.x, MIN(p1.x, MIN(p2.x, p3.x)))((p0.x) < (((p1.x) < (((p2.x) < (p3.x) ? (p2.x) : (p3
.x))) ? (p1.x) : (((p2.x) < (p3.x) ? (p2.x) : (p3.x))))) ?
(p0.x) : (((p1.x) < (((p2.x) < (p3.x) ? (p2.x) : (p3.x
))) ? (p1.x) : (((p2.x) < (p3.x) ? (p2.x) : (p3.x))))))
;
961 bbox->xMax = MAX(p0.x, MAX(p1.x, MAX(p2.x, p3.x)))((p0.x) > (((p1.x) > (((p2.x) > (p3.x) ? (p2.x) : (p3
.x))) ? (p1.x) : (((p2.x) > (p3.x) ? (p2.x) : (p3.x))))) ?
(p0.x) : (((p1.x) > (((p2.x) > (p3.x) ? (p2.x) : (p3.x
))) ? (p1.x) : (((p2.x) > (p3.x) ? (p2.x) : (p3.x))))))
;
962 bbox->yMin = MIN(p0.y, MIN(p1.y, MIN(p2.y, p3.y)))((p0.y) < (((p1.y) < (((p2.y) < (p3.y) ? (p2.y) : (p3
.y))) ? (p1.y) : (((p2.y) < (p3.y) ? (p2.y) : (p3.y))))) ?
(p0.y) : (((p1.y) < (((p2.y) < (p3.y) ? (p2.y) : (p3.y
))) ? (p1.y) : (((p2.y) < (p3.y) ? (p2.y) : (p3.y))))))
;
963 bbox->yMax = MAX(p0.y, MAX(p1.y, MAX(p2.y, p3.y)))((p0.y) > (((p1.y) > (((p2.y) > (p3.y) ? (p2.y) : (p3
.y))) ? (p1.y) : (((p2.y) > (p3.y) ? (p2.y) : (p3.y))))) ?
(p0.y) : (((p1.y) > (((p2.y) > (p3.y) ? (p2.y) : (p3.y
))) ? (p1.y) : (((p2.y) > (p3.y) ? (p2.y) : (p3.y))))))
;
964 return 0; /* Successful */
965 }
966 return -1;
967}
968
969static FT_Error
970FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index,
971 FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return,
972 int *sbitchk_incomplete_but_exist )
973{
974#if 1
975 if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL((void*)0) )
976 {
977 FT_Error error;
978 FT_Bitmap_Size* sz = &ft_face->available_sizes[strike_index];
979
980 error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 );
981 if ( !error )
982 {
983 error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY0x4000 );
984 if ( !error )
985 {
986 if ( metrics_return != NULL((void*)0) )
987 *metrics_return = ft_face->glyph->metrics;
988
989 return 0;
990 }
991 }
992 }
993 return -1;
994#elif (FREETYPE_VERSION(2 * 1000000 + 4 * 1000 + 4) >= 2001008)
995 SFNT_Service sfnt;
996 TT_Face face;
997 FT_Error error;
998 FT_Stream stream;
999 TT_SBit_Strike strike;
1000 TT_SBit_Range range;
1001 TT_SBit_MetricsRec elem_metrics;
1002 FT_ULong ebdt_pos;
1003 FT_ULong glyph_offset;
1004 ;
1005
1006 if ( ! FT_IS_SFNT( ft_face )( ft_face->face_flags & ( 1L << 3 ) ) )
1007 {
1008 error=-1;
1009 goto Exit;
1010 }
1011
1012 face = (TT_Face)ft_face;
1013 sfnt = (SFNT_Service)face->sfnt;
1014
1015 if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image &&
1016 sfnt->load_sbits) {
1017 /* Check whether there is a glyph sbit for the current index */
1018 error = sfnt->find_sbit_image( face, glyph_index, strike_index,
1019 &range, &strike, &glyph_offset );
1020 }
1021 else error=-1;
1022 if ( error ) goto Exit;
1023
1024 if ( metrics_return == NULL((void*)0) ) goto Exit;
1025
1026 stream = face->root.stream;
1027
1028 /* now, find the location of the `EBDT' table in */
1029 /* the font file */
1030 error = face->goto_table( face, TTAG_EBDT(FT_Tag) ( ( (FT_ULong)'E' << 24 ) | ( (FT_ULong)'B' <<
16 ) | ( (FT_ULong)'D' << 8 ) | (FT_ULong)'T' )
, stream, 0 );
1031 if ( error )
1032 error = face->goto_table( face, TTAG_bdat(FT_Tag) ( ( (FT_ULong)'b' << 24 ) | ( (FT_ULong)'d' <<
16 ) | ( (FT_ULong)'a' << 8 ) | (FT_ULong)'t' )
, stream, 0 );
1033 if (error)
1034 goto Exit;
1035
1036 ebdt_pos = FT_STREAM_POS();
1037
1038 /* place stream at beginning of glyph data and read metrics */
1039 if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
1040 goto Exit;
1041
1042 error = sfnt->load_sbit_metrics( stream, range, &elem_metrics );
1043 if ( error )
1044 goto Exit;
1045
1046 metrics_return->width = (FT_Pos)elem_metrics.width << 6;
1047 metrics_return->height = (FT_Pos)elem_metrics.height << 6;
1048
1049 metrics_return->horiBearingX = (FT_Pos)elem_metrics.horiBearingX << 6;
1050 metrics_return->horiBearingY = (FT_Pos)elem_metrics.horiBearingY << 6;
1051 metrics_return->horiAdvance = (FT_Pos)elem_metrics.horiAdvance << 6;
1052
1053 metrics_return->vertBearingX = (FT_Pos)elem_metrics.vertBearingX << 6;
1054 metrics_return->vertBearingY = (FT_Pos)elem_metrics.vertBearingY << 6;
1055 metrics_return->vertAdvance = (FT_Pos)elem_metrics.vertAdvance << 6;
1056
1057 Exit:
1058 return error;
1059#else /* if (FREETYPE_VERSION < 2001008) */
1060 TT_Face face;
1061 SFNT_Service sfnt;
1062 if ( ! FT_IS_SFNT( ft_face )( ft_face->face_flags & ( 1L << 3 ) ) ) return -1;
1063 face = (TT_Face)ft_face;
1064 sfnt = (SFNT_Service)face->sfnt;
1065 if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
1066 if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1;
1067 }
1068 return -1;
1069#endif
1070}
1071
1072#pragma GCC diagnostic ignored "-Wbad-function-cast"
1073
1074int
1075FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
1076 FTInstancePtr instance, int hasMetrics)
1077{
1078 FTFacePtr face;
1079 FT_BBox bbox;
1080 FT_Long outline_hori_advance, outline_vert_advance;
1081 FT_Glyph_Metrics sbit_metrics;
1082 FT_Glyph_Metrics *bitmap_metrics=NULL((void*)0), *metrics = NULL((void*)0);
1083 char *raster;
1084 int wd, ht, bpr; /* width, height, bytes per row */
1085 int wd_actual, ht_actual;
1086 int ftrc, is_outline, correct, b_shift=0;
1087 int dx, dy;
1088 int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth,
1089 ascent, descent;
1090 int sbitchk_incomplete_but_exist;
1091 double bbox_center_raw;
1092
1093 face = instance->face;
1094
1095 FreeTypeActivateInstance(instance);
1096
1097 if(!tgp) return AllocError80;
1098
1099 /*
1100 * PREPARE METRICS
1101 */
1102
1103 if(!hasMetrics) {
1104 if( instance->spacing == FT_CHARCELL2 || flags & FT_GET_DUMMY0x04 ){
1105 memcpy((char*)&tgp->metrics,__builtin___memcpy_chk ((char*)&tgp->metrics, (char*)instance
->charcellMetrics, sizeof(xCharInfo), __builtin_object_size
((char*)&tgp->metrics, 0))
1106 (char*)instance->charcellMetrics,__builtin___memcpy_chk ((char*)&tgp->metrics, (char*)instance
->charcellMetrics, sizeof(xCharInfo), __builtin_object_size
((char*)&tgp->metrics, 0))
1107 sizeof(xCharInfo))__builtin___memcpy_chk ((char*)&tgp->metrics, (char*)instance
->charcellMetrics, sizeof(xCharInfo), __builtin_object_size
((char*)&tgp->metrics, 0))
;
1108 }
1109 else if( flags & FT_FORCE_CONSTANT_SPACING0x08 ) {
1110 memcpy((char*)&tgp->metrics,__builtin___memcpy_chk ((char*)&tgp->metrics, (char*)instance
->forceConstantMetrics, sizeof(xCharInfo), __builtin_object_size
((char*)&tgp->metrics, 0))
1111 (char*)instance->forceConstantMetrics,__builtin___memcpy_chk ((char*)&tgp->metrics, (char*)instance
->forceConstantMetrics, sizeof(xCharInfo), __builtin_object_size
((char*)&tgp->metrics, 0))
1112 sizeof(xCharInfo))__builtin___memcpy_chk ((char*)&tgp->metrics, (char*)instance
->forceConstantMetrics, sizeof(xCharInfo), __builtin_object_size
((char*)&tgp->metrics, 0))
;
1113 }
1114 /* mono or prop. */
1115 else{
1116 int new_width;
1117 double ratio;
1118
1119 sbitchk_incomplete_but_exist=0;
1120 if( ! (instance->load_flags & FT_LOAD_NO_BITMAP0x8) ) {
1121 if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index,
1122 idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) {
1123 bitmap_metrics = &sbit_metrics;
1124 }
1125 }
1126 if( bitmap_metrics == NULL((void*)0) ) {
1127 if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY0x0010) ) {
1128 if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
1129 face->num_hmetrics,
1130 instance->ttcap.vl_slant,
1131 &instance->transformation.matrix,
1132 &bbox, &outline_hori_advance,
1133 &outline_vert_advance ) == 0 ) {
1134 goto bbox_ok; /* skip exact calculation */
1135 }
1136 }
1137 ftrc = FT_Load_Glyph(instance->face->face, idx,
1138 instance->load_flags);
1139 if(ftrc != 0) return FTtoXReturnCode(ftrc);
1140 metrics = &face->face->glyph->metrics;
1141 if( face->face->glyph->format == FT_GLYPH_FORMAT_BITMAP ) {
1142 bitmap_metrics = metrics;
1143 }
1144 }
1145
1146 if( bitmap_metrics ) {
1147 FT_Pos factor;
1148
1149 leftSideBearing = bitmap_metrics->horiBearingX / 64;
1150 rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64;
1151 bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0;
1152 characterWidth = (int)floor(bitmap_metrics->horiAdvance
1153 * instance->ttcap.scaleBBoxWidth / 64.0 + .5);
1154 ascent = bitmap_metrics->horiBearingY / 64;
1155 descent = (bitmap_metrics->height - bitmap_metrics->horiBearingY) / 64 ;
1156 /* */
1157 new_width = characterWidth;
1158 if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008 )
1159 new_width += instance->ttcap.doubleStrikeShift;
1160 new_width += instance->ttcap.adjustBBoxWidthByPixel;
1161 ratio = (double)new_width/characterWidth;
1162 characterWidth = new_width;
1163 /* adjustment by pixel unit */
1164 if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE0x0001 )
1165 rightSideBearing += instance->ttcap.doubleStrikeShift;
1166 rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
1167 leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
1168 rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic;
1169 leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic;
1170 /* */
1171 factor = bitmap_metrics->horiAdvance;
1172 rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor
1173 * instance->ttcap.scaleBBoxWidth * ratio / 64.
1174 / instance->pixel_size));
1175 }
1176 else {
1177 /* Outline */
1178#ifdef USE_GET_CBOX
1179 /* Very fast?? */
1180 FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
1181 ftrc=0; /* FT_Outline_Get_CBox returns nothing. */
1182#else
1183 /* Calculate exact metrics */
1184 ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
1185#endif
1186 if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
1187 outline_hori_advance = metrics->horiAdvance;
1188 outline_vert_advance = metrics->vertAdvance;
1189 bbox_ok:
1190 descent = CEIL64(-bbox.yMin - 32)(((-bbox.yMin - 32) + 64 - 1) & -64) / 64;
1191 leftSideBearing = FLOOR64(bbox.xMin + 32)((bbox.xMin + 32) & -64) / 64;
1192 ascent = FLOOR64(bbox.yMax + 32)((bbox.yMax + 32) & -64) / 64;
1193 rightSideBearing = FLOOR64(bbox.xMax + 32)((bbox.xMax + 32) & -64) / 64;
1194 bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
1195 if ( instance->pixel_width_unit_x != 0 )
1196 characterWidth =
1197 (int)floor( outline_hori_advance
1198 * instance->ttcap.scaleBBoxWidth
1199 * instance->pixel_width_unit_x / 64. + .5);
1200 else {
1201 characterWidth =
1202 (int)floor( outline_vert_advance
1203 * instance->ttcap.scaleBBoxHeight
1204 * instance->pixel_width_unit_y / 64. + .5);
1205 if(characterWidth <= 0)
1206 characterWidth = instance->charcellMetrics->characterWidth;
1207 }
1208 /* */
1209 new_width = characterWidth;
1210 if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008 )
1211 new_width += instance->ttcap.doubleStrikeShift;
1212 new_width += instance->ttcap.adjustBBoxWidthByPixel;
1213 ratio = (double)new_width/characterWidth;
1214 characterWidth = new_width;
1215 if ( instance->pixel_width_unit_x != 0 )
1216 rawCharacterWidth =
1217 (unsigned short)(short)(floor(1000 * outline_hori_advance
1218 * instance->ttcap.scaleBBoxWidth * ratio
1219 * instance->pixel_width_unit_x / 64.));
1220 else {
1221 rawCharacterWidth =
1222 (unsigned short)(short)(floor(1000 * outline_vert_advance
1223 * instance->ttcap.scaleBBoxHeight * ratio
1224 * instance->pixel_width_unit_y / 64.));
1225 if(rawCharacterWidth <= 0)
1226 rawCharacterWidth = instance->charcellMetrics->attributes;
1227 }
1228 /* adjustment by pixel unit */
1229 if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE0x0001 )
1230 rightSideBearing += instance->ttcap.doubleStrikeShift;
1231 rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
1232 leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
1233 }
1234
1235 /* Set the glyph metrics. */
1236 tgp->metrics.attributes = (unsigned short)((short)rawCharacterWidth);
1237 tgp->metrics.leftSideBearing = leftSideBearing;
1238 tgp->metrics.rightSideBearing = rightSideBearing;
1239 tgp->metrics.characterWidth = characterWidth;
1240 tgp->metrics.ascent = ascent;
1241 tgp->metrics.descent = descent;
1242 /* Update the width to match the width of the font */
1243 if( instance->spacing != FT_PROPORTIONAL0 )
1244 tgp->metrics.characterWidth = instance->charcellMetrics->characterWidth;
1245 if(instance->ttcap.flags & TTCAP_MONO_CENTER0x0800){
1246 b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
1247 tgp->metrics.leftSideBearing += b_shift;
1248 tgp->metrics.rightSideBearing += b_shift;
1249 }
1250 }
1251 }
1252
1253 if( flags & FT_GET_GLYPH_METRICS_ONLY0x02 ) return Successful85;
1254
1255 /*
1256 * CHECK THE NECESSITY OF BITMAP POSITION'S CORRECTION
1257 */
1258
1259 correct=0;
1260 if( instance->spacing == FT_CHARCELL2 ) correct=1;
1261 else if( flags & FT_FORCE_CONSTANT_SPACING0x08 ) correct=1;
1262 else{
1263 int sbit_available=0;
1264 sbitchk_incomplete_but_exist=0;
1265 if( !(instance->load_flags & FT_LOAD_NO_BITMAP0x8) ) {
1266 if( FT_Do_SBit_Metrics(face->face,instance->size,
1267 instance->strike_index,idx,NULL((void*)0),
1268 &sbitchk_incomplete_but_exist)==0 ) {
1269 sbit_available=1;
1270 }
1271 }
1272 if( sbit_available == 0 ) {
1273 if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY0x0010) ) {
1274 if( FT_IS_SFNT(face->face)( face->face->face_flags & ( 1L << 3 ) ) ) correct=1;
1275 }
1276 }
1277 }
1278
1279 /*
1280 * RENDER AND ALLOCATE BUFFER
1281 */
1282
1283 if( flags & FT_GET_DUMMY0x04 ) is_outline = -1;
1284 else {
1285 if( !metrics ) {
1286 ftrc = FT_Load_Glyph(instance->face->face, idx,
1287 instance->load_flags);
1288 metrics = &face->face->glyph->metrics;
1289
1290 if(ftrc != 0) return FTtoXReturnCode(ftrc);
1291 }
1292
1293 if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
1294#ifdef USE_GET_CBOX
1295 FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
1296 ftrc = 0;
1297#else
1298 ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
1299#endif
1300 if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
1301 bbox.yMin = FLOOR64( bbox.yMin )((bbox.yMin) & -64);
1302 bbox.yMax = CEIL64 ( bbox.yMax )(((bbox.yMax) + 64 - 1) & -64);
1303 ht_actual = ( bbox.yMax - bbox.yMin ) >> 6;
1304 /* FreeType think a glyph with 0 height control box is invalid.
1305 * So just let X to create a empty bitmap instead. */
1306 if ( ht_actual == 0 )
1307 is_outline = -1;
1308 else
1309 {
1310 ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO);
1311 if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
1312 is_outline = 1;
1313 }
1314 }
1315 else{
1316 is_outline=0;
1317 }
1318 }
1319
1320 /* Spacial case */
1321 if( (instance->ttcap.flags & TTCAP_MONO_CENTER0x0800) && hasMetrics ) {
1322 if( is_outline == 1 ){
1323 if( correct ){
1324 if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
1325 face->num_hmetrics,
1326 instance->ttcap.vl_slant,
1327 &instance->transformation.matrix,
1328 &bbox, &outline_hori_advance,
1329 &outline_vert_advance ) != 0 ){
1330 is_outline = -1; /* <- error */
1331 }
1332 }
1333 else {
1334#ifdef USE_GET_CBOX
1335 FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
1336 ftrc=0;
1337#else
1338 ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
1339#endif
1340 if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
1341 }
1342 bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
1343 }
1344 else if( is_outline == 0 )
1345 bbox_center_raw = (2.0 * metrics->horiBearingX + metrics->width)/2.0/64.0;
1346 else
1347 bbox_center_raw = 0;
1348 b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
1349 }
1350
1351 wd_actual = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing;
1352 ht_actual = tgp->metrics.ascent + tgp->metrics.descent;
1353
1354 /* The X convention is to consider a character with an empty
1355 * bounding box as undefined. This convention is broken. */
1356
1357 if(wd_actual <= 0) wd = 1;
1358 else wd=wd_actual;
1359 if(ht_actual <= 0) ht = 1;
1360 else ht=ht_actual;
1361
1362 bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) &
1363 -instance->bmfmt.glyph);
1364 raster = calloc(1, ht * bpr);
1365 if(raster == NULL((void*)0))
1366 return AllocError80;
1367
1368 tgp->bits = raster;
1369
1370 /* If FT_GET_DUMMY is set, we return white space. */
1371 if ( is_outline == -1 ) return Successful85;
1372
1373 if ( wd_actual <= 0 || ht_actual <= 0 ) return Successful85;
1374
1375 /*
1376 * CALCULATE OFFSET, dx AND dy.
1377 */
1378
1379 dx = face->face->glyph->bitmap_left - tgp->metrics.leftSideBearing;
1380 dy = tgp->metrics.ascent - face->face->glyph->bitmap_top;
1381
1382 if(instance->ttcap.flags & TTCAP_MONO_CENTER0x0800)
1383 dx += b_shift;
1384
1385 /* To prevent chipped bitmap, we correct dx and dy if needed. */
1386 if( correct && is_outline==1 ){
1387 int lsb, rsb, asc, des;
1388 int chip_left,chip_right,chip_top,chip_bot;
1389#ifdef USE_GET_CBOX
1390 FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
1391 ftrc=0;
1392#else
1393 ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
1394#endif
1395 if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
1396 des = CEIL64(-bbox.yMin - 32)(((-bbox.yMin - 32) + 64 - 1) & -64) / 64;
1397 lsb = FLOOR64(bbox.xMin + 32)((bbox.xMin + 32) & -64) / 64;
1398 asc = FLOOR64(bbox.yMax + 32)((bbox.yMax + 32) & -64) / 64;
1399 rsb = FLOOR64(bbox.xMax + 32)((bbox.xMax + 32) & -64) / 64;
1400 rightSideBearing = tgp->metrics.rightSideBearing;
1401 leftSideBearing = tgp->metrics.leftSideBearing;
1402 if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE0x0001 )
1403 rightSideBearing -= instance->ttcap.doubleStrikeShift;
1404 /* special case */
1405 if(instance->ttcap.flags & TTCAP_MONO_CENTER0x0800){
1406 leftSideBearing -= b_shift;
1407 rightSideBearing -= b_shift;
1408 }
1409 chip_left = lsb - leftSideBearing;
1410 chip_right = rightSideBearing - rsb;
1411 if( flags & FT_FORCE_CONSTANT_SPACING0x08 ){
1412 if( instance->ttcap.force_c_adjust_lsb_by_pixel != 0 ||
1413 instance->ttcap.force_c_adjust_rsb_by_pixel != 0 ){
1414 chip_left=0;
1415 chip_right=0;
1416 }
1417 }
1418 else{
1419 if( instance->ttcap.adjustRightSideBearingByPixel != 0 ||
1420 instance->ttcap.adjustLeftSideBearingByPixel != 0 ){
1421 chip_left=0;
1422 chip_right=0;
1423 }
1424 }
1425 chip_top = tgp->metrics.ascent - asc;
1426 chip_bot = tgp->metrics.descent - des;
1427 if( chip_left < 0 && 0 < chip_right ) dx++;
1428 else if( chip_right < 0 && 0 < chip_left ) dx--;
1429 if( chip_top < 0 && 0 < chip_bot ) dy++;
1430 else if( chip_bot < 0 && 0 < chip_top ) dy--;
1431 }
1432
1433 /*
1434 * COPY RASTER
1435 */
1436
1437 {
1438 FT_Bitmap *bitmap;
1439 int i, j;
1440 unsigned char *current_raster;
1441 unsigned char *current_buffer;
1442 int mod_dx0,mod_dx1;
1443 int div_dx;
1444 bitmap = &face->face->glyph->bitmap;
1445 if( 0 <= dx ){
1446 div_dx = dx / 8;
1447 mod_dx0 = dx % 8;
1448 mod_dx1 = 8-mod_dx0;
1449 }
1450 else{
1451 div_dx = dx / 8 -1;
1452 mod_dx1 = -dx % 8;
1453 mod_dx0 = 8-mod_dx1;
1454 }
1455 for( i = MAX(0, dy)((0) > (dy) ? (0) : (dy)) ; i<ht ; i++ ){
1456 int prev_jj,jj;
1457 if( bitmap->rows <= i-dy ) break;
1458 current_buffer=(unsigned char *)(bitmap->buffer+bitmap->pitch*(i-dy));
1459 current_raster=(unsigned char *)(raster+i*bpr);
1460 j = MAX(0,div_dx)((0) > (div_dx) ? (0) : (div_dx));
1461 jj = j-div_dx;
1462 prev_jj = jj-1;
1463 if( j<bpr ){
1464 if( 0 <= prev_jj && prev_jj < bitmap->pitch )
1465 current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
1466 if( 0 <= jj && jj < bitmap->pitch ){
1467 current_raster[j]|=current_buffer[jj]>>mod_dx0;
1468 j++; prev_jj++; jj++;
1469 for( ; j<bpr ; j++,prev_jj++,jj++ ){
1470 current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
1471 if( bitmap->pitch <= jj ) break;
1472 current_raster[j]|=current_buffer[jj]>>mod_dx0;
1473 }
1474 }
1475 }
1476 }
1477 }
1478
1479 /* by TTCap */
1480 if ( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE0x0001 ) {
1481 int i;
1482 for( i=0 ; i < instance->ttcap.doubleStrikeShift ; i++ )
1483 ft_make_up_bold_bitmap( raster, bpr, ht, instance->ttcap.flags);
1484 }
1485 if ( is_outline == 0 &&
1486 ( instance->ttcap.lsbShiftOfBitmapAutoItalic != 0 ||
1487 instance->ttcap.rsbShiftOfBitmapAutoItalic != 0 ) ) {
1488 ft_make_up_italic_bitmap( raster, bpr, ht,
1489 - instance->ttcap.lsbShiftOfBitmapAutoItalic
1490 + instance->ttcap.rsbShiftOfBitmapAutoItalic,
1491 instance->charcellMetrics->ascent
1492 + instance->charcellMetrics->descent,
1493 instance->charcellMetrics->ascent
1494 - tgp->metrics.ascent,
1495 instance->ttcap.autoItalic);
1496 }
1497
1498 if(instance->bmfmt.bit == LSBFirst0) {
1499 BitOrderInvert((unsigned char*)(tgp->bits), ht*bpr);
1500 }
1501
1502 if(instance->bmfmt.byte != instance->bmfmt.bit) {
1503 switch(instance->bmfmt.scan) {
1504 case 1:
1505 break;
1506 case 2:
1507 TwoByteSwap((unsigned char*)(tgp->bits), ht*bpr);
1508 break;
1509 case 4:
1510 FourByteSwap((unsigned char*)(tgp->bits), ht*bpr);
1511 break;
1512 default:
1513 ;
1514 }
1515 }
1516
1517 return Successful85;
1518}
1519
1520static void
1521FreeTypeFreeFont(FTFontPtr font)
1522{
1523 FreeTypeFreeInstance(font->instance);
1524 if(font->ranges)
1525 free(font->ranges);
1526 if(font->dummy_char.bits)
1527 free(font->dummy_char.bits);
1528 free(font);
1529}
1530
1531/* Free a font. If freeProps is 0, don't free the properties. */
1532
1533static void
1534FreeTypeFreeXFont(FontPtr pFont, int freeProps)
1535{
1536 FTFontPtr tf;
1537
1538 if(pFont) {
1539 if((tf = (FTFontPtr)pFont->fontPrivate)) {
1540 FreeTypeFreeFont(tf);
1541 }
1542 if(freeProps && pFont->info.nprops>0) {
1543 free(pFont->info.isStringProp);
1544 free(pFont->info.props);
1545 }
1546 DestroyFontRec(pFont);
1547 }
1548}
1549
1550
1551/* Unload a font */
1552
1553static void
1554FreeTypeUnloadXFont(FontPtr pFont)
1555{
1556 MUMBLE("Unloading\n");
1557 FreeTypeFreeXFont(pFont, 1);
1558}
1559
1560/* Add the font properties, including the Font name, the XLFD
1561 properties, some strings from the font, and various typographical
1562 data. We only provide data readily available in the tables in the
1563 font for now, altough FIGURE_WIDTH would be a good idea as it is
1564 used by Xaw. */
1565
1566static int
1567FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
1568 char *fontname, int rawAverageWidth, Bool font_properties)
1569{
1570 int i, j, maxprops;
1571 char *sp, *ep, val[MAXFONTNAMELEN1024], *vp;
1572 FTFacePtr face;
1573 FTInstancePtr instance;
1574 FTNormalisedTransformationPtr trans;
1575 int upm;
1576 TT_OS2 *os2;
1577 TT_Postscript *post;
1578 PS_FontInfoRec t1info_rec, *t1info;
1579 int xlfdProps = 0;
1580 int ftrc;
1581
1582 instance = font->instance;
1583 face = instance->face;
1584 trans = &instance->transformation;
1585 upm = face->face->units_per_EM;
1586 if(upm == 0) {
1587 /* Work around FreeType bug */
1588 upm = WORK_AROUND_UPM2048;
1589 }
1590
1591 os2 = FT_Get_Sfnt_Table(face->face, ft_sfnt_os2);
1592 post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
1593 ftrc = FT_Get_PS_Font_Info(face->face, &t1info_rec);
1594 if(ftrc == 0)
1595 t1info = &t1info_rec;
1596 else
1597 t1info = NULL((void*)0);
1598
1599 if(t1info) {
1600 os2 = NULL((void*)0);
1601 post = NULL((void*)0);
1602 }
1603
1604 info->nprops = 0; /* in case we abort */
1605
1606 strcpy(val, fontname)__builtin___strcpy_chk (val, fontname, __builtin_object_size (
val, 2 > 1 ? 1 : 0))
;
1607 if(FontParseXLFDName(val, vals, FONT_XLFD_REPLACE_VALUE3)) {
1608 xlfdProps = 1;
1609 } else {
1610 MUMBLE("Couldn't parse XLFD\n");
1611 xlfdProps = 0;
1612 }
1613
1614 maxprops=
1615 1 + /* NAME */
1616 (xlfdProps ? 14 : 0) + /* from XLFD */
1617 5 +
1618 ( !face->bitmap ? 3 : 0 ) + /* raw_av,raw_asc,raw_dec */
1619 ( font_properties ? 2 : 0 ) + /* asc,dec */
1620 ( (font_properties && os2) ? 6 : 0 ) +
1621 ( (font_properties && (post || t1info)) ? 3 : 0 ) +
1622 2; /* type */
1623
1624 info->props = malloc(maxprops * sizeof(FontPropRec));
1625 if(info->props == NULL((void*)0))
1626 return AllocError80;
1627
1628 info->isStringProp = malloc(maxprops);
1629 if(info->isStringProp == NULL((void*)0)) {
1630 free(info->props);
1631 return AllocError80;
1632 }
1633
1634 memset((char *)info->isStringProp, 0, maxprops)__builtin___memset_chk ((char *)info->isStringProp, 0, maxprops
, __builtin_object_size ((char *)info->isStringProp, 0))
;
1635
1636 i = 0;
1637
1638 info->props[i].name = MakeAtom("FONT", 4, TRUE1);
1639 info->props[i].value = MakeAtom(val, strlen(val), TRUE1);
1640 info->isStringProp[i] = 1;
1641 i++;
1642
1643 if(*val && *(sp = val + 1)) {
1644 for (j = 0, sp = val + 1; j < 14; j++) {
1645 if (j == 13)
1646 /* Handle the case of the final field containing a subset
1647 specification. */
1648 for (ep = sp; *ep && *ep != '['; ep++);
1649 else
1650 for (ep = sp; *ep && *ep != '-'; ep++);
1651
1652 info->props[i].name =
1653 MakeAtom(xlfd_props[j], strlen(xlfd_props[j]), TRUE1);
1654
1655 switch(j) {
1656 case 6: /* pixel size */
1657 info->props[i].value =
1658 (int)(fabs(vals->pixel_matrix[3]) + 0.5);
1659 i++;
1660 break;
1661 case 7: /* point size */
1662 info->props[i].value =
1663 (int)(fabs(vals->point_matrix[3])*10.0 + 0.5);
1664 i++;
1665 break;
1666 case 8: /* resolution x */
1667 info->props[i].value = vals->x;
1668 i++;
1669 break;
1670 case 9: /* resolution y */
1671 info->props[i].value = vals->y;
1672 i++;
1673 break;
1674 case 11: /* average width */
1675 info->props[i].value = vals->width;
1676 i++;
1677 break;
1678 default: /* a string */
1679 info->props[i].value = MakeAtom(sp, ep - sp, TRUE1);
1680 info->isStringProp[i] = 1;
1681 i++;
1682 }
1683 sp = ++ep;
1684 }
1685 }
1686
1687 info->props[i].name = MakeAtom("RAW_PIXEL_SIZE", 14, TRUE1);
1688 info->props[i].value = 1000;
1689 i++;
1690
1691 info->props[i].name = MakeAtom("RAW_POINT_SIZE", 14, TRUE1);
1692 info->props[i].value = (long)(72270.0 / (double)vals->y + .5);
1693 i++;
1694
1695 if(!face->bitmap) {
1696 info->props[i].name = MakeAtom("RAW_AVERAGE_WIDTH", 17, TRUE1);
1697 info->props[i].value = rawAverageWidth;
1698 i++;
1699 }
1700
1701 if ( font_properties ) {
1702 info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE1);
1703 info->props[i].value = info->fontAscent;
1704 i++;
1705 }
1706
1707 if(!face->bitmap) {
1708 info->props[i].name = MakeAtom("RAW_ASCENT", 10, TRUE1);
1709 info->props[i].value =
1710 ((double)face->face->ascender/(double)upm*1000.0);
1711 i++;
1712 }
1713
1714 if ( font_properties ) {
1715 info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE1);
1716 info->props[i].value = info->fontDescent;
1717 i++;
1718 }
1719
1720 if(!face->bitmap) {
1721 info->props[i].name = MakeAtom("RAW_DESCENT", 11, TRUE1);
1722 info->props[i].value =
1723 -((double)face->face->descender/(double)upm*1000.0);
1724 i++;
1725 }
1726
1727 j = FTGetEnglishName(face->face, TT_NAME_ID_COPYRIGHT0,
1728 val, MAXFONTNAMELEN1024);
1729 vp = val;
1730 if (j < 0) {
1731 if(t1info && t1info->notice) {
1732 vp = t1info->notice;
1733 j = strlen(vp);
1734 }
1735 }
1736 if(j > 0) {
1737 info->props[i].name = MakeAtom("COPYRIGHT", 9, TRUE1);
1738 info->props[i].value = MakeAtom(vp, j, TRUE1);
1739 info->isStringProp[i] = 1;
1740 i++;
1741 }
1742
1743 j = FTGetEnglishName(face->face, TT_NAME_ID_FULL_NAME4,
1744 val, MAXFONTNAMELEN1024);
1745 vp = val;
1746 if (j < 0) {
1747 if(t1info && t1info->full_name) {
1748 vp = t1info->full_name;
1749 j = strlen(vp);
1750 }
1751 }
1752 if(j > 0) {
1753 info->props[i].name = MakeAtom("FACE_NAME", 9, TRUE1);
1754 info->props[i].value = MakeAtom(vp, j, TRUE1);
1755 info->isStringProp[i] = 1;
1756 i++;
1757 }
1758
1759 vp = (char *)FT_Get_Postscript_Name(face->face);
1760 if (vp) {
1761 j = strlen(vp);
1762 } else {
1763 j = -1;
1764 }
1765 if (j < 0) {
1766 j = FTGetEnglishName(face->face, TT_NAME_ID_PS_NAME6,
1767 val, MAXFONTNAMELEN1024);
1768 vp = val;
1769 }
1770 if (j < 0) {
1771 if(t1info && t1info->full_name) {
1772 vp = t1info->full_name;
1773 j = strlen(vp);
1774 }
1775 }
1776 if(j > 0) {
1777 info->props[i].name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, TRUE1);
1778 info->props[i].value = MakeAtom(vp, j, TRUE1);
1779 info->isStringProp[i] = 1;
1780 i++;
1781 }
1782
1783 /* These macros handle the case of a diagonal matrix. They convert
1784 FUnits into pixels. */
1785#define TRANSFORM_FUNITS_X(xval) \
1786 ((int) \
1787 floor( ((double)(xval)/(double)upm) * (double)vals->pixel_matrix[0] + 0.5 ) )
1788
1789#define TRANSFORM_FUNITS_Y(yval) \
1790 ((int) \
1791 floor( ((double)(yval)/(double)upm) * (double)vals->pixel_matrix[3] + 0.5 ) )
1792
1793 /* In what follows, we assume the matrix is diagonal. In the rare
1794 case when it is not, the values will be somewhat wrong. */
1795
1796 if( font_properties && os2 ) {
1797 info->props[i].name = MakeAtom("SUBSCRIPT_SIZE",14,TRUE1);
1798 info->props[i].value =
1799 TRANSFORM_FUNITS_Y(os2->ySubscriptYSize);
1800 i++;
1801 info->props[i].name = MakeAtom("SUBSCRIPT_X",11,TRUE1);
1802 info->props[i].value =
1803 TRANSFORM_FUNITS_X(os2->ySubscriptXOffset);
1804 i++;
1805 info->props[i].name = MakeAtom("SUBSCRIPT_Y",11,TRUE1);
1806 info->props[i].value =
1807 TRANSFORM_FUNITS_Y(os2->ySubscriptYOffset);
1808 i++;
1809 info->props[i].name = MakeAtom("SUPERSCRIPT_SIZE",16,TRUE1);
1810 info->props[i].value =
1811 TRANSFORM_FUNITS_Y(os2->ySuperscriptYSize);
1812 i++;
1813 info->props[i].name = MakeAtom("SUPERSCRIPT_X",13,TRUE1);
1814 info->props[i].value =
1815 TRANSFORM_FUNITS_X(os2->ySuperscriptXOffset);
1816 i++;
1817 info->props[i].name = MakeAtom("SUPERSCRIPT_Y",13,TRUE1);
1818 info->props[i].value =
1819 TRANSFORM_FUNITS_Y(os2->ySuperscriptYOffset);
1820 i++;
1821 }
1822
1823 if( font_properties && (post || t1info) ) {
1824 int underlinePosition, underlineThickness;
1825
1826 /* Raw underlineposition counts upwards,
1827 but UNDERLINE_POSITION counts downwards. */
1828 if(post) {
1829 underlinePosition = TRANSFORM_FUNITS_Y(-post->underlinePosition);
1830 underlineThickness = TRANSFORM_FUNITS_Y(post->underlineThickness);
1831 } else {
1832 underlinePosition =
1833 TRANSFORM_FUNITS_Y(-t1info->underline_position);
1834 underlineThickness =
1835 TRANSFORM_FUNITS_Y(t1info->underline_thickness);
1836 }
1837 if(underlineThickness <= 0)
1838 underlineThickness = 1;
1839
1840 info->props[i].name = MakeAtom("UNDERLINE_THICKNESS",19,TRUE1);
1841 info->props[i].value = underlineThickness;
1842 i++;
1843
1844 info->props[i].name = MakeAtom("UNDERLINE_POSITION",18,TRUE1);
1845
1846 info->props[i].value = underlinePosition;
1847
1848 i++;
1849
1850 /* The italic angle is often unreliable for Type 1 fonts */
1851 if(post && trans->matrix.xx == trans->matrix.yy) {
1852 info->props[i].name = MakeAtom("ITALIC_ANGLE",12,TRUE1);
1853 info->props[i].value =
1854 /* Convert from TT_Fixed to
1855 64th of a degree counterclockwise from 3 o'clock */
1856 90*64+(post->italicAngle >> 10);
1857 i++;
1858 }
1859#undef TRANSFORM_FUNITS_X
1860#undef TRANSFORM_FUNITS_Y
1861 }
1862
1863 info->props[i].name = MakeAtom("FONT_TYPE", 9, TRUE1);
1864 vp = (char *)FT_Get_X11_Font_Format(face->face);
1865 info->props[i].value = MakeAtom(vp, strlen(vp), TRUE1);
1866 info->isStringProp[i] = 1;
1867 i++;
1868
1869 info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE1);
1870 info->props[i].value = MakeAtom("FreeType", 8, TRUE1);
1871 info->isStringProp[i] = 1;
1872 i++;
1873
1874 info->nprops = i;
1875 return Successful85;
1876}
1877
1878static int
1879ft_get_index(unsigned code, FTFontPtr font, unsigned *idx)
1880{
1881
1882 /* As a special case, we pass 0 even when it is not in the ranges;
1883 this will allow for the default glyph, which should exist in any
1884 TrueType font. */
1885
1886 /* This is not required...
1887 if(code > 0 && font->nranges) {
1888 int i;
1889 for(i = 0; i < font->nranges; i++)
1890 if((code >=
1891 font->ranges[i].min_char_low+
1892 (font->ranges[i].min_char_high<<8)) &&
1893 (code <=
1894 font->ranges[i].max_char_low +
1895 (font->ranges[i].max_char_high<<8)))
1896 break;
1897 if(i == font->nranges) {
1898 *idx = font->zero_idx;
1899 return -1;
1900 }
1901 }
1902 */
1903 if( font->info ) {
1904 if( !( font->info->firstCol <= (code & 0x000ff) &&
1905 (code & 0x000ff) <= font->info->lastCol &&
1906 font->info->firstRow <= (code >> 8) &&
1907 (code >> 8) <= font->info->lastRow ) ) {
1908 *idx = font->zero_idx;
1909 /* Error: The code has not been parsed in ft_compute_bounds()!
1910 We should not return any metrics. */
1911 return -1;
1912 }
1913 }
1914
1915 *idx = FTRemap(font->instance->face->face, &font->mapping, code);
1916
1917 return 0;
1918}
1919
1920static int
1921FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font)
1922{
1923 unsigned idx = 0;
1924 int xrc;
1925
1926#ifdef X_ACCEPTS_NO_SUCH_CHAR
1927 if( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
1928 *g = NULL((void*)0);
1929 flags &= ~FT_FORCE_CONSTANT_SPACING0x08;
1930 /* if( font->instance->spacing != FT_CHARCELL ) */
1931 return Successful85;
1932 }
1933#else
1934 if( ft_get_index(code,font,&idx) ) {
1935 /* The code has not been parsed! */
1936 *g = NULL((void*)0);
1937 flags &= ~FT_FORCE_CONSTANT_SPACING0x08;
1938 }
1939#endif
1940
1941 xrc = FreeTypeInstanceGetGlyph(idx, flags, g, font->instance);
1942 if( xrc == Successful85 && *g != NULL((void*)0) )
1943 return Successful85;
1944 if( font->zero_idx != idx ) {
1945 xrc = FreeTypeInstanceGetGlyph(font->zero_idx, flags, g, font->instance);
1946 if( xrc == Successful85 && *g != NULL((void*)0) )
1947 return Successful85;
1948 }
1949 return FreeTypeInstanceGetGlyph(font->zero_idx, flags|FT_GET_DUMMY0x04, g, font->instance);
1950}
1951
1952static int
1953FreeTypeFontGetGlyphMetrics(unsigned code, int flags, xCharInfo **metrics, FTFontPtr font)
1954{
1955 unsigned idx = 0;
1956 int xrc;
1957
1958#ifdef X_ACCEPTS_NO_SUCH_CHAR
1959 if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
1960 *metrics = NULL((void*)0);
1961 flags &= ~FT_FORCE_CONSTANT_SPACING0x08;
1962 /* if( font->instance->spacing != FT_CHARCELL ) */
1963 return Successful85;
1964 }
1965#else
1966 if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
1967 /* The code has not been parsed! */
1968 *metrics = NULL((void*)0);
1969 flags &= ~FT_FORCE_CONSTANT_SPACING0x08;
1970 }
1971#endif
1972
1973 xrc = FreeTypeInstanceGetGlyphMetrics(idx, flags, metrics, font->instance);
1974 if( xrc == Successful85 && *metrics != NULL((void*)0) )
1975 return Successful85;
1976 if( font->zero_idx != idx ) {
1977 xrc = FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags,
1978 metrics, font->instance);
1979 if( xrc == Successful85 && *metrics != NULL((void*)0) )
1980 return Successful85;
1981 }
1982 return FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags|FT_GET_DUMMY0x04, metrics, font->instance);
1983}
1984
1985/*
1986 * restrict code range
1987 *
1988 * boolean for the numeric zone:
1989 * results = results & (ranges[0] | ranges[1] | ... ranges[nranges-1])
1990 */
1991
1992static void
1993restrict_code_range(unsigned short *refFirstCol,
1994 unsigned short *refFirstRow,
1995 unsigned short *refLastCol,
1996 unsigned short *refLastRow,
1997 fsRange const *ranges, int nRanges)
1998{
1999 if (nRanges) {
2000 int minCol = 256, minRow = 256, maxCol = -1, maxRow = -1;
2001 fsRange const *r = ranges;
2002 int i;
2003
2004 for (i=0; i<nRanges; i++) {
2005 if (r->min_char_high != r->max_char_high) {
2006 minCol = 0x00;
2007 maxCol = 0xff;
2008 } else {
2009 if (minCol > r->min_char_low)
2010 minCol = r->min_char_low;
2011 if (maxCol < r->max_char_low)
2012 maxCol = r->max_char_low;
2013 }
2014 if (minRow > r->min_char_high)
2015 minRow = r->min_char_high;
2016 if (maxRow < r->max_char_high)
2017 maxRow = r->max_char_high;
2018 r++;
2019 }
2020
2021 if (minCol > *refLastCol)
2022 *refFirstCol = *refLastCol;
2023 else if (minCol > *refFirstCol)
2024 *refFirstCol = minCol;
2025
2026 if (maxCol < *refFirstCol)
2027 *refLastCol = *refFirstCol;
2028 else if (maxCol < *refLastCol)
2029 *refLastCol = maxCol;
2030
2031 if (minRow > *refLastRow) {
2032 *refFirstRow = *refLastRow;
2033 *refFirstCol = *refLastCol;
2034 } else if (minRow > *refFirstRow)
2035 *refFirstRow = minRow;
2036
2037 if (maxRow < *refFirstRow) {
2038 *refLastRow = *refFirstRow;
2039 *refLastCol = *refFirstCol;
2040 } else if (maxRow < *refLastRow)
2041 *refLastRow = maxRow;
2042 }
2043}
2044
2045
2046static int
2047restrict_code_range_by_str(int count,unsigned short *refFirstCol,
2048 unsigned short *refFirstRow,
2049 unsigned short *refLastCol,
2050 unsigned short *refLastRow,
2051 char const *str)
2052{
2053 int nRanges = 0;
2054 int result = 0;
2055 fsRange *ranges = NULL((void*)0), *oldRanges;
2056 char const *p, *q;
2057
2058 p = q = str;
2059 for (;;) {
2060 int minpoint=0, maxpoint=65535;
2061 long val;
2062
2063 /* skip comma and/or space */
2064 while (',' == *p || isspace(*p))
2065 p++;
2066
2067 /* begin point */
2068 if ('-' != *p) {
2069 val = strtol(p, (char **)&q, 0);
2070 if (p == q)
2071 /* end or illegal */
2072 break;
2073 if (val<0 || val>65535) {
2074 /* out of zone */
2075 break;
2076 }
2077 minpoint = val;
2078 p=q;
2079 }
2080
2081 /* skip space */
2082 while (isspace(*p))
2083 p++;
2084
2085 if (',' != *p && '\0' != *p) {
2086 /* contiune */
2087 if ('-' == *p)
2088 /* hyphon */
2089 p++;
2090 else
2091 /* end or illegal */
2092 break;
2093
2094 /* skip space */
2095 while (isspace(*p))
2096 p++;
2097
2098 val = strtol(p, (char **)&q, 0);
2099 if (p != q) {
2100 if (val<0 || val>65535)
2101 break;
2102 maxpoint = val;
2103 } else if (',' != *p && '\0' != *p)
2104 /* end or illegal */
2105 break;
2106 p=q;
2107 } else
2108 /* comma - single code */
2109 maxpoint = minpoint;
2110
2111 if ( count <= 0 && minpoint>maxpoint ) {
2112 int tmp;
2113 tmp = minpoint;
2114 minpoint = maxpoint;
2115 maxpoint = tmp;
2116 }
2117
2118 /* add range */
2119#if 0
2120 fprintf(stderr__stderrp, "zone: 0x%04X - 0x%04X\n", minpoint, maxpoint);
2121 fflush(stderr__stderrp);
2122#endif
2123 nRanges++;
2124 oldRanges = ranges;
2125 ranges = realloc(ranges, nRanges*sizeof(*ranges));
2126 if (NULL((void*)0) == ranges) {
2127 free(oldRanges);
2128 break;
2129 }
2130 else {
2131 fsRange *r = ranges+nRanges-1;
2132
2133 r->min_char_low = minpoint & 0xff;
2134 r->max_char_low = maxpoint & 0xff;
2135 r->min_char_high = (minpoint>>8) & 0xff;
2136 r->max_char_high = (maxpoint>>8) & 0xff;
2137 }
2138 }
2139
2140 if (ranges) {
2141 if ( count <= 0 ) {
2142 restrict_code_range(refFirstCol, refFirstRow, refLastCol, refLastRow,
2143 ranges, nRanges);
2144 }
2145 else {
2146 int i;
2147 fsRange *r;
2148 for ( i=0 ; i<nRanges ; i++ ) {
2149 if ( count <= i ) break;
2150 r = ranges+i;
2151 refFirstCol[i] = r->min_char_low;
2152 refLastCol[i] = r->max_char_low;
2153 refFirstRow[i] = r->min_char_high;
2154 refLastRow[i] = r->max_char_high;
2155 }
2156 result=i;
2157 }
2158 free(ranges);
2159 }
2160 return result;
2161}
2162
2163/* *face_number and *spacing are initialized but *load_flags is NOT. */
2164static int
2165FreeTypeSetUpTTCap( char *fileName, FontScalablePtr vals,
2166 char **dynStrRealFileName, char **dynStrFTFileName,
2167 struct TTCapInfo *ret, int *face_number, FT_Int32 *load_flags,
2168 int *spacing, Bool *font_properties, char **dynStrTTCapCodeRange )
2169{
2170 int result = Successful85;
2171 SDynPropRecValList listPropRecVal;
2172 SPropRecValContainer contRecValue;
2173 Bool hinting=True(-1);
2174 Bool isEmbeddedBitmap = True(-1);
2175 Bool alwaysEmbeddedBitmap = False(0);
2176 int pixel = vals->pixel;
2177
2178 *font_properties=True(-1);
2179 *dynStrRealFileName=NULL((void*)0);
2180 *dynStrFTFileName=NULL((void*)0);
2181 *dynStrTTCapCodeRange=NULL((void*)0);
2182
2183 if (SPropRecValList_new(&listPropRecVal)) {
2184 return AllocError80;
2185 }
2186
2187 {
2188 int len = strlen(fileName);
2189 char *capHead = NULL((void*)0);
2190 {
2191 /* font cap */
2192 char *p1=NULL((void*)0), *p2=NULL((void*)0);
2193
2194 p1=strrchr(fileName, '/');
2195 if ( p1 == NULL((void*)0) ) p1 = fileName;
2196 else p1++;
2197 if (NULL((void*)0) != (p2=strrchr(p1, ':'))) {
2198 /* colon exist in the right side of slash. */
2199 int dirLen = p1-fileName;
2200 int baseLen = fileName+len - p2 -1;
2201
2202 *dynStrRealFileName = malloc(dirLen+baseLen+1);
2203 if( *dynStrRealFileName == NULL((void*)0) ) {
2204 result = AllocError80;
2205 goto quit;
2206 }
2207 if ( 0 < dirLen )
2208 memcpy(*dynStrRealFileName, fileName, dirLen)__builtin___memcpy_chk (*dynStrRealFileName, fileName, dirLen
, __builtin_object_size (*dynStrRealFileName, 0))
;
2209 strcpy(*dynStrRealFileName+dirLen, p2+1)__builtin___strcpy_chk (*dynStrRealFileName+dirLen, p2+1, __builtin_object_size
(*dynStrRealFileName+dirLen, 2 > 1 ? 1 : 0))
;
2210 capHead = p1;
2211 } else {
2212 *dynStrRealFileName = strdup(fileName);
2213 if( *dynStrRealFileName == NULL((void*)0) ) {
2214 result = AllocError80;
2215 goto quit;
2216 }
2217 }
2218 }
2219
2220 /* font cap */
2221 if (capHead) {
2222 if (SPropRecValList_add_by_font_cap(&listPropRecVal,
2223 capHead)) {
2224 result = BadFontPath86;
2225 goto quit;
2226 }
2227 }
2228 }
2229
2230 *face_number=0;
2231 *spacing=0;
2232 ret->autoItalic=0.0;
2233 ret->scaleWidth=1.0;
2234 ret->scaleBBoxWidth = 1.0;
2235 ret->scaleBBoxHeight = 1.0;
2236 ret->doubleStrikeShift = 1;
2237 ret->adjustBBoxWidthByPixel = 0;
2238 ret->adjustLeftSideBearingByPixel = 0;
2239 ret->adjustRightSideBearingByPixel = 0;
2240 ret->flags = 0;
2241 ret->scaleBitmap = 0.0;
2242 ret->forceConstantSpacingBegin = -1;
2243 ret->forceConstantSpacingEnd = -1;
2244 ret->force_c_representative_metrics_char_code = -2;
2245 ret->force_c_scale_b_box_width = 1.0;
2246 ret->force_c_scale_b_box_height = 1.0;
2247 ret->force_c_adjust_width_by_pixel = 0;
2248 ret->force_c_adjust_lsb_by_pixel = 0;
2249 ret->force_c_adjust_rsb_by_pixel = 0;
2250 ret->force_c_scale_lsb = 0.0;
2251 ret->force_c_scale_rsb = 1.0;
2252 /* */
2253 ret->vl_slant=0;
2254 ret->lsbShiftOfBitmapAutoItalic=0;
2255 ret->rsbShiftOfBitmapAutoItalic=0;
2256 /* face number */
2257 {
2258 char *beginptr=NULL((void*)0),*endptr;
2259 if ( SPropRecValList_search_record(&listPropRecVal,
2260 &contRecValue,
2261 "FaceNumber")) {
2262 int lv;
2263 beginptr = SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue);
2264 lv=strtol(beginptr, &endptr, 10);
2265 if ( *beginptr != '\0' && *endptr == '\0' ) {
2266 if ( 0 < lv ) *face_number = lv;
2267 }
2268 }
2269 if( beginptr && 0 < *face_number ) {
2270 char *slash;
2271 *dynStrFTFileName = /* add -> ':'+strlen0+':'+strlen1+'\0' */
2272 malloc(1+strlen(beginptr)+1+strlen(*dynStrRealFileName)+1);
2273 if( *dynStrFTFileName == NULL((void*)0) ){
2274 result = AllocError80;
2275 goto quit;
2276 }
2277 **dynStrFTFileName = '\0';
2278 slash = strrchr(*dynStrRealFileName,'/');
2279 if( slash ) {
2280 char *p;
2281 strcat(*dynStrFTFileName,*dynStrRealFileName)__builtin___strcat_chk (*dynStrFTFileName, *dynStrRealFileName
, __builtin_object_size (*dynStrFTFileName, 2 > 1 ? 1 : 0)
)
;
2282 p = strrchr(*dynStrFTFileName,'/');
2283 p[1] = '\0';
2284 strcat(*dynStrFTFileName,":")__builtin___strcat_chk (*dynStrFTFileName, ":", __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2285 strcat(*dynStrFTFileName,beginptr)__builtin___strcat_chk (*dynStrFTFileName, beginptr, __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2286 strcat(*dynStrFTFileName,":")__builtin___strcat_chk (*dynStrFTFileName, ":", __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2287 strcat(*dynStrFTFileName,slash+1)__builtin___strcat_chk (*dynStrFTFileName, slash+1, __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2288 }
2289 else{
2290 strcat(*dynStrFTFileName,":")__builtin___strcat_chk (*dynStrFTFileName, ":", __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2291 strcat(*dynStrFTFileName,beginptr)__builtin___strcat_chk (*dynStrFTFileName, beginptr, __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2292 strcat(*dynStrFTFileName,":")__builtin___strcat_chk (*dynStrFTFileName, ":", __builtin_object_size
(*dynStrFTFileName, 2 > 1 ? 1 : 0))
;
2293 strcat(*dynStrFTFileName,*dynStrRealFileName)__builtin___strcat_chk (*dynStrFTFileName, *dynStrRealFileName
, __builtin_object_size (*dynStrFTFileName, 2 > 1 ? 1 : 0)
)
;
2294 }
2295 }
2296 else{
2297 *dynStrFTFileName = strdup(*dynStrRealFileName);
2298 if( *dynStrFTFileName == NULL((void*)0) ){
2299 result = AllocError80;
2300 goto quit;
2301 }
2302 }
2303 }
2304 /*
2305 fprintf(stderr,"[Filename:%s]\n",fileName);
2306 fprintf(stderr,"[RealFilename:%s]\n",*dynStrRealFileName);
2307 fprintf(stderr,"[FTFilename:%s]\n",*dynStrFTFileName);
2308 */
2309 /* slant control */
2310 if (SPropRecValList_search_record(&listPropRecVal,
2311 &contRecValue,
2312 "AutoItalic"))
2313 ret->autoItalic = SPropContainer_value_dbl(contRecValue)((contRecValue)->uValue.doubleValue);
2314 /* hinting control */
2315 if (SPropRecValList_search_record(&listPropRecVal,
2316 &contRecValue,
2317 "Hinting"))
2318 hinting = SPropContainer_value_bool(contRecValue)((contRecValue)->uValue.boolValue);
2319 /* scaling */
2320 if (SPropRecValList_search_record(&listPropRecVal,
2321 &contRecValue,
2322 "ScaleWidth")) {
2323 ret->scaleWidth = SPropContainer_value_dbl(contRecValue)((contRecValue)->uValue.doubleValue);
2324 if (ret->scaleWidth<=0.0) {
2325 fprintf(stderr__stderrp, "ScaleWitdh needs plus.\n");
2326 result = BadFontName83;
2327 goto quit;
2328 }
2329 }
2330 /* bbox adjustment */
2331 if (SPropRecValList_search_record(&listPropRecVal,
2332 &contRecValue,
2333 "ScaleBBoxWidth")) {
2334 /* Scaling to Bounding Box Width */
2335 int lv;
2336 char *endptr,*beginptr;
2337 double v,scaleBBoxWidth=1.0,scaleBBoxHeight=1.0;
2338 beginptr = SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue);
2339 do {
2340 if ( strlen(beginptr) < 1 ) break;
2341 v=strtod(beginptr, &endptr);
2342 if ( endptr!=beginptr ) {
2343 scaleBBoxWidth = v;
2344 }
2345 if ( *endptr != ';' && *endptr != ',' ) break;
2346 if ( *endptr == ',' ) {
2347 beginptr=endptr+1;
2348 v=strtod(beginptr, &endptr);
2349 if ( endptr!=beginptr ) {
2350 scaleBBoxHeight = v;
2351 }
2352 }
2353 if ( *endptr != ';' && *endptr != ',' ) break;
2354 beginptr=endptr+1;
2355 lv=strtol(beginptr, &endptr, 10);
2356 if ( endptr!=beginptr ) {
2357 ret->adjustBBoxWidthByPixel = lv;
2358 }
2359 if ( *endptr != ',' ) break;
2360 beginptr=endptr+1;
2361 lv=strtol(beginptr, &endptr, 10);
2362 if ( endptr!=beginptr ) {
2363 ret->adjustLeftSideBearingByPixel = lv;
2364 }
2365 if ( *endptr != ',' ) break;
2366 beginptr=endptr+1;
2367 lv=strtol(beginptr, &endptr, 10);
2368 if ( endptr!=beginptr ) {
2369 ret->adjustRightSideBearingByPixel = lv;
2370 }
2371 } while ( 0 );
2372 if (scaleBBoxWidth<=0.0) {
2373 fprintf(stderr__stderrp, "ScaleBBoxWitdh needs plus.\n");
2374 result = BadFontName83;
2375 goto quit;
2376 }
2377 if (scaleBBoxHeight<=0.0) {
2378 fprintf(stderr__stderrp, "ScaleBBoxHeight needs plus.\n");
2379 result = BadFontName83;
2380 goto quit;
2381 }
2382 ret->scaleBBoxWidth = scaleBBoxWidth;
2383 ret->scaleBBoxHeight = scaleBBoxHeight;
2384 }
2385 /* spacing */
2386 if (SPropRecValList_search_record(&listPropRecVal,
2387 &contRecValue,
2388 "ForceSpacing")) {
2389 char *strSpace = SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue);
2390 Bool err = False(0);
2391 if (1 != strlen(strSpace))
2392 err = True(-1);
2393 else
2394 switch (strSpace[0]) {
2395 case 'M':
2396 ret->flags |= TTCAP_MONO_CENTER0x0800;
2397 *spacing = 'm';
2398 break;
2399 case 'm':
2400 case 'p':
2401 case 'c':
2402 *spacing = strSpace[0];
2403 break;
2404 default:
2405 err = True(-1);
2406 }
2407 if (err) {
2408 result = BadFontName83;
2409 goto quit;
2410 }
2411 }
2412 /* doube striking */
2413 if (SPropRecValList_search_record(&listPropRecVal,
2414 &contRecValue,
2415 "DoubleStrike")) {
2416 /* Set or Reset Auto Bold Flag */
2417 char *strDoubleStrike = SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue);
2418 Bool err = False(0);
2419 if ( 0 < strlen(strDoubleStrike) ) {
2420 switch (strDoubleStrike[0]) {
2421 case 'm':
2422 case 'M':
2423 case 'l':
2424 case 'L':
2425 ret->flags |= TTCAP_DOUBLE_STRIKE0x0001;
2426 ret->flags |= TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT0x0002;
2427 break;
2428 case 'y':
2429 case 'Y':
2430 ret->flags |= TTCAP_DOUBLE_STRIKE0x0001;
2431 break;
2432 case 'n':
2433 case 'N':
2434 ret->flags &= ~TTCAP_DOUBLE_STRIKE0x0001;
2435 ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT0x0002;
2436 ret->flags &= ~TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008;
2437 break;
2438 default:
2439 err = True(-1);
2440 }
2441 if ( err != True(-1) ) {
2442 if ( strDoubleStrike[1] ) {
2443 switch (strDoubleStrike[1]) {
2444 case 'b':
2445 case 'B':
2446 case 'p':
2447 case 'P':
2448 case 'y':
2449 case 'Y':
2450 ret->flags |= TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008;
2451 break;
2452 default:
2453 break;
2454 }
2455 }
2456 do {
2457 char *comma_ptr=strchr(strDoubleStrike,';');
2458 if ( !comma_ptr ) comma_ptr=strchr(strDoubleStrike,',');
2459 if ( !comma_ptr ) break;
2460 if ( comma_ptr[1] ) {
2461 char *endptr;
2462 int mkboldMaxPixel;
2463 mkboldMaxPixel=strtol(comma_ptr+1, &endptr, 10);
2464 if ( endptr != comma_ptr+1 && mkboldMaxPixel <= pixel ) {
2465 ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT0x0002;
2466 }
2467 }
2468 comma_ptr=strchr(comma_ptr+1,',');
2469 if ( !comma_ptr ) break;
2470 if ( comma_ptr[1] ) {
2471 char *endptr;
2472 int max_pixel;
2473 max_pixel=strtol(comma_ptr+1, &endptr, 10);
2474 if ( endptr != comma_ptr+1 && max_pixel <= pixel ) {
2475 if( ret->flags & TTCAP_DOUBLE_STRIKE0x0001 )
2476 ret->doubleStrikeShift += pixel / max_pixel;
2477 }
2478 }
2479 } while(0);
2480 }
2481 }
2482 else
2483 err = True(-1);
2484 if (err) {
2485 result = BadFontName83;
2486 goto quit;
2487 }
2488 }
2489 /* very lazy metrics */
2490 if (SPropRecValList_search_record(&listPropRecVal,
2491 &contRecValue,
2492 "VeryLazyMetrics")){
2493 Bool isVeryLazy = SPropContainer_value_bool(contRecValue)((contRecValue)->uValue.boolValue);
2494 ret->flags |= TTCAP_DISABLE_DEFAULT_VERY_LAZY0x0020;
2495 if( isVeryLazy == True(-1) )
2496 ret->flags |= TTCAP_IS_VERY_LAZY0x0010;
2497 else
2498 ret->flags &= ~TTCAP_IS_VERY_LAZY0x0010;
2499 }
2500 /* embedded bitmap */
2501 if (SPropRecValList_search_record(&listPropRecVal,
2502 &contRecValue,
2503 "EmbeddedBitmap")) {
2504 char *strEmbeddedBitmap = SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue);
2505 Bool err = False(0);
2506 if ( 1 == strlen(strEmbeddedBitmap) ) {
2507 switch (strEmbeddedBitmap[0]) {
2508 case 'y':
2509 case 'Y':
2510 isEmbeddedBitmap = True(-1);
2511 alwaysEmbeddedBitmap = True(-1);
2512 break;
2513 case 'u':
2514 case 'U':
2515 isEmbeddedBitmap = True(-1);
2516 alwaysEmbeddedBitmap = False(0);
2517 break;
2518 case 'n':
2519 case 'N':
2520 isEmbeddedBitmap = False(0);
2521 break;
2522 default:
2523 err = True(-1);
2524 }
2525 }
2526 else
2527 err = True(-1);
2528 if (err) {
2529 result = BadFontName83;
2530 goto quit;
2531 }
2532 }
2533 /* scale bitmap */
2534 if((ret->flags & TTCAP_IS_VERY_LAZY0x0010) &&
2535 SPropRecValList_search_record(&listPropRecVal,
2536 &contRecValue,
2537 "VeryLazyBitmapWidthScale")) {
2538 /* Scaling to Bitmap Bounding Box Width */
2539 double scaleBitmapWidth = SPropContainer_value_dbl(contRecValue)((contRecValue)->uValue.doubleValue);
2540
2541 fprintf(stderr__stderrp, "Warning: `bs' option is not required in X-TT version 2.\n");
2542#if 0
2543 if (scaleBitmapWidth<=0.0) {
2544 fprintf(stderr__stderrp, "ScaleBitmapWitdh needs plus.\n");
2545 result = BadFontName83;
2546 goto quit;
2547 }
2548#endif
2549 ret->scaleBitmap = scaleBitmapWidth;
2550 }
2551 /* restriction of the code range */
2552 if (SPropRecValList_search_record(&listPropRecVal,
2553 &contRecValue,
2554 "CodeRange")) {
2555 *dynStrTTCapCodeRange = strdup(SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue));
2556 if( *dynStrTTCapCodeRange == NULL((void*)0) ) {
2557 result = AllocError80;
2558 goto quit;
2559 }
2560 }
2561 /* forceConstantSpacing{Begin,End} */
2562 if ( 1 /* ft->spacing == 'p' */ ){
2563 unsigned short first_col=0,last_col=0x00ff;
2564 unsigned short first_row=0,last_row=0x00ff;
2565 if (SPropRecValList_search_record(&listPropRecVal,
2566 &contRecValue,
2567 "ForceConstantSpacingCodeRange")) {
2568 if ( restrict_code_range_by_str(1,&first_col, &first_row,
2569 &last_col, &last_row,
2570 SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue)) == 1 ) {
2571 ret->forceConstantSpacingBegin = (int)( first_row<<8 | first_col );
2572 ret->forceConstantSpacingEnd = (int)( last_row<<8 | last_col );
2573 if ( ret->forceConstantSpacingBegin <= ret->forceConstantSpacingEnd )
2574 ret->flags &= ~TTCAP_FORCE_C_OUTSIDE0x0400;
2575 else ret->flags |= TTCAP_FORCE_C_OUTSIDE0x0400;
2576 }
2577 }
2578 }
2579 /* */
2580 if ( 1 ){
2581 unsigned short first_col=0, last_col=0x0ff;
2582 unsigned short first_row=0, last_row=0x0ff;
2583 if ( SPropRecValList_search_record(&listPropRecVal,
2584 &contRecValue,
2585 "ForceConstantSpacingMetrics")) {
2586 char *strMetrics;
2587 strMetrics = SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue);
2588 if ( strMetrics ) {
2589 char *comma_ptr,*period_ptr,*semic_ptr;
2590 semic_ptr=strchr(strMetrics,';');
2591 comma_ptr=strchr(strMetrics,',');
2592 period_ptr=strchr(strMetrics,'.');
2593 if ( semic_ptr && comma_ptr )
2594 if ( semic_ptr < comma_ptr ) comma_ptr=NULL((void*)0);
2595 if ( semic_ptr && period_ptr )
2596 if ( semic_ptr < period_ptr ) period_ptr=NULL((void*)0);
2597 if ( !comma_ptr && !period_ptr && strMetrics != semic_ptr ) {
2598 if ( restrict_code_range_by_str(1,&first_col, &first_row,
2599 &last_col, &last_row,
2600 SPropContainer_value_str(contRecValue)((contRecValue)->uValue.dynStringValue)) == 1 ) {
2601 ret->force_c_representative_metrics_char_code =
2602 (int)( first_row<<8 | first_col );
2603 }
2604 }
2605 else {
2606 double v;
2607 char *endptr,*beginptr=strMetrics;
2608 do {
2609 v=strtod(beginptr, &endptr);
2610 if ( endptr!=beginptr ) {
2611 ret->force_c_scale_b_box_width = v;
2612 }
2613 if ( *endptr != ',' ) break;
2614 beginptr=endptr+1;
2615 v=strtod(beginptr, &endptr);
2616 if ( endptr!=beginptr ) {
2617 ret->force_c_scale_lsb = v;
2618 ret->flags |= TTCAP_FORCE_C_LSB_FLAG0x0100;
2619 }
2620 if ( *endptr != ',' ) break;
2621 beginptr=endptr+1;
2622 v=strtod(beginptr, &endptr);
2623 if ( endptr!=beginptr ) {
2624 ret->force_c_scale_rsb = v;
2625 ret->flags |= TTCAP_FORCE_C_RSB_FLAG0x0200;
2626 }
2627 if ( *endptr != ',' ) break;
2628 beginptr=endptr+1;
2629 v=strtod(beginptr, &endptr);
2630 if ( endptr!=beginptr ) {
2631 ret->force_c_scale_b_box_height = v;
2632 }
2633 } while (0);
2634 }
2635 if ( semic_ptr ) {
2636 int lv;
2637 char *endptr,*beginptr=semic_ptr+1;
2638 do {
2639 lv=strtol(beginptr, &endptr, 10);
2640 if ( endptr!=beginptr ) {
2641 ret->force_c_adjust_width_by_pixel=lv;
2642 }
2643 if ( *endptr != ',' ) break;
2644 beginptr=endptr+1;
2645 lv=strtol(beginptr, &endptr, 10);
2646 if ( endptr!=beginptr ) {
2647 ret->force_c_adjust_lsb_by_pixel=lv;
2648 }
2649 if ( *endptr != ',' ) break;
2650 beginptr=endptr+1;
2651 lv=strtol(beginptr, &endptr, 10);
2652 if ( endptr!=beginptr ) {
2653 ret->force_c_adjust_rsb_by_pixel=lv;
2654 }
2655 } while (0);
2656 }
2657 }
2658 }
2659 }
2660
2661 if (SPropRecValList_search_record(&listPropRecVal,
2662 &contRecValue,
2663 "FontProperties")) {
2664 /* Set or Reset the Flag of FontProperties */
2665 *font_properties=SPropContainer_value_bool(contRecValue)((contRecValue)->uValue.boolValue);
2666 }
2667
2668 ret->force_c_scale_b_box_width *= ret->scaleBBoxWidth;
2669 ret->force_c_scale_b_box_height *= ret->scaleBBoxHeight;
2670
2671 ret->force_c_scale_b_box_width *= ret->scaleWidth;
2672 ret->scaleBBoxWidth *= ret->scaleWidth;
2673
2674 ret->force_c_adjust_rsb_by_pixel += ret->adjustRightSideBearingByPixel;
2675 ret->force_c_adjust_lsb_by_pixel += ret->adjustLeftSideBearingByPixel;
2676
2677 /* scaleWidth, scaleBBoxWidth, force_c_scale_b_box_width, force_c_scale_b_box_width */
2678
2679 /* by TTCap */
2680 if( hinting == False(0) ) *load_flags |= FT_LOAD_NO_HINTING0x2;
2681 if( isEmbeddedBitmap == False(0) ) *load_flags |= FT_LOAD_NO_BITMAP0x8;
2682 if( ret->autoItalic != 0 && alwaysEmbeddedBitmap == False(0) )
2683 *load_flags |= FT_LOAD_NO_BITMAP0x8;
2684
2685 quit:
2686 return result;
2687}
2688
2689static int
2690ft_get_trans_from_vals( FontScalablePtr vals, FTNormalisedTransformationPtr trans )
2691{
2692 /* Compute the transformation matrix. We use floating-point
2693 arithmetic for simplicity */
2694
2695 trans->xres = vals->x;
2696 trans->yres = vals->y;
2697
2698 /* This value cannot be 0. */
2699 trans->scale = hypot(vals->point_matrix[2], vals->point_matrix[3]);
2700 trans->nonIdentity = 0;
2701
2702 /* Try to round stuff. We want approximate zeros to be exact zeros,
2703 and if the elements on the diagonal are approximately equal, we
2704 want them equal. We do this to avoid breaking hinting. */
2705 if(DIFFER(vals->point_matrix[0], vals->point_matrix[3])(fabs((vals->point_matrix[0])-(vals->point_matrix[3]))>=
((double)0.001)*fabs(vals->point_matrix[0]))
) {
2706 trans->nonIdentity = 1;
2707 trans->matrix.xx =
2708 (int)((vals->point_matrix[0]*(double)TWO_SIXTEENTH((double)(1<<16)))/trans->scale);
2709 trans->matrix.yy =
2710 (int)((vals->point_matrix[3]*(double)TWO_SIXTEENTH((double)(1<<16)))/trans->scale);
2711 } else {
2712 trans->matrix.xx = trans->matrix.yy =
2713 ((vals->point_matrix[0] + vals->point_matrix[3])/2*
2714 (double)TWO_SIXTEENTH((double)(1<<16)))/trans->scale;
2715 }
2716
2717 if(DIFFER0(vals->point_matrix[1], trans->scale)(fabs(vals->point_matrix[1])>=((double)0.001)*fabs(trans
->scale))
) {
2718 trans->matrix.yx =
2719 (int)((vals->point_matrix[1]*(double)TWO_SIXTEENTH((double)(1<<16)))/trans->scale);
2720 trans->nonIdentity = 1;
2721 } else
2722 trans->matrix.yx = 0;
2723
2724 if(DIFFER0(vals->point_matrix[2], trans->scale)(fabs(vals->point_matrix[2])>=((double)0.001)*fabs(trans
->scale))
) {
2725 trans->matrix.xy =
2726 (int)((vals->point_matrix[2]*(double)TWO_SIXTEENTH((double)(1<<16)))/trans->scale);
2727 trans->nonIdentity = 1;
2728 } else
2729 trans->matrix.xy=0;
2730 return 0;
2731}
2732
2733
2734static int
2735is_fixed_width(FT_Face face)
2736{
2737 PS_FontInfoRec t1info_rec;
2738 int ftrc;
2739
2740 if(FT_IS_FIXED_WIDTH(face)( face->face_flags & ( 1L << 2 ) )) {
2741 return 1;
2742 }
2743
2744 ftrc = FT_Get_PS_Font_Info(face, &t1info_rec);
2745 if(ftrc == 0 && t1info_rec.is_fixed_pitch) {
2746 return 1;
2747 }
2748
2749 return 0;
2750}
2751
2752static int
2753FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
2754 char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
2755 FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
2756 struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
2757 int ttcap_spacing )
2758{
2759 int xrc;
2760 FTNormalisedTransformationRec trans;
2761 int spacing, actual_spacing, zero_code;
2762 long lastCode, firstCode;
2763 TT_Postscript *post;
2764
2765 ft_get_trans_from_vals(vals,&trans);
2766
2767 /* Check for charcell in XLFD */
2768 spacing = FT_PROPORTIONAL0;
2769 if(entry->name.ndashes == 14) {
2770 char *p;
2771 int dashes = 0;
2772 for(p = entry->name.name;
2773 p <= entry->name.name + entry->name.length - 2;
2774 p++) {
2775 if(*p == '-') {
2776 dashes++;
2777 if(dashes == 11) {
2778 if(p[1]=='c' && p[2]=='-')
2779 spacing=FT_CHARCELL2;
2780 else if(p[1]=='m' && p[2]=='-')
2781 spacing=FT_MONOSPACED1;
2782 break;
2783 }
2784 }
2785 }
2786 }
2787 /* by TTCap */
2788 if( ttcap_spacing != 0 ) {
2789 if( ttcap_spacing == 'c' ) spacing=FT_CHARCELL2;
2790 else if( ttcap_spacing == 'm' ) spacing=FT_MONOSPACED1;
2791 else spacing=FT_PROPORTIONAL0;
2792 }
2793
2794 actual_spacing = spacing;
2795 if( spacing == FT_PROPORTIONAL0 ) {
2796 if( is_fixed_width(face->face) )
2797 actual_spacing = FT_MONOSPACED1;
2798 }
2799
2800 if(entry->name.ndashes == 14) {
2801 xrc = FTPickMapping(entry->name.name, entry->name.length, FTFileName,
2802 face->face, &font->mapping);
2803 if (xrc != Successful85)
2804 return xrc;
2805 } else {
2806 xrc = FTPickMapping(0, 0, FTFileName,
2807 face->face, &font->mapping);
2808 if (xrc != Successful85)
2809 return xrc;
2810 }
2811
2812 font->nranges = vals->nranges;
2813 font->ranges = 0;
2814 if(font->nranges) {
2815 font->ranges = malloc(vals->nranges*sizeof(fsRange));
2816 if(font->ranges == NULL((void*)0))
2817 return AllocError80;
2818 memcpy((char*)font->ranges, (char*)vals->ranges,__builtin___memcpy_chk ((char*)font->ranges, (char*)vals->
ranges, vals->nranges*sizeof(fsRange), __builtin_object_size
((char*)font->ranges, 0))
2819 vals->nranges*sizeof(fsRange))__builtin___memcpy_chk ((char*)font->ranges, (char*)vals->
ranges, vals->nranges*sizeof(fsRange), __builtin_object_size
((char*)font->ranges, 0))
;
2820 }
2821
2822 zero_code=-1;
2823 if(info) {
2824 firstCode = 0;
2825 lastCode = 0xFFFFL;
2826 if(!font->mapping.mapping ||
2827 font->mapping.mapping->encoding->row_size == 0) {
2828 /* linear indexing */
2829 lastCode=MIN(lastCode,((lastCode) < (font->mapping.mapping ? font->mapping
.mapping->encoding->size-1 : 0xFF) ? (lastCode) : (font
->mapping.mapping ? font->mapping.mapping->encoding->
size-1 : 0xFF))
2830 font->mapping.mapping ?((lastCode) < (font->mapping.mapping ? font->mapping
.mapping->encoding->size-1 : 0xFF) ? (lastCode) : (font
->mapping.mapping ? font->mapping.mapping->encoding->
size-1 : 0xFF))
2831 font->mapping.mapping->encoding->size-1 :((lastCode) < (font->mapping.mapping ? font->mapping
.mapping->encoding->size-1 : 0xFF) ? (lastCode) : (font
->mapping.mapping ? font->mapping.mapping->encoding->
size-1 : 0xFF))
2832 0xFF)((lastCode) < (font->mapping.mapping ? font->mapping
.mapping->encoding->size-1 : 0xFF) ? (lastCode) : (font
->mapping.mapping ? font->mapping.mapping->encoding->
size-1 : 0xFF))
;
2833 if(font->mapping.mapping && font->mapping.mapping->encoding->first)
2834 firstCode = font->mapping.mapping->encoding->first;
2835 info->firstRow = firstCode/0x100;
2836 info->lastRow = lastCode/0x100;
2837 info->firstCol =
2838 (info->firstRow || info->lastRow) ? 0 : (firstCode & 0xFF);
2839 info->lastCol = info->lastRow ? 0xFF : (lastCode & 0xFF);
2840 if ( firstCode == 0 ) zero_code=0;
2841 } else {
2842 /* matrix indexing */
2843 info->firstRow = font->mapping.mapping->encoding->first;
2844 info->lastRow = MIN(font->mapping.mapping->encoding->size-1,((font->mapping.mapping->encoding->size-1) < (lastCode
/0x100) ? (font->mapping.mapping->encoding->size-1) :
(lastCode/0x100))
2845 lastCode/0x100)((font->mapping.mapping->encoding->size-1) < (lastCode
/0x100) ? (font->mapping.mapping->encoding->size-1) :
(lastCode/0x100))
;
2846 info->firstCol = font->mapping.mapping->encoding->first_col;
2847 info->lastCol = MIN(font->mapping.mapping->encoding->row_size-1,((font->mapping.mapping->encoding->row_size-1) < (
lastCode<0x100?lastCode:0xFF) ? (font->mapping.mapping->
encoding->row_size-1) : (lastCode<0x100?lastCode:0xFF))
2848 lastCode<0x100?lastCode:0xFF)((font->mapping.mapping->encoding->row_size-1) < (
lastCode<0x100?lastCode:0xFF) ? (font->mapping.mapping->
encoding->row_size-1) : (lastCode<0x100?lastCode:0xFF))
;
2849 if( info->firstRow == 0 && info->firstCol == 0 ) zero_code=0;
2850 }
2851
2852 /* firstCode and lastCode are not valid in case of a matrix
2853 encoding */
2854
2855 if( dynStrTTCapCodeRange ) {
2856 restrict_code_range_by_str(0,&info->firstCol, &info->firstRow,
2857 &info->lastCol, &info->lastRow,
2858 dynStrTTCapCodeRange);
2859 }
2860 restrict_code_range(&info->firstCol, &info->firstRow,
2861 &info->lastCol, &info->lastRow,
2862 font->ranges, font->nranges);
2863 }
2864 font->info = info;
2865
2866 /* zero code is frequently used. */
2867 if ( zero_code < 0 ) {
2868 /* The fontenc should have the information of DefaultCh.
2869 But we do not have such a information.
2870 So we cannot but set 0. */
2871 font->zero_idx = 0;
2872 }
2873 else
2874 font->zero_idx = FTRemap(face->face,
2875 &font->mapping, zero_code);
2876
2877 post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
2878
2879#ifdef DEFAULT_VERY_LAZY2
2880 if( !( tmp_ttcap->flags & TTCAP_DISABLE_DEFAULT_VERY_LAZY0x0020 ) )
2881 if( DEFAULT_VERY_LAZY2 <= 1 + info->lastRow - info->firstRow ) {
2882 if( post ){
2883 tmp_ttcap->flags |= TTCAP_IS_VERY_LAZY0x0010;
2884 }
2885 }
2886#endif
2887 /* We should always reset. */
2888 tmp_ttcap->flags &= ~TTCAP_DISABLE_DEFAULT_VERY_LAZY0x0020;
2889
2890 if ( face->bitmap || actual_spacing == FT_CHARCELL2 )
2891 tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY0x0010;
2892 /* "vl=y" is available when TrueType or OpenType only */
2893 if ( !face->bitmap && !(FT_IS_SFNT( face->face )( face->face->face_flags & ( 1L << 3 ) )) )
2894 tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY0x0010;
2895
2896 if( post ) {
2897 if( post->italicAngle != 0 )
2898 tmp_ttcap->vl_slant = -sin( (post->italicAngle/1024./5760.)*1.57079632679489661923 );
2899 /* fprintf(stderr,"angle=%g(%g)\n",tmp_ttcap->vl_slant,(post->italicAngle/1024./5760.)*90); */
2900 }
2901
2902 xrc = FreeTypeOpenInstance(&font->instance, face,
2903 FTFileName, &trans, actual_spacing, bmfmt,
2904 tmp_ttcap, load_flags );
2905 return xrc;
2906}
2907
2908static void
2909adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp)
2910{
2911#define MINMAX(field,ci) \
2912 if (minc->field > (ci)->field) \
2913 minc->field = (ci)->field; \
2914 if (maxc->field < (ci)->field) \
2915 maxc->field = (ci)->field;
2916
2917 MINMAX(ascent, tmp);
2918 MINMAX(descent, tmp);
2919 MINMAX(leftSideBearing, tmp);
2920 MINMAX(rightSideBearing, tmp);
2921 MINMAX(characterWidth, tmp);
2922
2923 if ((INT16)minc->attributes > (INT16)tmp->attributes)
2924 minc->attributes = tmp->attributes;
2925 if ((INT16)maxc->attributes < (INT16)tmp->attributes)
2926 maxc->attributes = tmp->attributes;
2927#undef MINMAX
2928}
2929
2930static void
2931ft_compute_bounds(FTFontPtr font, FontInfoPtr pinfo, FontScalablePtr vals )
2932{
2933 FTInstancePtr instance;
2934 int row, col;
2935 unsigned int c;
2936 xCharInfo minchar, maxchar, *tmpchar = NULL((void*)0);
2937 int overlap, maxOverlap;
2938 long swidth = 0;
2939 long total_width = 0;
2940 int num_cols, num_chars = 0;
2941 int flags, skip_ok = 0;
2942 int force_c_outside ;
2943
2944 instance = font->instance;
2945 force_c_outside = instance->ttcap.flags & TTCAP_FORCE_C_OUTSIDE0x0400;
2946
2947 minchar.ascent = minchar.descent =
2948 minchar.leftSideBearing = minchar.rightSideBearing =
2949 minchar.characterWidth = minchar.attributes = 32767;
2950 maxchar.ascent = maxchar.descent =
2951 maxchar.leftSideBearing = maxchar.rightSideBearing =
2952 maxchar.characterWidth = maxchar.attributes = -32767;
2953 maxOverlap = -32767;
2954
2955 /* Parse all glyphs */
2956 num_cols = 1 + pinfo->lastCol - pinfo->firstCol;
2957 for (row = pinfo->firstRow; row <= pinfo->lastRow; row++) {
2958 if ( skip_ok && tmpchar ) {
2959 if ( !force_c_outside ) {
2960 if ( instance->ttcap.forceConstantSpacingBegin < row<<8
2961 && row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
2962 if (tmpchar->characterWidth) {
2963 num_chars += num_cols;
2964 swidth += ABS(tmpchar->characterWidth)((tmpchar->characterWidth) >= 0 ? (tmpchar->characterWidth
) : -(tmpchar->characterWidth))
*num_cols;
2965 total_width += tmpchar->characterWidth*num_cols;
2966 continue;
2967 }
2968 }
2969 else skip_ok=0;
2970 }
2971 else { /* for GB18030 proportional */
2972 if ( instance->ttcap.forceConstantSpacingBegin < row<<8
2973 || row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
2974 if (tmpchar->characterWidth) {
2975 num_chars += num_cols;
2976 swidth += ABS(tmpchar->characterWidth)((tmpchar->characterWidth) >= 0 ? (tmpchar->characterWidth
) : -(tmpchar->characterWidth))
*num_cols;
2977 total_width += tmpchar->characterWidth*num_cols;
2978 continue;
2979 }
2980 }
2981 else skip_ok=0;
2982 }
2983 }
2984 for (col = pinfo->firstCol; col <= pinfo->lastCol; col++) {
2985 c = row<<8|col;
2986 flags=0;
2987 if ( !force_c_outside ) {
2988 if ( c <= instance->ttcap.forceConstantSpacingEnd
2989 && instance->ttcap.forceConstantSpacingBegin <= c )
2990 flags|=FT_FORCE_CONSTANT_SPACING0x08;
2991 }
2992 else { /* for GB18030 proportional */
2993 if ( c <= instance->ttcap.forceConstantSpacingEnd
2994 || instance->ttcap.forceConstantSpacingBegin <= c )
2995 flags|=FT_FORCE_CONSTANT_SPACING0x08;
2996 }
2997#if 0
2998 fprintf(stderr__stderrp, "comp_bounds: %x ->", c);
2999#endif
3000 if ( skip_ok == 0 || flags == 0 ){
3001 tmpchar=NULL((void*)0);
3002#if 0
3003 fprintf(stderr__stderrp, "%x\n", c);
3004#endif
3005 if( FreeTypeFontGetGlyphMetrics(c, flags, &tmpchar, font) != Successful85 )
3006 continue;
3007 }
3008 if ( !tmpchar ) continue;
3009 adjust_min_max(&minchar, &maxchar, tmpchar);
3010 overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
3011 if (maxOverlap < overlap)
3012 maxOverlap = overlap;
3013
3014 if (!tmpchar->characterWidth)
3015 continue;
3016 num_chars++;
3017 swidth += ABS(tmpchar->characterWidth)((tmpchar->characterWidth) >= 0 ? (tmpchar->characterWidth
) : -(tmpchar->characterWidth))
;
3018 total_width += tmpchar->characterWidth;
3019
3020 if ( flags & FT_FORCE_CONSTANT_SPACING0x08 ) skip_ok=1;
3021 }
3022 }
3023
3024#ifndef X_ACCEPTS_NO_SUCH_CHAR
3025 /* Check code 0 */
3026 if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, 0, &tmpchar, font->instance) != Successful85 || tmpchar == NULL((void*)0))
3027 if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, FT_GET_DUMMY0x04, &tmpchar, font->instance) != Successful85 )
3028 tmpchar = NULL((void*)0);
3029 if ( tmpchar ) {
3030 adjust_min_max(&minchar, &maxchar, tmpchar);
3031 overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
3032 if (maxOverlap < overlap)
3033 maxOverlap = overlap;
3034 }
3035#endif
3036
3037 /* AVERAGE_WIDTH ... 1/10 pixel unit */
3038 if (num_chars > 0) {
3039 swidth = (swidth * 10.0 + num_chars / 2.0) / num_chars;
3040 if (total_width < 0)
3041 swidth = -swidth;
3042 vals->width = swidth;
3043 } else
3044 vals->width = 0;
3045
3046 /*
3047 if (char_width.pixel) {
3048 maxchar.characterWidth = char_width.pixel;
3049 minchar.characterWidth = char_width.pixel;
3050 }
3051 */
3052
3053 pinfo->maxbounds = maxchar;
3054 pinfo->minbounds = minchar;
3055 pinfo->ink_maxbounds = maxchar;
3056 pinfo->ink_minbounds = minchar;
3057 pinfo->maxOverlap = maxOverlap;
3058}
3059
3060static int
3061compute_new_extents( FontScalablePtr vals, double scale, double lsb, double rsb, double desc, double asc,
3062 int *lsb_result, int *rsb_result, int *desc_result, int *asc_result )
3063{
3064#define TRANSFORM_POINT(matrix, x, y, dest) \
3065 ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
3066 (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
3067
3068#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
3069 ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
3070 (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
3071 (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
3072 (asc) < (data)[1] ? (asc) = (data)[1] : 0)
3073 double newlsb, newrsb, newdesc, newasc;
3074 double point[2];
3075
3076 /* Compute new extents for this glyph */
3077 TRANSFORM_POINT(vals->pixel_matrix, lsb, -desc, point);
3078 newlsb = point[0];
3079 newrsb = newlsb;
3080 newdesc = -point[1];
3081 newasc = -newdesc;
3082 TRANSFORM_POINT(vals->pixel_matrix, lsb, asc, point);
3083 CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
3084 TRANSFORM_POINT(vals->pixel_matrix, rsb, -desc, point);
3085 CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
3086 TRANSFORM_POINT(vals->pixel_matrix, rsb, asc, point);
3087 CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
3088
3089 /* ???: lsb = (int)floor(newlsb * scale); */
3090 *lsb_result = (int)floor(newlsb * scale + 0.5);
3091 *rsb_result = (int)floor(newrsb * scale + 0.5);
3092 *desc_result = (int)ceil(newdesc * scale - 0.5);
3093 *asc_result = (int)floor(newasc * scale + 0.5);
3094
3095 return 0;
3096#undef CHECK_EXTENT
3097#undef TRANSFORM_POINT
3098}
3099
3100static int
3101is_matrix_unit(FontScalablePtr vals)
3102{
3103 double base_size;
3104 FT_Matrix m;
3105
3106 base_size = hypot(vals->point_matrix[2], vals->point_matrix[3]);
3107
3108 m.xx = vals->point_matrix[0] / base_size * 65536;
3109 m.xy = vals->point_matrix[2] / base_size * 65536;
3110 m.yx = vals->point_matrix[1] / base_size * 65536;
3111 m.yy = vals->point_matrix[3] / base_size * 65536;
3112
3113 return (m.xx == 65536) && (m.yx == 0) &&
3114 (m.xy == 0) && (m.yy == 65536);
3115}
3116
3117/* Do all the real work for OpenFont or FontInfo */
3118/* xf->info is only accessed through info, and xf might be null */
3119
3120static int
3121FreeTypeLoadXFont(char *fileName,
3122 FontScalablePtr vals, FontPtr xf, FontInfoPtr info,
3123 FontBitmapFormatPtr bmfmt, FontEntryPtr entry)
3124{
3125 FTFontPtr font = NULL((void*)0);
3126 FTFacePtr face = NULL((void*)0);
3127 FTInstancePtr instance;
3128 FT_Size_Metrics *smetrics;
3129 int xrc=Successful85;
3130 int charcell;
3131 long rawWidth = 0, rawAverageWidth = 0;
3132 int upm, minLsb, maxRsb, ascent, descent, width, averageWidth;
3133 double scale, base_width, base_height;
3134 Bool orig_is_matrix_unit, font_properties;
3135 int face_number, ttcap_spacing;
3136 struct TTCapInfo tmp_ttcap;
3137 struct TTCapInfo *ins_ttcap;
3138 FT_Int32 load_flags = FT_LOAD_DEFAULT0x0; /* orig: FT_LOAD_RENDER | FT_LOAD_MONOCHROME */
3139 char *dynStrRealFileName = NULL((void*)0); /* foo.ttc */
3140 char *dynStrFTFileName = NULL((void*)0); /* :1:foo.ttc */
3141 char *dynStrTTCapCodeRange = NULL((void*)0);
3142
3143 font = calloc(1, sizeof(FTFontRec));
3144 if(font == NULL((void*)0)) {
3145 xrc = AllocError80;
3146 goto quit;
3147 }
3148
3149 xrc = FreeTypeSetUpTTCap(fileName, vals,
3150 &dynStrRealFileName, &dynStrFTFileName,
3151 &tmp_ttcap, &face_number,
3152 &load_flags, &ttcap_spacing,
3153 &font_properties, &dynStrTTCapCodeRange);
3154 if ( xrc != Successful85 ) {
3155 goto quit;
3156 }
3157
3158 xrc = FreeTypeOpenFace(&face, dynStrFTFileName, dynStrRealFileName, face_number);
3159 if(xrc != Successful85) {
3160 goto quit;
3161 }
3162
3163 if( is_matrix_unit(vals) )
3164 orig_is_matrix_unit = True(-1);
3165 else {
3166 orig_is_matrix_unit = False(0);
3167 /* Turn off EmbeddedBitmap when original matrix is not diagonal. */
3168 load_flags |= FT_LOAD_NO_BITMAP0x8;
3169 }
3170
3171 if( face->bitmap ) load_flags &= ~FT_LOAD_NO_BITMAP0x8;
3172
3173 /* Slant control by TTCap */
3174 if(!face->bitmap) {
3175 vals->pixel_matrix[2] +=
3176 vals->pixel_matrix[0] * tmp_ttcap.autoItalic;
3177 vals->point_matrix[2] +=
3178 vals->point_matrix[0] * tmp_ttcap.autoItalic;
3179 vals->pixel_matrix[3] +=
3180 vals->pixel_matrix[1] * tmp_ttcap.autoItalic;
3181 vals->point_matrix[3] +=
3182 vals->point_matrix[1] * tmp_ttcap.autoItalic;
3183 }
3184
3185 base_width=hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
3186 base_height=hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]);
3187 if(MAX(base_width, base_height)((base_width) > (base_height) ? (base_width) : (base_height
))
< 1.0 ) {
3188 xrc = BadFontName83;
3189 goto quit;
3190 }
3191
3192 xrc = FreeTypeLoadFont(font, info, face, dynStrFTFileName, vals, entry, bmfmt,
3193 load_flags, &tmp_ttcap, dynStrTTCapCodeRange,
3194 ttcap_spacing );
3195 if(xrc != Successful85) {
3196 goto quit;
3197 }
3198
3199 instance = font->instance;
3200 smetrics = &instance->size->metrics;
3201 ins_ttcap = &instance->ttcap;
3202
3203 upm = face->face->units_per_EM;
3204 if(upm == 0) {
3205 /* Work around FreeType bug */
3206 upm = WORK_AROUND_UPM2048;
3207 }
3208 scale = 1.0 / upm;
3209
3210 charcell = (instance->spacing == FT_CHARCELL2);
3211
3212 if( instance->charcellMetrics == NULL((void*)0) ) {
3213
3214 /* New instance */
3215
3216 long force_c_rawWidth = 0;
3217 int force_c_lsb,force_c_rsb,force_c_width;
3218 double unit_x=0,unit_y=0,advance;
3219 CharInfoPtr tmpglyph;
3220
3221 /*
3222 * CALCULATE HEADER'S METRICS
3223 */
3224
3225 /* for OUTLINE fonts */
3226 if(!face->bitmap) {
3227 int new_width;
3228 double ratio,force_c_ratio;
3229 double width_x=0,width_y=0;
3230 double force_c_width_x, force_c_rsb_x, force_c_lsb_x;
3231 double tmp_rsb,tmp_lsb,tmp_asc,tmp_des;
3232 double max_advance_height;
3233 tmp_asc = face->face->bbox.yMax;
3234 tmp_des = -(face->face->bbox.yMin);
3235 if ( tmp_asc < face->face->ascender ) tmp_asc = face->face->ascender;
3236 if ( tmp_des < -(face->face->descender) ) tmp_des = -(face->face->descender);
3237 tmp_lsb = face->face->bbox.xMin;
3238 tmp_rsb = face->face->bbox.xMax;
3239 if ( tmp_rsb < face->face->max_advance_width ) tmp_rsb = face->face->max_advance_width;
3240 /* apply scaleBBoxWidth */
3241 /* we should not ...??? */
3242 tmp_lsb *= ins_ttcap->scaleBBoxWidth;
3243 tmp_rsb *= ins_ttcap->scaleBBoxWidth;
3244 /* transform and rescale */
3245 compute_new_extents( vals, scale, tmp_lsb, tmp_rsb, tmp_des, tmp_asc,
3246 &minLsb, &maxRsb, &descent, &ascent );
3247 /* */
3248 /* Consider vertical layouts */
3249 if( 0 < face->face->max_advance_height )
3250 max_advance_height = face->face->max_advance_height;
3251 else
3252 max_advance_height = tmp_asc + tmp_des;
3253 if( vals->pixel_matrix[1] == 0 ){
3254 unit_x = fabs(vals->pixel_matrix[0]);
3255 unit_y = 0;
3256 width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
3257 }
3258 else if( vals->pixel_matrix[3] == 0 ){
3259 unit_y = fabs(vals->pixel_matrix[2]);
3260 unit_x = 0;
3261 width_x = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
3262 }
3263 else{
3264 unit_x = fabs(vals->pixel_matrix[0] -
3265 vals->pixel_matrix[1]*vals->pixel_matrix[2]/vals->pixel_matrix[3]);
3266 unit_y = fabs(vals->pixel_matrix[2] -
3267 vals->pixel_matrix[3]*vals->pixel_matrix[0]/vals->pixel_matrix[1]);
3268 width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
3269 width_y = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
3270 if( width_y < width_x ){
3271 width_x = width_y;
3272 unit_x = 0;
3273 }
3274 else{
3275 unit_y = 0;
3276 }
3277 }
3278 /* calculate correction ratio */
3279 width = (int)floor( (advance = width_x * scale) + 0.5);
3280 new_width = width;
3281 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008 )
3282 new_width += ins_ttcap->doubleStrikeShift;
3283 new_width += ins_ttcap->adjustBBoxWidthByPixel;
3284 ratio = (double)new_width/width;
3285 width = new_width;
3286 /* force constant */
3287 if( unit_x != 0 ) {
3288 force_c_width_x = face->face->max_advance_width
3289 * ins_ttcap->force_c_scale_b_box_width * unit_x;
3290 force_c_lsb_x = face->face->max_advance_width
3291 * ins_ttcap->force_c_scale_lsb * unit_x;
3292 force_c_rsb_x = face->face->max_advance_width
3293 * ins_ttcap->force_c_scale_rsb * unit_x;
3294 }
3295 else {
3296 force_c_width_x = max_advance_height
3297 * ins_ttcap->force_c_scale_b_box_height * unit_y;
3298 force_c_lsb_x = max_advance_height
3299 * ins_ttcap->force_c_scale_lsb * unit_y;
3300 force_c_rsb_x = max_advance_height
3301 * ins_ttcap->force_c_scale_rsb * unit_y;
3302 }
3303 /* calculate correction ratio */
3304 force_c_width = (int)floor(force_c_width_x * scale + 0.5);
3305 new_width = force_c_width;
3306 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008 )
3307 force_c_width += ins_ttcap->doubleStrikeShift;
3308 new_width += ins_ttcap->force_c_adjust_width_by_pixel;
3309 force_c_ratio = (double)new_width/force_c_width;
3310 force_c_width = new_width;
3311 /* force_c_lsb, force_c_rsb */
3312 if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG0x0100 )
3313 force_c_lsb = (int)floor( force_c_lsb_x * scale + 0.5 );
3314 else
3315 force_c_lsb = minLsb;
3316 if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG0x0200 )
3317 force_c_rsb = (int)floor( force_c_rsb_x * scale + 0.5 );
3318 else
3319 force_c_rsb = maxRsb;
3320 /* calculate shift of BitmapAutoItalic
3321 (when diagonal matrix only) */
3322 if( orig_is_matrix_unit == True(-1) ) {
3323 if( ins_ttcap->autoItalic != 0 ) {
3324 double ai;
3325 int ai_lsb,ai_rsb,ai_total;
3326 if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
3327 else ai = -ins_ttcap->autoItalic;
3328 ai_total = (int)( (ascent+descent) * ai + 0.5);
3329 ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
3330 ai_lsb = -(ai_total - ai_rsb);
3331 if( 0 < ins_ttcap->autoItalic ) {
3332 ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
3333 ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
3334 }
3335 else {
3336 ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
3337 ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
3338 }
3339 }
3340 }
3341 /* integer adjustment by TTCap */
3342 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE0x0001 )
3343 maxRsb += ins_ttcap->doubleStrikeShift;
3344 maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
3345 minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
3346 /* */
3347 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE0x0001 )
3348 force_c_rsb += ins_ttcap->doubleStrikeShift;
3349 force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
3350 force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
3351 /* apply to rawWidth */
3352 averageWidth = (int)floor(10 * width_x * scale
3353 * ratio + 0.5);
3354 rawWidth = floor(width_x * scale
3355 * ratio * 1000. / base_height + 0.5);
3356 rawAverageWidth = floor(width_x * scale * ratio * 10.
3357 * 1000. / base_height + 0.5);
3358 force_c_rawWidth = floor(force_c_width_x * scale
3359 * force_c_ratio * 1000. / base_height + 0.5);
3360 /* */
3361 }
3362 /* for BITMAP fonts [if(face->bitmap)] */
3363 else {
3364 /* These values differ from actual when outline,
3365 so we must use them ONLY FOR BITMAP. */
3366 width = (int)floor(smetrics->max_advance * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
3367 descent = -smetrics->descender / 64;
3368 ascent = smetrics->ascender / 64;
3369 /* force constant */
3370 force_c_width = (int)floor(smetrics->max_advance
3371 * ins_ttcap->force_c_scale_b_box_width / 64.0 + .5);
3372 /* Preserve average width for bitmap fonts */
3373 if(vals->width != 0)
3374 averageWidth = (int)floor(vals->width * ins_ttcap->scaleBBoxWidth +.5);
3375 else
3376 averageWidth = (int)floor(10.0 * smetrics->max_advance
3377 * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
3378 rawWidth = 0;
3379 rawAverageWidth = 0;
3380 force_c_rawWidth = 0;
3381 /* We don't consider vertical layouts */
3382 advance = (int)floor(smetrics->max_advance / 64.0 +.5);
3383 unit_x = vals->pixel_matrix[0];
3384 unit_y = 0;
3385 /* We can use 'width' only when bitmap.
3386 This should not be set when outline. */
3387 minLsb = 0;
3388 maxRsb = width;
3389 /* force constant */
3390 if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG0x0100 )
3391 force_c_lsb = (int)floor(smetrics->max_advance
3392 * ins_ttcap->force_c_scale_lsb / 64.0 + .5);
3393 else
3394 force_c_lsb = minLsb;
3395 if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG0x0200 )
3396 force_c_rsb = (int)floor(smetrics->max_advance
3397 * ins_ttcap->force_c_scale_rsb / 64.0 + .5);
3398 else
3399 force_c_rsb = maxRsb;
3400 /* calculate shift of BitmapAutoItalic */
3401 if( ins_ttcap->autoItalic != 0 ) {
3402 double ai;
3403 int ai_lsb,ai_rsb,ai_total;
3404 if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
3405 else ai = -ins_ttcap->autoItalic;
3406 ai_total = (int)( (ascent+descent) * ai + 0.5);
3407 ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
3408 ai_lsb = -(ai_total - ai_rsb);
3409 if( 0 < ins_ttcap->autoItalic ) {
3410 ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
3411 ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
3412 }
3413 else {
3414 ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
3415 ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
3416 }
3417 }
3418 /* integer adjustment by TTCap */
3419 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH0x0008 )
3420 width += ins_ttcap->doubleStrikeShift;
3421 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE0x0001 )
3422 maxRsb += ins_ttcap->doubleStrikeShift;
3423 maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
3424 minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
3425 /* We have not carried out matrix calculation, so this is done. */
3426 maxRsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
3427 minLsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
3428 /* force constant */
3429 if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE0x0001 )
3430 force_c_rsb += ins_ttcap->doubleStrikeShift;
3431 force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
3432 force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
3433 force_c_rsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
3434 force_c_lsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
3435 }
3436
3437 /* SET CALCULATED VALUES TO INSTANCE */
3438
3439 /* Set actual height and cosine */
3440 instance->pixel_size = base_height;
3441 instance->advance = advance;
3442 if ( unit_x != 0 ){
3443 instance->pixel_width_unit_x = unit_x/base_height;
3444 instance->pixel_width_unit_y = 0;
3445 }
3446 else{
3447 instance->pixel_width_unit_x = 0;
3448 instance->pixel_width_unit_y = unit_y/base_height;
3449 }
3450
3451 /* header's metrics */
3452 instance->charcellMetrics = malloc(sizeof(xCharInfo));
3453 if(instance->charcellMetrics == NULL((void*)0)) {
3454 xrc = AllocError80;
3455 goto quit;
3456 }
3457 instance->charcellMetrics->ascent = ascent;
3458 instance->charcellMetrics->descent = descent;
3459 instance->charcellMetrics->attributes = rawWidth;
3460 instance->charcellMetrics->rightSideBearing = maxRsb;
3461 instance->charcellMetrics->leftSideBearing = minLsb;
3462 instance->charcellMetrics->characterWidth = width;
3463 instance->averageWidth = averageWidth;
3464 instance->rawAverageWidth = rawAverageWidth;
3465
3466 /* Check code 0 */
3467 if( FreeTypeInstanceGetGlyph(font->zero_idx, 0, &tmpglyph, font->instance) != Successful85
3468 || tmpglyph == NULL((void*)0))
3469 if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_GET_DUMMY0x04, &tmpglyph, font->instance)
3470 != Successful85 )
3471 tmpglyph = NULL((void*)0);
3472 if ( !tmpglyph ) {
3473 xrc = AllocError80;
3474 goto quit;
3475 }
3476
3477 /* FORCE CONSTANT METRICS */
3478 if( 0 <= ins_ttcap->forceConstantSpacingEnd ) {
3479 xCharInfo *tmpchar = NULL((void*)0);
3480 int c = ins_ttcap->force_c_representative_metrics_char_code;
3481 /* header's metrics */
3482 if( instance->forceConstantMetrics == NULL((void*)0) ){
3483 instance->forceConstantMetrics = malloc(sizeof(xCharInfo));
3484 if(instance->forceConstantMetrics == NULL((void*)0)) {
3485 xrc = AllocError80;
3486 goto quit;
3487 }
3488 }
3489 /* Get Representative Metrics */
3490 if ( 0 <= c ) {
3491 if( FreeTypeFontGetGlyphMetrics(c, 0, &tmpchar, font) != Successful85 )
3492 tmpchar = NULL((void*)0);
3493 }
3494 if ( tmpchar && 0 < tmpchar->characterWidth ) {
3495 instance->forceConstantMetrics->leftSideBearing = tmpchar->leftSideBearing;
3496 instance->forceConstantMetrics->rightSideBearing = tmpchar->rightSideBearing;
3497 instance->forceConstantMetrics->characterWidth = tmpchar->characterWidth;
3498 instance->forceConstantMetrics->ascent = tmpchar->ascent;
3499 instance->forceConstantMetrics->descent = tmpchar->descent;
3500 instance->forceConstantMetrics->attributes = tmpchar->attributes;
3501 }
3502 else {
3503 instance->forceConstantMetrics->leftSideBearing = force_c_lsb;
3504 instance->forceConstantMetrics->rightSideBearing = force_c_rsb;
3505 instance->forceConstantMetrics->characterWidth = force_c_width;
3506 instance->forceConstantMetrics->ascent = ascent;
3507 instance->forceConstantMetrics->descent = descent;
3508 instance->forceConstantMetrics->attributes = force_c_rawWidth;
3509 }
3510 /* Check code 0 */
3511 if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING0x08,
3512 &tmpglyph, font->instance) != Successful85
3513 || tmpglyph == NULL((void*)0))
3514 if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING0x08 | FT_GET_DUMMY0x04,
3515 &tmpglyph, font->instance)
3516 != Successful85 )
3517 tmpglyph = NULL((void*)0);
3518 if ( !tmpglyph ) {
3519 xrc = AllocError80;
3520 goto quit;
3521 }
3522 }
3523 }
3524 else{
3525
3526 /*
3527 * CACHED VALUES
3528 */
3529
3530 width = instance->charcellMetrics->characterWidth;
3531 ascent = instance->charcellMetrics->ascent;
3532 descent = instance->charcellMetrics->descent;
3533 rawWidth = instance->charcellMetrics->attributes;
3534 maxRsb = instance->charcellMetrics->rightSideBearing;
3535 minLsb = instance->charcellMetrics->leftSideBearing;
3536 averageWidth = instance->averageWidth;
3537 rawAverageWidth = instance->rawAverageWidth;
3538
3539 }
3540
3541 /*
3542 * SET maxbounds, minbounds ...
3543 */
3544
3545 if( !charcell ) { /* NOT CHARCELL */
3546 if( info ){
3547 /*
3548 Calculate all glyphs' metrics.
3549 maxbounds.ascent and maxbounds.descent are quite important values
3550 for XAA. If ascent/descent of each glyph exceeds
3551 maxbounds.ascent/maxbounds.descent, XAA causes SERVER CRASH.
3552 Therefore, THIS MUST BE DONE.
3553 */
3554 ft_compute_bounds(font,info,vals);
3555 }
3556 }
3557 else{ /* CHARCELL */
3558
3559 /*
3560 * SET CALCULATED OR CACHED VARIABLES
3561 */
3562
3563 vals->width = averageWidth;
3564
3565 if( info ){
3566
3567 info->maxbounds.leftSideBearing = minLsb;
3568 info->maxbounds.rightSideBearing = maxRsb;
3569 info->maxbounds.characterWidth = width;
3570 info->maxbounds.ascent = ascent;
3571 info->maxbounds.descent = descent;
3572 info->maxbounds.attributes =
3573 (unsigned short)(short)rawWidth;
3574
3575 info->minbounds = info->maxbounds;
3576 }
3577 }
3578
3579 /* set info */
3580
3581 if( info ){
3582 /*
3583 info->fontAscent = ascent;
3584 info->fontDescent = descent;
3585 */
3586 info->fontAscent = info->maxbounds.ascent;
3587 info->fontDescent = info->maxbounds.descent;
3588 /* Glyph metrics are accurate */
3589 info->inkMetrics=1;
3590
3591 memcpy((char *)&info->ink_maxbounds,__builtin___memcpy_chk ((char *)&info->ink_maxbounds, (
char *)&info->maxbounds, sizeof(xCharInfo), __builtin_object_size
((char *)&info->ink_maxbounds, 0))
3592 (char *)&info->maxbounds, sizeof(xCharInfo))__builtin___memcpy_chk ((char *)&info->ink_maxbounds, (
char *)&info->maxbounds, sizeof(xCharInfo), __builtin_object_size
((char *)&info->ink_maxbounds, 0))
;
3593 memcpy((char *)&info->ink_minbounds,__builtin___memcpy_chk ((char *)&info->ink_minbounds, (
char *)&info->minbounds, sizeof(xCharInfo), __builtin_object_size
((char *)&info->ink_minbounds, 0))
3594 (char *)&info->minbounds, sizeof(xCharInfo))__builtin___memcpy_chk ((char *)&info->ink_minbounds, (
char *)&info->minbounds, sizeof(xCharInfo), __builtin_object_size
((char *)&info->ink_minbounds, 0))
;
3595
3596 /* XXX - hack */
3597 info->defaultCh=0;
3598
3599 /* Set the pInfo flags */
3600 /* Properties set by FontComputeInfoAccelerators:
3601 pInfo->noOverlap;
3602 pInfo->terminalFont;
3603 pInfo->constantMetrics;
3604 pInfo->constantWidth;
3605 pInfo->inkInside;
3606 */
3607 /* from lib/font/util/fontaccel.c */
3608 FontComputeInfoAccelerators(info);
3609 }
3610
3611 if(xf)
3612 xf->fontPrivate = (void*)font;
3613
3614 if(info) {
3615 xrc = FreeTypeAddProperties(font, vals, info, entry->name.name,
3616 rawAverageWidth, font_properties);
3617 if (xrc != Successful85) {
3618 goto quit;
3619 }
3620 }
3621
3622 quit:
3623 if ( dynStrTTCapCodeRange ) free(dynStrTTCapCodeRange);
3624 if ( dynStrFTFileName ) free(dynStrFTFileName);
3625 if ( dynStrRealFileName ) free(dynStrRealFileName);
3626 if ( xrc != Successful85 ) {
3627 if( font ){
3628 if( face && font->instance == NULL((void*)0) ) FreeTypeFreeFace(face);
3629 FreeTypeFreeFont(font);
3630 }
3631 }
3632 return xrc;
3633}
3634
3635/* Routines used by X11 to get info and glyphs from the font. */
3636
3637static int
3638FreeTypeGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
3639 FontEncoding charEncoding, unsigned long *metricCount,
3640 xCharInfo **metrics)
3641{
3642 unsigned int code = 0;
3643 int flags = 0;
3644 FTFontPtr tf;
3645 struct TTCapInfo *ttcap;
3646 xCharInfo **mp, *m;
3647
3648 /* MUMBLE("Get metrics for %ld characters\n", count);*/
3649
3650 tf = (FTFontPtr)pFont->fontPrivate;
3651 ttcap = &tf->instance->ttcap;
3652 mp = metrics;
3653
3654 while (count-- > 0) {
3655 switch (charEncoding) {
3656 case Linear8Bit:
3657 case TwoD8Bit:
3658 code = *chars++;
3659 break;
3660 case Linear16Bit:
3661 case TwoD16Bit:
3662 code = (*chars++ << 8);
3663 code |= *chars++;
3664 /* */
3665 if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE0x0400) ) {
3666 if ( (int)code <= ttcap->forceConstantSpacingEnd
3667 && ttcap->forceConstantSpacingBegin <= (int)code )
3668 flags|=FT_FORCE_CONSTANT_SPACING0x08;
3669 else flags=0;
3670 }
3671 else { /* for GB18030 proportional */
3672 if ( (int)code <= ttcap->forceConstantSpacingEnd
3673 || ttcap->forceConstantSpacingBegin <= (int)code )
3674 flags|=FT_FORCE_CONSTANT_SPACING0x08;
3675 else flags=0;
3676 }
3677 break;
3678 }
3679
3680 if(FreeTypeFontGetGlyphMetrics(code, flags, &m, tf) == Successful85 && m!=NULL((void*)0)) {
3681 *mp++ = m;
3682 }
3683#ifdef X_ACCEPTS_NO_SUCH_CHAR
3684 else *mp++ = &noSuchChar.metrics;
3685#endif
3686 }
3687
3688 *metricCount = mp - metrics;
3689 return Successful85;
3690}
3691
3692static int
3693FreeTypeGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
3694 FontEncoding charEncoding, unsigned long *glyphCount,
3695 CharInfoPtr *glyphs)
3696{
3697 unsigned int code = 0;
3698 int flags = 0;
3699 FTFontPtr tf;
3700 CharInfoPtr *gp;
3701 CharInfoPtr g;
3702 struct TTCapInfo *ttcap;
3703
3704 tf = (FTFontPtr)pFont->fontPrivate;
3705 ttcap = &tf->instance->ttcap;
3706 gp = glyphs;
3707
3708 while (count-- > 0) {
3709 switch (charEncoding) {
3710 case Linear8Bit: case TwoD8Bit:
3711 code = *chars++;
3712 break;
3713 case Linear16Bit: case TwoD16Bit:
3714 code = *chars++ << 8;
3715 code |= *chars++;
3716 /* */
3717 if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE0x0400) ) {
3718 if ( (int)code <= ttcap->forceConstantSpacingEnd
3719 && ttcap->forceConstantSpacingBegin <= (int)code )
3720 flags|=FT_FORCE_CONSTANT_SPACING0x08;
3721 else flags=0;
3722 }
3723 else { /* for GB18030 proportional */
3724 if ( (int)code <= ttcap->forceConstantSpacingEnd
3725 || ttcap->forceConstantSpacingBegin <= (int)code )
3726 flags|=FT_FORCE_CONSTANT_SPACING0x08;
3727 else flags=0;
3728 }
3729 break;
3730 }
3731
3732 if(FreeTypeFontGetGlyph(code, flags, &g, tf) == Successful85 && g!=NULL((void*)0)) {
3733 *gp++ = g;
3734 }
3735#ifdef X_ACCEPTS_NO_SUCH_CHAR
3736 else {
3737#ifdef XAA_ACCEPTS_NULL_BITS
3738 *gp++ = &noSuchChar;
3739#else
3740 if ( tf->dummy_char.bits ) {
3741 *gp++ = &tf->dummy_char;
3742 }
3743 else {
3744 char *raster = NULL((void*)0);
3745 int wd_actual, ht_actual, wd, ht, bpr;
3746 wd_actual = tf->info->maxbounds.rightSideBearing - tf->info->maxbounds.leftSideBearing;
3747 ht_actual = tf->info->maxbounds.ascent + tf->info->maxbounds.descent;
3748 if(wd_actual <= 0) wd = 1;
3749 else wd=wd_actual;
3750 if(ht_actual <= 0) ht = 1;
3751 else ht=ht_actual;
3752 bpr = (((wd + (tf->instance->bmfmt.glyph<<3) - 1) >> 3) &
3753 -tf->instance->bmfmt.glyph);
3754 raster = calloc(1, ht * bpr);
3755 if(raster) {
3756 tf->dummy_char.bits = raster;
3757 *gp++ = &tf->dummy_char;
3758 }
3759 }
3760#endif
3761 }
3762#endif
3763 }
3764
3765 *glyphCount = gp - glyphs;
3766 return Successful85;
3767}
3768
3769static int
3770FreeTypeSetUpFont(FontPathElementPtr fpe, FontPtr xf, FontInfoPtr info,
3771 fsBitmapFormat format, fsBitmapFormatMask fmask,
3772 FontBitmapFormatPtr bmfmt)
3773{
3774 int xrc;
3775 int image;
3776
3777 /* Get the default bitmap format information for this X installation.
3778 Also update it for the client if running in the font server. */
3779 FontDefaultFormat(&bmfmt->bit, &bmfmt->byte, &bmfmt->glyph, &bmfmt->scan);
3780 if ((xrc = CheckFSFormat(format, fmask, &bmfmt->bit, &bmfmt->byte,
3781 &bmfmt->scan, &bmfmt->glyph,
3782 &image)) != Successful85) {
3783 MUMBLE("Aborting after checking FS format: %d\n", xrc);
3784 return xrc;
3785 }
3786
3787 if(xf) {
3788 xf->refcnt = 0;
3789 xf->bit = bmfmt->bit;
3790 xf->byte = bmfmt->byte;
3791 xf->glyph = bmfmt->glyph;
3792 xf->scan = bmfmt->scan;
3793 xf->format = format;
3794 xf->get_glyphs = FreeTypeGetGlyphs;
3795 xf->get_metrics = FreeTypeGetMetrics;
3796 xf->unload_font = FreeTypeUnloadXFont;
3797 xf->unload_glyphs = 0;
3798 xf->fpe = fpe;
3799 xf->svrPrivate = 0;
3800 xf->fontPrivate = 0; /* we'll set it later */
3801 xf->fpePrivate = 0;
3802 }
3803
3804 info->defaultCh = 0;
3805 info->noOverlap = 0; /* not updated */
3806 info->terminalFont = 0; /* not updated */
3807 info->constantMetrics = 0; /* we'll set it later */
3808 info->constantWidth = 0; /* we'll set it later */
3809 info->inkInside = 1;
3810 info->inkMetrics = 1;
3811 info->allExist=0; /* not updated */
3812 info->drawDirection = LeftToRight0; /* we'll set it later */
3813 info->cachable = 1; /* we don't do licensing */
3814 info->anamorphic = 0; /* can hinting lead to anamorphic scaling? */
3815 info->maxOverlap = 0; /* we'll set it later. */
3816 info->pad = 0; /* ??? */
3817 return Successful85;
3818}
3819
3820/* Functions exported by the backend */
3821
3822static int
3823FreeTypeOpenScalable(FontPathElementPtr fpe, FontPtr *ppFont, int flags,
3824 FontEntryPtr entry, char *fileName, FontScalablePtr vals,
3825 fsBitmapFormat format, fsBitmapFormatMask fmask,
3826 FontPtr non_cachable_font)
3827{
3828 int xrc;
3829 FontPtr xf;
3830 FontBitmapFormatRec bmfmt;
3831
3832 MUMBLE("Open Scalable %s, XLFD=%s\n",fileName, entry->name.length ? entry->name.name : "");
3833
3834 xf = CreateFontRec();
3835 if (xf == NULL((void*)0))
3836 return AllocError80;
3837
3838 xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt);
3839 if(xrc != Successful85) {
3840 DestroyFontRec(xf);
3841 return xrc;
3842 }
3843 xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry);
3844 if(xrc != Successful85) {
3845 MUMBLE("Error during load: %d\n",xrc);
3846 DestroyFontRec(xf);
3847 return xrc;
3848 }
3849
3850 *ppFont = xf;
3851
3852 return xrc;
3853}
3854
3855/* Routine to get requested font info. */
3856
3857static int
3858FreeTypeGetInfoScalable(FontPathElementPtr fpe, FontInfoPtr info,
3859 FontEntryPtr entry, FontNamePtr fontName,
3860 char *fileName, FontScalablePtr vals)
3861{
3862 int xrc;
3863 FontBitmapFormatRec bmfmt;
3864
3865 MUMBLE("Get info, XLFD=%s\n", entry->name.length ? entry->name.name : "");
3866
3867 xrc = FreeTypeSetUpFont(fpe, 0, info, 0, 0, &bmfmt);
3868 if(xrc != Successful85) {
3869 return xrc;
3870 }
3871
3872 bmfmt.glyph <<= 3;
3873
3874 xrc = FreeTypeLoadXFont(fileName, vals, 0, info, &bmfmt, entry);
3875 if(xrc != Successful85) {
3876 MUMBLE("Error during load: %d\n", xrc);
3877 return xrc;
3878 }
3879
3880 return Successful85;
3881}
3882
3883/* Renderer registration. */
3884
3885/* Set the capabilities of this renderer. */
3886#define CAPABILITIES(0x2 | 0x1) (CAP_CHARSUBSETTING0x2 | CAP_MATRIX0x1)
3887
3888/* Set it up so file names with either upper or lower case can be
3889 loaded. We don't support compressed fonts. */
3890static FontRendererRec renderers[] = {
3891 {".ttf", 4, 0, FreeTypeOpenScalable, 0,
3892 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3893 {".ttc", 4, 0, FreeTypeOpenScalable, 0,
3894 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3895 {".otf", 4, 0, FreeTypeOpenScalable, 0,
3896 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3897 {".otc", 4, 0, FreeTypeOpenScalable, 0,
3898 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3899 {".pfa", 4, 0, FreeTypeOpenScalable, 0,
3900 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3901 {".pfb", 4, 0, FreeTypeOpenScalable, 0,
3902 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3903};
3904static int num_renderers = sizeof(renderers) / sizeof(renderers[0]);
3905
3906static FontRendererRec alt_renderers[] = {
3907 {".bdf", 4, 0, FreeTypeOpenScalable, 0,
3908 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3909 {".pcf", 4, 0, FreeTypeOpenScalable, 0,
3910 FreeTypeGetInfoScalable, 0, CAPABILITIES(0x2 | 0x1)},
3911};
3912
3913static int num_alt_renderers =
3914sizeof(alt_renderers) / sizeof(alt_renderers[0]);
3915
3916
3917void
3918FreeTypeRegisterFontFileFunctions(void)
3919{
3920 int i;
3921
3922 for (i = 0; i < num_renderers; i++)
3923 FontFileRegisterRenderer(&renderers[i]);
3924
3925 for (i = 0; i < num_alt_renderers; i++)
3926 FontFilePriorityRegisterRenderer(&alt_renderers[i], -10);
3927}