| @@ -32,28 +32,52 @@ makeFont(void) | | | @@ -32,28 +32,52 @@ makeFont(void) |
32 | { | | 32 | { |
33 | FontPtr font; | | 33 | FontPtr font; |
34 | | | 34 | |
35 | font = malloc(sizeof(FontRec)); | | 35 | font = malloc(sizeof(FontRec)); |
36 | if(font == NULL) | | 36 | if(font == NULL) |
37 | return NULL; | | 37 | return NULL; |
38 | | | 38 | |
39 | font->numNames = 0; | | 39 | font->numNames = 0; |
40 | font->names = NULL; | | 40 | font->names = NULL; |
41 | font->flags = 0; | | 41 | font->flags = 0; |
42 | font->weight = 500; | | 42 | font->weight = 500; |
43 | font->width = 5; | | 43 | font->width = 5; |
44 | font->italicAngle = 0; | | 44 | font->italicAngle = 0; |
45 | font->underlinePosition = - TWO_SIXTEENTH; | | 45 | font->pxMetrics.height = UNDEF; |
46 | font->underlineThickness = TWO_SIXTEENTH; | | 46 | font->pxMetrics.maxX = UNDEF; |
| | | 47 | font->pxMetrics.minX = UNDEF; |
| | | 48 | font->pxMetrics.maxY = UNDEF; |
| | | 49 | font->pxMetrics.minY = UNDEF; |
| | | 50 | font->pxMetrics.xHeight = UNDEF; |
| | | 51 | font->pxMetrics.capHeight = UNDEF; |
| | | 52 | font->pxMetrics.maxAwidth = UNDEF; |
| | | 53 | font->pxMetrics.awidth = UNDEF; |
| | | 54 | font->pxMetrics.ascent = UNDEF; |
| | | 55 | font->pxMetrics.descent = UNDEF; |
| | | 56 | font->pxMetrics.underlinePosition = UNDEF; |
| | | 57 | font->pxMetrics.underlineThickness = UNDEF; |
| | | 58 | font->metrics.height = UNDEF; |
| | | 59 | font->metrics.maxX = UNDEF; |
| | | 60 | font->metrics.minX = UNDEF; |
| | | 61 | font->metrics.maxY = UNDEF; |
| | | 62 | font->metrics.minY = UNDEF; |
| | | 63 | font->metrics.xHeight = UNDEF; |
| | | 64 | font->metrics.capHeight = UNDEF; |
| | | 65 | font->metrics.maxAwidth = UNDEF; |
| | | 66 | font->metrics.awidth = UNDEF; |
| | | 67 | font->metrics.ascent = UNDEF; |
| | | 68 | font->metrics.descent = UNDEF; |
| | | 69 | font->metrics.underlinePosition = UNDEF; |
| | | 70 | font->metrics.underlineThickness = UNDEF; |
47 | font->foundry = makeName("UNKN"); | | 71 | font->foundry = makeName("UNKN"); |
48 | font->strikes = NULL; | | 72 | font->strikes = NULL; |
49 | return font; | | 73 | return font; |
50 | } | | 74 | } |
51 | | | 75 | |
52 | StrikePtr | | 76 | StrikePtr |
53 | makeStrike(FontPtr font, int sizeX, int sizeY) | | 77 | makeStrike(FontPtr font, int sizeX, int sizeY) |
54 | { | | 78 | { |
55 | StrikePtr strike, last_strike; | | 79 | StrikePtr strike, last_strike; |
56 | | | 80 | |
57 | strike = font->strikes; | | 81 | strike = font->strikes; |
58 | last_strike = NULL; | | 82 | last_strike = NULL; |
59 | while(strike) { | | 83 | while(strike) { |
| @@ -391,124 +415,71 @@ maxIndex(CmapPtr cmap_head) | | | @@ -391,124 +415,71 @@ maxIndex(CmapPtr cmap_head) |
391 | return cmap_head->maxindex; | | 415 | return cmap_head->maxindex; |
392 | } | | 416 | } |
393 | | | 417 | |
394 | BitmapPtr | | 418 | BitmapPtr |
395 | strikeBitmapIndex(StrikePtr strike, CmapPtr cmap, int index) | | 419 | strikeBitmapIndex(StrikePtr strike, CmapPtr cmap, int index) |
396 | { | | 420 | { |
397 | int code = findCode(cmap, index); | | 421 | int code = findCode(cmap, index); |
398 | if(code < 0) | | 422 | if(code < 0) |
399 | return NULL; | | 423 | return NULL; |
400 | | | 424 | |
401 | return STRIKE_BITMAP(strike, code); | | 425 | return STRIKE_BITMAP(strike, code); |
402 | } | | 426 | } |
403 | | | 427 | |
404 | void | | 428 | int |
405 | strikeMetrics(StrikePtr strike, | | 429 | strikeMaxWidth(StrikePtr strike) |
406 | int *width_max_return, | | | |
407 | int *x_min_return, int *y_min_return, | | | |
408 | int *x_max_return, int *y_max_return) | | | |
409 | { | | 430 | { |
410 | BitmapPtr bitmap; | | 431 | BitmapPtr bitmap; |
411 | int i; | | 432 | int i; |
412 | int width_max = 0; | | 433 | int width_max = 0; |
413 | int x_min = 10000; | | | |
414 | int y_min = 10000; | | | |
415 | int x_max = -10000; | | | |
416 | int y_max = -10000; | | | |
417 | | | 434 | |
418 | for(i = 0; i < FONT_CODES; i++) { | | 435 | for(i = 0; i < FONT_CODES; i++) { |
419 | bitmap = STRIKE_BITMAP(strike, i); | | 436 | bitmap = STRIKE_BITMAP(strike, i); |
420 | if(!bitmap) | | 437 | if(!bitmap) |
421 | continue; | | 438 | continue; |
422 | if(bitmap->advanceWidth > width_max) | | 439 | if(bitmap->advanceWidth > width_max) |
423 | width_max = bitmap->advanceWidth; | | 440 | width_max = bitmap->advanceWidth; |
424 | if(bitmap->horiBearingX < x_min) | | | |
425 | x_min = bitmap->horiBearingX; | | | |
426 | if(bitmap->horiBearingY > y_max) | | | |
427 | y_max = bitmap->horiBearingY; | | | |
428 | if(bitmap->horiBearingX + bitmap->width > x_max) | | | |
429 | x_max = bitmap->horiBearingX + bitmap->width; | | | |
430 | if(bitmap->horiBearingY - bitmap->height < y_min) | | | |
431 | y_min = bitmap->horiBearingY - bitmap->height; | | | |
432 | } | | 441 | } |
433 | | | 442 | |
434 | if(width_max_return) *width_max_return = width_max; | | 443 | return width_max; |
435 | if(x_min_return) *x_min_return = x_min; | | | |
436 | if(y_min_return) *y_min_return = y_min; | | | |
437 | if(x_max_return) *x_max_return = x_max; | | | |
438 | if(y_max_return) *y_max_return = y_max; | | | |
439 | } | | 444 | } |
440 | | | 445 | |
441 | int | | 446 | int |
442 | glyphMetrics(FontPtr font, int code, | | 447 | glyphMetrics(FontPtr font, int code, |
443 | int *width_return, | | 448 | int *width_return, |
444 | int *x_min_return, int *y_min_return, | | 449 | int *x_min_return, int *y_min_return, |
445 | int *x_max_return, int *y_max_return) | | 450 | int *x_max_return, int *y_max_return) |
446 | { | | 451 | { |
447 | StrikePtr strike; | | 452 | StrikePtr strike; |
448 | BitmapPtr bitmap; | | 453 | BitmapPtr bitmap; |
449 | | | 454 | |
450 | strike = font->strikes; | | 455 | strike = font->strikes; |
451 | while(strike) { | | 456 | while(strike) { |
452 | bitmap = STRIKE_BITMAP(strike, code); | | 457 | bitmap = STRIKE_BITMAP(strike, code); |
453 | if(bitmap) { | | 458 | if(bitmap) { |
454 | if(width_return) | | 459 | if(width_return) |
455 | *width_return = | | 460 | *width_return = |
456 | (((float)bitmap->advanceWidth + 0.5) / strike->sizeX) * | | 461 | (((float)bitmap->advanceWidth) / strike->sizeX) * |
457 | TWO_SIXTEENTH; | | 462 | TWO_SIXTEENTH; |
458 | if(x_min_return) | | 463 | if(x_min_return) |
459 | *x_min_return = | | 464 | *x_min_return = |
460 | ((float)bitmap->horiBearingX / strike->sizeX) * | | 465 | ((float)bitmap->horiBearingX / strike->sizeX) * |
461 | TWO_SIXTEENTH; | | 466 | TWO_SIXTEENTH; |
462 | if(y_min_return) | | 467 | if(y_min_return) |
463 | *y_min_return = | | 468 | *y_min_return = |
464 | (((float)bitmap->horiBearingY - bitmap->height) | | 469 | (((float)bitmap->horiBearingY - bitmap->height) |
465 | / strike->sizeY) * TWO_SIXTEENTH; | | 470 | / strike->sizeY) * TWO_SIXTEENTH; |
466 | /* For the following two, 0.9 instead of 0.5 might make | | | |
467 | more sense. However, using different rounding rules | | | |
468 | for x_max and awidth causes problems for detecting | | | |
469 | charcell fonts. */ | | | |
470 | if(x_max_return) | | 471 | if(x_max_return) |
471 | *x_max_return = | | 472 | *x_max_return = |
472 | (((float)bitmap->horiBearingX + bitmap->width + 0.5) | | 473 | (((float)bitmap->horiBearingX + bitmap->width) |
473 | / strike->sizeX) * TWO_SIXTEENTH; | | 474 | / strike->sizeX) * TWO_SIXTEENTH; |
474 | if(y_max_return) | | 475 | if(y_max_return) |
475 | *y_max_return = | | 476 | *y_max_return = |
476 | (((float)bitmap->horiBearingY + 0.5) / strike->sizeY) * | | 477 | (((float)bitmap->horiBearingY) / strike->sizeY) * |
477 | TWO_SIXTEENTH; | | 478 | TWO_SIXTEENTH; |
478 | return 1; | | 479 | return 1; |
479 | } | | 480 | } |
480 | strike = strike->next; | | 481 | strike = strike->next; |
481 | } | | 482 | } |
482 | | | 483 | |
483 | return -1; | | 484 | return -1; |
484 | } | | 485 | } |
485 | | | | |
486 | void | | | |
487 | fontMetrics(FontPtr font, | | | |
488 | int *max_awidth_return, | | | |
489 | int *min_x_return, int *min_y_return, | | | |
490 | int *max_x_return, int *max_y_return) | | | |
491 | { | | | |
492 | int i, rc; | | | |
493 | int max_awidth = 0; | | | |
494 | int min_x = 10000 * 65536, min_y = 10000 * 65536; | | | |
495 | int max_x = -10000 * 65536, max_y = -10000 * 65536; | | | |
496 | for(i = 0; i < FONT_CODES; i++) { | | | |
497 | int awidth, x0, y0, x1, y1; | | | |
498 | rc = glyphMetrics(font, i, &awidth, &x0, &y0, &x1, &y1); | | | |
499 | if(rc < 0) | | | |
500 | continue; | | | |
501 | if(awidth > max_awidth) | | | |
502 | max_awidth = awidth; | | | |
503 | if(x0 < min_x) min_x = x0; | | | |
504 | if(y0 < min_y) min_y = y0; | | | |
505 | if(x1 > max_x) max_x = x1; | | | |
506 | if(y1 > max_y) max_y = y1; | | | |
507 | } | | | |
508 | if(max_awidth_return) *max_awidth_return = max_awidth; | | | |
509 | if(min_x_return) *min_x_return = min_x; | | | |
510 | if(min_y_return) *min_y_return = min_y; | | | |
511 | if(max_x_return) *max_x_return = max_x; | | | |
512 | if(max_y_return) *max_y_return = max_y; | | | |
513 | } | | | |
514 | | | | |