143f32c10Smrg/*
243f32c10SmrgCopyright (c) 2002-2003 by Juliusz Chroboczek
343f32c10Smrg
443f32c10SmrgPermission is hereby granted, free of charge, to any person obtaining a copy
543f32c10Smrgof this software and associated documentation files (the "Software"), to deal
643f32c10Smrgin the Software without restriction, including without limitation the rights
743f32c10Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
843f32c10Smrgcopies of the Software, and to permit persons to whom the Software is
943f32c10Smrgfurnished to do so, subject to the following conditions:
1043f32c10Smrg
1143f32c10SmrgThe above copyright notice and this permission notice shall be included in
1243f32c10Smrgall copies or substantial portions of the Software.
1343f32c10Smrg
1443f32c10SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1543f32c10SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1643f32c10SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1743f32c10SmrgAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1843f32c10SmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1943f32c10SmrgOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2043f32c10SmrgTHE SOFTWARE.
2143f32c10Smrg*/
2243f32c10Smrg/* $XFree86: xc/programs/fonttosfnt/struct.c,v 1.3 2003/10/24 20:38:11 tsi Exp $ */
2343f32c10Smrg
2443f32c10Smrg#include <stdlib.h>
2543f32c10Smrg#include <stdio.h>
2643f32c10Smrg#include <ft2build.h>
2743f32c10Smrg#include FT_FREETYPE_H
2843f32c10Smrg#include "fonttosfnt.h"
2943f32c10Smrg
3043f32c10SmrgFontPtr
3151b1aeb1SmrgmakeFont(void)
3243f32c10Smrg{
3343f32c10Smrg    FontPtr font;
3443f32c10Smrg
3543f32c10Smrg    font = malloc(sizeof(FontRec));
3643f32c10Smrg    if(font == NULL)
3743f32c10Smrg        return NULL;
3843f32c10Smrg
39845f12d7Smrg    *font = (FontRec) {
40845f12d7Smrg        .numNames = 0,
41845f12d7Smrg        .names = NULL,
42845f12d7Smrg        .flags = 0,
43845f12d7Smrg        .weight = 500,
44845f12d7Smrg        .width = 5,
45845f12d7Smrg        .italicAngle = 0,
46845f12d7Smrg        .pxMetrics.height = UNDEF,
47845f12d7Smrg        .pxMetrics.maxX = UNDEF,
48845f12d7Smrg        .pxMetrics.minX = UNDEF,
49845f12d7Smrg        .pxMetrics.maxY = UNDEF,
50845f12d7Smrg        .pxMetrics.minY = UNDEF,
51845f12d7Smrg        .pxMetrics.xHeight = UNDEF,
52845f12d7Smrg        .pxMetrics.capHeight = UNDEF,
53845f12d7Smrg        .pxMetrics.maxAwidth = UNDEF,
54845f12d7Smrg        .pxMetrics.awidth = UNDEF,
55845f12d7Smrg        .pxMetrics.ascent = UNDEF,
56845f12d7Smrg        .pxMetrics.descent = UNDEF,
57845f12d7Smrg        .pxMetrics.underlinePosition = UNDEF,
58845f12d7Smrg        .pxMetrics.underlineThickness = UNDEF,
59845f12d7Smrg        .metrics.height = UNDEF,
60845f12d7Smrg        .metrics.maxX = UNDEF,
61845f12d7Smrg        .metrics.minX = UNDEF,
62845f12d7Smrg        .metrics.maxY = UNDEF,
63845f12d7Smrg        .metrics.minY = UNDEF,
64845f12d7Smrg        .metrics.xHeight = UNDEF,
65845f12d7Smrg        .metrics.capHeight = UNDEF,
66845f12d7Smrg        .metrics.maxAwidth = UNDEF,
67845f12d7Smrg        .metrics.awidth = UNDEF,
68845f12d7Smrg        .metrics.ascent = UNDEF,
69845f12d7Smrg        .metrics.descent = UNDEF,
70845f12d7Smrg        .metrics.underlinePosition = UNDEF,
71845f12d7Smrg        .metrics.underlineThickness = UNDEF,
72845f12d7Smrg        .foundry = makeName("UNKN"),
73845f12d7Smrg        .strikes = NULL,
74845f12d7Smrg    };
7543f32c10Smrg    return font;
7643f32c10Smrg}
7743f32c10Smrg
7843f32c10SmrgStrikePtr
7943f32c10SmrgmakeStrike(FontPtr font, int sizeX, int sizeY)
8043f32c10Smrg{
8143f32c10Smrg    StrikePtr strike, last_strike;
8243f32c10Smrg
8343f32c10Smrg    strike = font->strikes;
8443f32c10Smrg    last_strike = NULL;
8543f32c10Smrg    while(strike) {
8643f32c10Smrg        if(strike->sizeX == sizeX && strike->sizeY == sizeY)
8743f32c10Smrg            return strike;
8843f32c10Smrg        last_strike = strike;
8943f32c10Smrg        strike = strike->next;
9043f32c10Smrg    }
9143f32c10Smrg
9243f32c10Smrg    strike = malloc(sizeof(StrikeRec));
9343f32c10Smrg    if(strike == NULL)
9443f32c10Smrg        return NULL;
95845f12d7Smrg    else {
96845f12d7Smrg        BitmapPtr **bitmaps =
97845f12d7Smrg            calloc(FONT_CODES / FONT_SEGMENT_SIZE, sizeof(BitmapPtr*));
98845f12d7Smrg        if (bitmaps == NULL) {
99845f12d7Smrg            free(strike);
100845f12d7Smrg            return NULL;
101845f12d7Smrg        }
102845f12d7Smrg        *strike = (StrikeRec) {
103845f12d7Smrg            .sizeX = sizeX,
104845f12d7Smrg            .sizeY = sizeY,
105845f12d7Smrg            .bitmaps = bitmaps,
106845f12d7Smrg            .numSbits = 0,
107845f12d7Smrg            .next = NULL,
108845f12d7Smrg            .bitmapSizeTableLocation = 0xDEADFACE,
109845f12d7Smrg            .indexSubTables = NULL,
110845f12d7Smrg        };
111845f12d7Smrg        if (last_strike)
112845f12d7Smrg            last_strike->next = strike;
113845f12d7Smrg        else
114845f12d7Smrg            font->strikes = strike;
11543f32c10Smrg    }
11643f32c10Smrg    return strike;
11743f32c10Smrg}
11843f32c10Smrg
11943f32c10SmrgBitmapPtr
12043f32c10SmrgmakeBitmap(StrikePtr strike, int code,
12143f32c10Smrg           int advanceWidth, int horiBearingX, int horiBearingY,
122845f12d7Smrg           int width, int height, int stride,
123845f12d7Smrg           const unsigned char *raster, int crop)
12443f32c10Smrg{
12543f32c10Smrg    BitmapPtr bitmap;
12643f32c10Smrg    int i, j, x, y;
12743f32c10Smrg    int dx, dy, new_width, new_height;
12843f32c10Smrg
12943f32c10Smrg    bitmap = malloc(sizeof(BitmapRec));
13043f32c10Smrg    if(bitmap == NULL)
13143f32c10Smrg        return NULL;
13243f32c10Smrg
133845f12d7Smrg    *bitmap = (BitmapRec) {
134845f12d7Smrg        .index = -1,
135845f12d7Smrg        .width = 0,
136845f12d7Smrg        .height = 0,
137845f12d7Smrg        .stride = 0,
138845f12d7Smrg        .raster = NULL,
139845f12d7Smrg        .location = 0xDEADFACE,
140845f12d7Smrg    };
14143f32c10Smrg
14243f32c10Smrg    i = code / FONT_SEGMENT_SIZE;
14343f32c10Smrg    j = code % FONT_SEGMENT_SIZE;
14443f32c10Smrg
14543f32c10Smrg    if(strike->bitmaps[i] == NULL) {
14643f32c10Smrg        strike->bitmaps[i] = calloc(FONT_SEGMENT_SIZE, sizeof(BitmapPtr));
14743f32c10Smrg    }
14843f32c10Smrg    if(strike->bitmaps[i] == NULL) {
14943f32c10Smrg        free(bitmap);
15043f32c10Smrg        return NULL;
15143f32c10Smrg    }
15243f32c10Smrg    if(strike->bitmaps[i][j] != NULL) {
15343f32c10Smrg        if(verbose_flag)
15443f32c10Smrg            fprintf(stderr, "Duplicate bitmap %d.\n", code);
15543f32c10Smrg        free(bitmap);
15643f32c10Smrg        return strike->bitmaps[i][j];
15743f32c10Smrg    }
15843f32c10Smrg
15943f32c10Smrg    dx = 0;
16043f32c10Smrg    dy = 0;
16143f32c10Smrg    new_width = width;
16243f32c10Smrg    new_height = height;
16343f32c10Smrg
16443f32c10Smrg    if(crop) {
16543f32c10Smrg        int empty;
16643f32c10Smrg        while(new_width > 0) {
16743f32c10Smrg            empty = 1;
16843f32c10Smrg            x = new_width - 1;
16943f32c10Smrg            for(y = 0; y < new_height; y++) {
17043f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
17143f32c10Smrg                    empty = 0;
17243f32c10Smrg                    break;
17343f32c10Smrg                }
17443f32c10Smrg            }
17543f32c10Smrg            if(empty)
17643f32c10Smrg                new_width--;
17743f32c10Smrg            else
17843f32c10Smrg                break;
17943f32c10Smrg        }
18043f32c10Smrg        while(new_height > 0) {
18143f32c10Smrg            empty = 1;
18243f32c10Smrg            y = new_height - 1;
18343f32c10Smrg            for(x = 0; x < new_width; x++) {
18443f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
18543f32c10Smrg                    empty = 0;
18643f32c10Smrg                    break;
18743f32c10Smrg                }
18843f32c10Smrg            }
18943f32c10Smrg            if(empty)
19043f32c10Smrg                new_height--;
19143f32c10Smrg            else
19243f32c10Smrg                break;
19343f32c10Smrg        }
19443f32c10Smrg        while(new_width > 0) {
19543f32c10Smrg            empty = 1;
19643f32c10Smrg            x = 0;
19743f32c10Smrg            for(y = 0; y < new_height; y++) {
19843f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
19943f32c10Smrg                    empty = 0;
20043f32c10Smrg                    break;
20143f32c10Smrg                }
20243f32c10Smrg            }
20343f32c10Smrg            if(empty) {
20443f32c10Smrg                dx++;
20543f32c10Smrg                new_width--;
20643f32c10Smrg            } else
20743f32c10Smrg                break;
20843f32c10Smrg        }
20943f32c10Smrg        while(new_height > 0) {
21043f32c10Smrg            empty = 1;
21143f32c10Smrg            y = 0;
21243f32c10Smrg            for(x = 0; x < new_width; x++) {
21343f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
21443f32c10Smrg                    empty = 0;
21543f32c10Smrg                    break;
21643f32c10Smrg                }
21743f32c10Smrg            }
21843f32c10Smrg            if(empty) {
21943f32c10Smrg                dy++;
22043f32c10Smrg                new_height--;
22143f32c10Smrg            } else
22243f32c10Smrg                break;
22343f32c10Smrg        }
22443f32c10Smrg    }
22543f32c10Smrg
22643f32c10Smrg
22743f32c10Smrg    bitmap->advanceWidth = advanceWidth;
22843f32c10Smrg    bitmap->horiBearingX = horiBearingX + dx;
22943f32c10Smrg    bitmap->horiBearingY = horiBearingY - dy;
23043f32c10Smrg    bitmap->width = new_width;
23143f32c10Smrg    bitmap->height = new_height;
23243f32c10Smrg    bitmap->stride = (new_width + 7) / 8;
23343f32c10Smrg
23443f32c10Smrg    bitmap->raster = malloc(bitmap->height * bitmap->stride);
23543f32c10Smrg    if(bitmap->raster == NULL) {
23643f32c10Smrg        free(bitmap);
23743f32c10Smrg        return NULL;
23843f32c10Smrg    }
23943f32c10Smrg    memset(bitmap->raster, 0, bitmap->height * bitmap->stride);
24043f32c10Smrg    for(y = 0; y < new_height; y++) {
24143f32c10Smrg        for(x = 0; x < new_width; x++) {
24243f32c10Smrg            if(BITREF(raster, stride, x + dx, y + dy))
24343f32c10Smrg                bitmap->raster[y * bitmap->stride + x / 8] |=
24443f32c10Smrg                    1 << (7 - (x % 8));
24543f32c10Smrg        }
24643f32c10Smrg    }
24743f32c10Smrg    strike->bitmaps[i][j] = bitmap;
24843f32c10Smrg    strike->numSbits++;
24943f32c10Smrg
25043f32c10Smrg    return bitmap;
25143f32c10Smrg}
25243f32c10Smrg
25343f32c10SmrgIndexSubTablePtr
25443f32c10SmrgmakeIndexSubTables(StrikePtr strike, CmapPtr cmap)
25543f32c10Smrg{
256845f12d7Smrg    IndexSubTablePtr first, last;
257845f12d7Smrg    int index;
25843f32c10Smrg
25943f32c10Smrg    first = NULL;
26043f32c10Smrg    last = NULL;
26143f32c10Smrg
26243f32c10Smrg    /* Assuming that we're writing bit-aligned data, small metrics
26343f32c10Smrg       and short offsets, a constant metrics segment saves 5 bytes
26443f32c10Smrg       per glyph in the EBDT table, and 2 bytes per glyph in the EBLC
26543f32c10Smrg       table.  On the other hand, the overhead for a supplementary
26643f32c10Smrg       type 2 indexSubTable is 8 bytes for the indexSubTableArray
26743f32c10Smrg       entry and 20 bytes for the subtable itself.  It's worth
26843f32c10Smrg       splitting at 5 glyphs.  There's no analogue of a type 2
26943f32c10Smrg       indexSubTable with byte-aligned data, so we don't bother
27043f32c10Smrg       splitting when byte-aligning. */
27143f32c10Smrg    index = 0;
27243f32c10Smrg    while(index < 0xFFFF) {
27343f32c10Smrg        int constantMetrics = 1;
274845f12d7Smrg        int n;
275845f12d7Smrg        IndexSubTablePtr table;
276845f12d7Smrg        BitmapPtr bitmap0, bitmap;
277845f12d7Smrg
27843f32c10Smrg        bitmap0 = strikeBitmapIndex(strike, cmap, index);
27943f32c10Smrg        if(bitmap0 == NULL) {
28043f32c10Smrg            index++;
28143f32c10Smrg            continue;
28243f32c10Smrg        }
28343f32c10Smrg        n = 1;
28443f32c10Smrg        while((bitmap = strikeBitmapIndex(strike, cmap, index + n)) != NULL) {
28543f32c10Smrg            if(constantMetrics) {
28643f32c10Smrg                if(!SAME_METRICS(bitmap0, bitmap)) {
28743f32c10Smrg                    if(bit_aligned_flag && n >= 4)
28843f32c10Smrg                        break;
28943f32c10Smrg                    else
29043f32c10Smrg                        constantMetrics = 0;
29143f32c10Smrg                }
29243f32c10Smrg            } else if(bit_aligned_flag) {
29343f32c10Smrg                BitmapPtr b1 = strikeBitmapIndex(strike, cmap, index + n + 1);
29443f32c10Smrg                BitmapPtr b2 = strikeBitmapIndex(strike, cmap, index + n + 2);
29543f32c10Smrg                BitmapPtr b3 = strikeBitmapIndex(strike, cmap, index + n + 3);
29643f32c10Smrg                BitmapPtr b4 = strikeBitmapIndex(strike, cmap, index + n + 4);
29743f32c10Smrg                if(b1 && b2 && b3 && b4 &&
29843f32c10Smrg                   SAME_METRICS(bitmap, b1) &&
29943f32c10Smrg                   SAME_METRICS(bitmap, b2) &&
30043f32c10Smrg                   SAME_METRICS(bitmap, b3) &&
30143f32c10Smrg                   SAME_METRICS(bitmap, b4)) {
30243f32c10Smrg                    break;
30343f32c10Smrg                }
30443f32c10Smrg            }
30543f32c10Smrg            n++;
30643f32c10Smrg        }
30743f32c10Smrg        if(n <= 1)
30843f32c10Smrg            constantMetrics = 0;
30943f32c10Smrg
31043f32c10Smrg        table = malloc(sizeof(IndexSubTableRec));
311845f12d7Smrg        *table = (IndexSubTableRec) {
312845f12d7Smrg            .firstGlyphIndex = index,
313845f12d7Smrg            .lastGlyphIndex = index + n - 1,
314845f12d7Smrg            .constantMetrics = constantMetrics,
315845f12d7Smrg            .location = 0xDEADFACE,
316845f12d7Smrg            .lastLocation = 0xDEADFACE,
317845f12d7Smrg            .next = NULL,
318845f12d7Smrg        };
31943f32c10Smrg
32043f32c10Smrg        if(first == NULL) {
32143f32c10Smrg            first = table;
32243f32c10Smrg            last = table;
32343f32c10Smrg        } else {
32443f32c10Smrg            last->next = table;
32543f32c10Smrg            last = table;
32643f32c10Smrg        }
32743f32c10Smrg        index += n;
32843f32c10Smrg    }
32943f32c10Smrg    return first;
33043f32c10Smrg}
33143f32c10Smrg
33243f32c10Smrgint
33343f32c10SmrgfontIndex(FontPtr font, int code)
33443f32c10Smrg{
33543f32c10Smrg    StrikePtr strike;
33643f32c10Smrg
33743f32c10Smrg    if(code == 0)
33843f32c10Smrg        return 0;
33943f32c10Smrg    strike = font->strikes;
34043f32c10Smrg    while(strike) {
341845f12d7Smrg        BitmapPtr bitmap = STRIKE_BITMAP(strike, code);
34243f32c10Smrg        if(bitmap)
34343f32c10Smrg            return bitmap->index;
34443f32c10Smrg        strike = strike->next;
34543f32c10Smrg    }
34643f32c10Smrg    return -1;
34743f32c10Smrg}
34843f32c10Smrg
34943f32c10SmrgCmapPtr
35043f32c10SmrgmakeCmap(FontPtr font)
35143f32c10Smrg{
35243f32c10Smrg    CmapPtr cmap_head = NULL;
35343f32c10Smrg    CmapPtr cmap_last = NULL;
35443f32c10Smrg    CmapPtr cmap;
355845f12d7Smrg    int code, maxindex = 0;
35643f32c10Smrg
35743f32c10Smrg    code = 0;
35843f32c10Smrg    while(code < FONT_CODES) {
359845f12d7Smrg        int i;
360845f12d7Smrg        int index = fontIndex(font, code);
36143f32c10Smrg        if(index < 0) {
36243f32c10Smrg            code++;
36343f32c10Smrg            continue;
36443f32c10Smrg        }
36543f32c10Smrg        i = 1;
36643f32c10Smrg        while(code + i < FONT_CODES &&
36743f32c10Smrg              fontIndex(font, code + i) == index + i) {
36843f32c10Smrg            i++;
36943f32c10Smrg        }
37043f32c10Smrg        cmap = malloc(sizeof(CmapRec));
37143f32c10Smrg        if(cmap == NULL)
37243f32c10Smrg            return NULL;
373845f12d7Smrg        *cmap = (CmapRec) {
374845f12d7Smrg            .startCode = code,
375845f12d7Smrg            .endCode = code + i - 1,
376845f12d7Smrg            .index = index,
377845f12d7Smrg            .next = NULL,
378845f12d7Smrg            .maxindex = 0,
379845f12d7Smrg        };
38043f32c10Smrg        if(maxindex < index + i - 1)
38143f32c10Smrg            maxindex = index + i - 1;
38243f32c10Smrg        if(cmap_head == NULL)
38343f32c10Smrg            cmap_head = cmap;
38443f32c10Smrg        else
38543f32c10Smrg            cmap_last->next = cmap;
38643f32c10Smrg        cmap_last = cmap;
38743f32c10Smrg
38843f32c10Smrg        code += i;
38943f32c10Smrg    }
39043f32c10Smrg    cmap_head->maxindex = maxindex;
39143f32c10Smrg    cmap_head->inverse = calloc(maxindex + 1, sizeof(int));
39243f32c10Smrg    cmap = cmap_head;
39343f32c10Smrg    while(cmap) {
394845f12d7Smrg        for(int i = cmap->index;
39543f32c10Smrg            i <= cmap->endCode - cmap->startCode + cmap->index; i++) {
39643f32c10Smrg            cmap_head->inverse[i] =
39743f32c10Smrg                i - cmap->index + cmap->startCode;
39843f32c10Smrg        }
39943f32c10Smrg        cmap = cmap->next;
40043f32c10Smrg    }
40143f32c10Smrg
40243f32c10Smrg    return cmap_head;
40343f32c10Smrg}
40443f32c10Smrg
40543f32c10Smrgint
40643f32c10SmrgfindCode(CmapPtr cmap_head, int index)
40743f32c10Smrg{
40843f32c10Smrg    if(index < 0 || index > cmap_head->maxindex)
40943f32c10Smrg        return -1;
41043f32c10Smrg    return cmap_head->inverse[index];
41143f32c10Smrg
41243f32c10Smrg}
41343f32c10Smrg
41443f32c10Smrgint
41543f32c10SmrgmaxIndex(CmapPtr cmap_head)
41643f32c10Smrg{
41743f32c10Smrg    return cmap_head->maxindex;
41843f32c10Smrg}
41943f32c10Smrg
42043f32c10SmrgBitmapPtr
42143f32c10SmrgstrikeBitmapIndex(StrikePtr strike, CmapPtr cmap, int index)
42243f32c10Smrg{
42343f32c10Smrg    int code = findCode(cmap, index);
42443f32c10Smrg    if(code < 0)
42543f32c10Smrg        return NULL;
42643f32c10Smrg
42743f32c10Smrg    return STRIKE_BITMAP(strike, code);
42843f32c10Smrg}
42943f32c10Smrg
4303ef3f551Smrgint
4313ef3f551SmrgstrikeMaxWidth(StrikePtr strike)
43243f32c10Smrg{
43343f32c10Smrg    int width_max = 0;
43443f32c10Smrg
435845f12d7Smrg    for(int i = 0; i < FONT_CODES; i++) {
436845f12d7Smrg        BitmapPtr bitmap = STRIKE_BITMAP(strike, i);
43743f32c10Smrg        if(!bitmap)
43843f32c10Smrg            continue;
43943f32c10Smrg        if(bitmap->advanceWidth > width_max)
44043f32c10Smrg            width_max = bitmap->advanceWidth;
44143f32c10Smrg    }
44243f32c10Smrg
4433ef3f551Smrg    return width_max;
44443f32c10Smrg}
44543f32c10Smrg
44643f32c10Smrgint
44743f32c10SmrgglyphMetrics(FontPtr font, int code,
44843f32c10Smrg             int *width_return,
44943f32c10Smrg             int *x_min_return, int *y_min_return,
45043f32c10Smrg             int *x_max_return, int *y_max_return)
45143f32c10Smrg{
45243f32c10Smrg    StrikePtr strike;
45343f32c10Smrg
45443f32c10Smrg    strike = font->strikes;
45543f32c10Smrg    while(strike) {
456845f12d7Smrg        BitmapPtr bitmap = STRIKE_BITMAP(strike, code);
45743f32c10Smrg        if(bitmap) {
45843f32c10Smrg            if(width_return)
45943f32c10Smrg                *width_return =
4603ef3f551Smrg                    (((float)bitmap->advanceWidth) / strike->sizeX) *
46143f32c10Smrg                    TWO_SIXTEENTH;
46243f32c10Smrg            if(x_min_return)
46343f32c10Smrg                *x_min_return =
46443f32c10Smrg                    ((float)bitmap->horiBearingX / strike->sizeX) *
46543f32c10Smrg                    TWO_SIXTEENTH;
46643f32c10Smrg            if(y_min_return)
46743f32c10Smrg                *y_min_return =
46843f32c10Smrg                    (((float)bitmap->horiBearingY - bitmap->height)
46943f32c10Smrg                     / strike->sizeY) * TWO_SIXTEENTH;
47043f32c10Smrg            if(x_max_return)
47143f32c10Smrg                *x_max_return =
4723ef3f551Smrg                    (((float)bitmap->horiBearingX + bitmap->width)
47343f32c10Smrg                     / strike->sizeX) * TWO_SIXTEENTH;
47443f32c10Smrg            if(y_max_return)
47543f32c10Smrg                *y_max_return =
4763ef3f551Smrg                    (((float)bitmap->horiBearingY) / strike->sizeY) *
47743f32c10Smrg                    TWO_SIXTEENTH;
47843f32c10Smrg            return 1;
47943f32c10Smrg        }
48043f32c10Smrg        strike = strike->next;
48143f32c10Smrg    }
48243f32c10Smrg
48343f32c10Smrg    return -1;
48443f32c10Smrg}
485