Bug Summary

File:FreeType/ftfuncs.c
Location:line 1930, column 2
Description:Value stored to 'flags' is never read

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