48 |
/* we don't want dangling pointers */ |
/* we don't want dangling pointers */ |
49 |
pfrface->family_name = NULL; |
pfrface->family_name = NULL; |
50 |
pfrface->style_name = NULL; |
pfrface->style_name = NULL; |
51 |
|
|
52 |
/* finalize the physical font record */ |
/* finalize the physical font record */ |
53 |
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); |
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); |
54 |
|
|
174 |
FT_Bitmap_Size* size; |
FT_Bitmap_Size* size; |
175 |
PFR_Strike strike; |
PFR_Strike strike; |
176 |
FT_Memory memory = pfrface->stream->memory; |
FT_Memory memory = pfrface->stream->memory; |
177 |
|
|
178 |
|
|
179 |
if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) |
if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) |
180 |
goto Exit; |
goto Exit; |
181 |
|
|
182 |
size = pfrface->available_sizes; |
size = pfrface->available_sizes; |
183 |
strike = phy_font->strikes; |
strike = phy_font->strikes; |
184 |
for ( n = 0; n < count; n++, size++, strike++ ) |
for ( n = 0; n < count; n++, size++, strike++ ) |
361 |
metrics->vertBearingX = 0; |
metrics->vertBearingX = 0; |
362 |
metrics->vertBearingY = 0; |
metrics->vertBearingY = 0; |
363 |
|
|
364 |
|
#if 0 /* some fonts seem to be broken here !! */ |
365 |
|
|
366 |
/* Apply the font matrix, if any. */ |
/* Apply the font matrix, if any. */ |
367 |
/* TODO: Test existing fonts with unusual matrix */ |
/* TODO: Test existing fonts with unusual matrix */ |
368 |
/* whether we have to adjust Units per EM. */ |
/* whether we have to adjust Units per EM. */ |
377 |
|
|
378 |
FT_Outline_Transform( outline, &font_matrix ); |
FT_Outline_Transform( outline, &font_matrix ); |
379 |
} |
} |
380 |
|
#endif |
381 |
|
|
382 |
/* scale when needed */ |
/* scale when needed */ |
383 |
if ( scaling ) |
if ( scaling ) |
422 |
/*************************************************************************/ |
/*************************************************************************/ |
423 |
/*************************************************************************/ |
/*************************************************************************/ |
424 |
|
|
425 |
|
#ifdef FT_OPTIMIZE_MEMORY |
426 |
|
FT_LOCAL_DEF( FT_Error ) |
427 |
|
pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ |
428 |
|
FT_UInt glyph1, |
429 |
|
FT_UInt glyph2, |
430 |
|
FT_Vector* kerning ) |
431 |
|
{ |
432 |
|
PFR_Face face = (PFR_Face)pfrface; |
433 |
|
FT_Error error = PFR_Err_Ok; |
434 |
|
PFR_PhyFont phy_font = &face->phy_font; |
435 |
|
FT_UInt32 code1, code2, pair; |
436 |
|
|
437 |
|
kerning->x = 0; |
438 |
|
kerning->y = 0; |
439 |
|
|
440 |
|
if ( glyph1 > 0 ) |
441 |
|
glyph1--; |
442 |
|
|
443 |
|
if ( glyph2 > 0 ) |
444 |
|
glyph2--; |
445 |
|
|
446 |
|
/* convert glyph indices to character codes */ |
447 |
|
if ( glyph1 > phy_font->num_chars || |
448 |
|
glyph2 > phy_font->num_chars ) |
449 |
|
goto Exit; |
450 |
|
|
451 |
|
code1 = phy_font->chars[glyph1].char_code; |
452 |
|
code2 = phy_font->chars[glyph2].char_code; |
453 |
|
pair = PFR_KERN_INDEX(code1,code2); |
454 |
|
|
455 |
|
/* now search the list of kerning items */ |
456 |
|
{ |
457 |
|
PFR_KernItem item = phy_font->kern_items; |
458 |
|
FT_Stream stream = pfrface->stream; |
459 |
|
|
460 |
|
for ( ; item; item = item->next ) |
461 |
|
{ |
462 |
|
if ( pair >= item->pair1 && pair <= item->pair2 ) |
463 |
|
goto FoundPair; |
464 |
|
} |
465 |
|
goto Exit; |
466 |
|
|
467 |
|
FoundPair: /* we found an item, now parse it and find the value if any */ |
468 |
|
if ( FT_STREAM_SEEK( item->offset ) || |
469 |
|
FT_FRAME_ENTER( item->pair_count*item->pair_size ) ) |
470 |
|
goto Exit; |
471 |
|
|
472 |
|
{ |
473 |
|
FT_UInt count = item->pair_count; |
474 |
|
FT_UInt size = item->pair_size; |
475 |
|
FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); |
476 |
|
FT_UInt probe = power*size; |
477 |
|
FT_UInt extra = count - power; |
478 |
|
FT_Byte* base = stream->cursor; |
479 |
|
FT_Bool twobytes = item->flags & 1; |
480 |
|
FT_Byte* p; |
481 |
|
FT_UInt32 cpair; |
482 |
|
|
483 |
|
if ( extra > 0 ) |
484 |
|
{ |
485 |
|
p = base + extra*size; |
486 |
|
if ( twobytes ) |
487 |
|
cpair = FT_NEXT_ULONG(p); |
488 |
|
else |
489 |
|
cpair = PFR_NEXT_KPAIR(p); |
490 |
|
|
491 |
|
if ( cpair == pair ) |
492 |
|
goto Found; |
493 |
|
|
494 |
|
if ( cpair < pair ) |
495 |
|
base = p; |
496 |
|
} |
497 |
|
|
498 |
|
while ( probe > size ) |
499 |
|
{ |
500 |
|
probe >>= 1; |
501 |
|
p = base + probe; |
502 |
|
if ( twobytes ) |
503 |
|
cpair = FT_NEXT_ULONG(p); |
504 |
|
else |
505 |
|
cpair = PFR_NEXT_KPAIR(p); |
506 |
|
|
507 |
|
if ( cpair == pair ) |
508 |
|
goto Found; |
509 |
|
|
510 |
|
if ( cpair < pair ) |
511 |
|
base += probe; |
512 |
|
} |
513 |
|
|
514 |
|
p = base; |
515 |
|
if ( twobytes ) |
516 |
|
cpair = FT_NEXT_ULONG(p); |
517 |
|
else |
518 |
|
cpair = PFR_NEXT_KPAIR(p); |
519 |
|
|
520 |
|
if ( cpair == pair ) |
521 |
|
{ |
522 |
|
FT_Int value; |
523 |
|
|
524 |
|
Found: |
525 |
|
if ( item->flags & 2 ) |
526 |
|
value = FT_PEEK_SHORT(p); |
527 |
|
else |
528 |
|
value = p[0]; |
529 |
|
|
530 |
|
kerning->x = item->base_adj + value; |
531 |
|
} |
532 |
|
} |
533 |
|
|
534 |
|
FT_FRAME_EXIT(); |
535 |
|
} |
536 |
|
|
537 |
|
Exit: |
538 |
|
return error; |
539 |
|
} |
540 |
|
|
541 |
|
#else /* !FT_OPTIMIZE_MEMORY */ |
542 |
FT_LOCAL_DEF( FT_Error ) |
FT_LOCAL_DEF( FT_Error ) |
543 |
pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ |
pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ |
544 |
FT_UInt glyph1, |
FT_UInt glyph1, |
558 |
|
|
559 |
min = 0; |
min = 0; |
560 |
max = phy_font->num_kern_pairs; |
max = phy_font->num_kern_pairs; |
561 |
|
|
562 |
while ( min < max ) |
while ( min < max ) |
563 |
{ |
{ |
564 |
FT_UInt mid = ( min + max ) >> 1; |
FT_UInt mid = ( min + max ) >> 1; |
565 |
PFR_KernPair pair = pairs + mid; |
PFR_KernPair pair = pairs + mid; |
566 |
FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair ); |
FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair ); |
567 |
|
|
568 |
|
|
569 |
if ( pidx == idx ) |
if ( pidx == idx ) |
570 |
{ |
{ |
571 |
kerning->x = pair->kerning; |
kerning->x = pair->kerning; |
572 |
break; |
break; |
573 |
} |
} |
574 |
|
|
575 |
if ( pidx < idx ) |
if ( pidx < idx ) |
576 |
min = mid + 1; |
min = mid + 1; |
577 |
else |
else |
580 |
|
|
581 |
return error; |
return error; |
582 |
} |
} |
583 |
|
#endif /* !FT_OPTIMIZE_MEMORY */ |
584 |
|
|
585 |
/* END */ |
/* END */ |