struct.c revision 3ef3f551
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
3943f32c10Smrg    font->numNames = 0;
4043f32c10Smrg    font->names = NULL;
4143f32c10Smrg    font->flags = 0;
4243f32c10Smrg    font->weight = 500;
4343f32c10Smrg    font->width = 5;
4443f32c10Smrg    font->italicAngle = 0;
453ef3f551Smrg    font->pxMetrics.height = UNDEF;
463ef3f551Smrg    font->pxMetrics.maxX = UNDEF;
473ef3f551Smrg    font->pxMetrics.minX = UNDEF;
483ef3f551Smrg    font->pxMetrics.maxY = UNDEF;
493ef3f551Smrg    font->pxMetrics.minY = UNDEF;
503ef3f551Smrg    font->pxMetrics.xHeight = UNDEF;
513ef3f551Smrg    font->pxMetrics.capHeight = UNDEF;
523ef3f551Smrg    font->pxMetrics.maxAwidth = UNDEF;
533ef3f551Smrg    font->pxMetrics.awidth = UNDEF;
543ef3f551Smrg    font->pxMetrics.ascent = UNDEF;
553ef3f551Smrg    font->pxMetrics.descent = UNDEF;
563ef3f551Smrg    font->pxMetrics.underlinePosition = UNDEF;
573ef3f551Smrg    font->pxMetrics.underlineThickness = UNDEF;
583ef3f551Smrg    font->metrics.height = UNDEF;
593ef3f551Smrg    font->metrics.maxX = UNDEF;
603ef3f551Smrg    font->metrics.minX = UNDEF;
613ef3f551Smrg    font->metrics.maxY = UNDEF;
623ef3f551Smrg    font->metrics.minY = UNDEF;
633ef3f551Smrg    font->metrics.xHeight = UNDEF;
643ef3f551Smrg    font->metrics.capHeight = UNDEF;
653ef3f551Smrg    font->metrics.maxAwidth = UNDEF;
663ef3f551Smrg    font->metrics.awidth = UNDEF;
673ef3f551Smrg    font->metrics.ascent = UNDEF;
683ef3f551Smrg    font->metrics.descent = UNDEF;
693ef3f551Smrg    font->metrics.underlinePosition = UNDEF;
703ef3f551Smrg    font->metrics.underlineThickness = UNDEF;
7143f32c10Smrg    font->foundry = makeName("UNKN");
7243f32c10Smrg    font->strikes = NULL;
7343f32c10Smrg    return font;
7443f32c10Smrg}
7543f32c10Smrg
7643f32c10SmrgStrikePtr
7743f32c10SmrgmakeStrike(FontPtr font, int sizeX, int sizeY)
7843f32c10Smrg{
7943f32c10Smrg    StrikePtr strike, last_strike;
8043f32c10Smrg
8143f32c10Smrg    strike = font->strikes;
8243f32c10Smrg    last_strike = NULL;
8343f32c10Smrg    while(strike) {
8443f32c10Smrg        if(strike->sizeX == sizeX && strike->sizeY == sizeY)
8543f32c10Smrg            return strike;
8643f32c10Smrg        last_strike = strike;
8743f32c10Smrg        strike = strike->next;
8843f32c10Smrg    }
8943f32c10Smrg
9043f32c10Smrg    strike = malloc(sizeof(StrikeRec));
9143f32c10Smrg    if(strike == NULL)
9243f32c10Smrg        return NULL;
9343f32c10Smrg    strike->sizeX = sizeX;
9443f32c10Smrg    strike->sizeY = sizeY;
9543f32c10Smrg    strike->bitmaps =
9643f32c10Smrg        calloc(FONT_CODES / FONT_SEGMENT_SIZE, sizeof(BitmapPtr*));
9743f32c10Smrg    if(strike->bitmaps == NULL) {
9843f32c10Smrg        free(strike);
9943f32c10Smrg        return NULL;
10043f32c10Smrg    }
10143f32c10Smrg    strike->numSbits = 0;
10243f32c10Smrg    strike->next = NULL;
10343f32c10Smrg    strike->bitmapSizeTableLocation = 0xDEADFACE;
10443f32c10Smrg    strike->indexSubTables = NULL;
10543f32c10Smrg    if(last_strike)
10643f32c10Smrg        last_strike->next = strike;
10743f32c10Smrg    else
10843f32c10Smrg        font->strikes = strike;
10943f32c10Smrg    return strike;
11043f32c10Smrg}
11143f32c10Smrg
11243f32c10SmrgBitmapPtr
11343f32c10SmrgmakeBitmap(StrikePtr strike, int code,
11443f32c10Smrg           int advanceWidth, int horiBearingX, int horiBearingY,
11543f32c10Smrg           int width, int height, int stride, unsigned char *raster, int crop)
11643f32c10Smrg{
11743f32c10Smrg    BitmapPtr bitmap;
11843f32c10Smrg    int i, j, x, y;
11943f32c10Smrg    int dx, dy, new_width, new_height;
12043f32c10Smrg
12143f32c10Smrg    bitmap = malloc(sizeof(BitmapRec));
12243f32c10Smrg    if(bitmap == NULL)
12343f32c10Smrg        return NULL;
12443f32c10Smrg
12543f32c10Smrg    bitmap->index = -1;
12643f32c10Smrg    bitmap->width = 0;
12743f32c10Smrg    bitmap->height = 0;
12843f32c10Smrg    bitmap->stride = 0;
12943f32c10Smrg    bitmap->raster = NULL;
13043f32c10Smrg    bitmap->location = 0xDEADFACE;
13143f32c10Smrg
13243f32c10Smrg    i = code / FONT_SEGMENT_SIZE;
13343f32c10Smrg    j = code % FONT_SEGMENT_SIZE;
13443f32c10Smrg
13543f32c10Smrg    if(strike->bitmaps[i] == NULL) {
13643f32c10Smrg        strike->bitmaps[i] = calloc(FONT_SEGMENT_SIZE, sizeof(BitmapPtr));
13743f32c10Smrg    }
13843f32c10Smrg    if(strike->bitmaps[i] == NULL) {
13943f32c10Smrg        free(bitmap);
14043f32c10Smrg        return NULL;
14143f32c10Smrg    }
14243f32c10Smrg    if(strike->bitmaps[i][j] != NULL) {
14343f32c10Smrg        if(verbose_flag)
14443f32c10Smrg            fprintf(stderr, "Duplicate bitmap %d.\n", code);
14543f32c10Smrg        free(bitmap);
14643f32c10Smrg        return strike->bitmaps[i][j];
14743f32c10Smrg    }
14843f32c10Smrg
14943f32c10Smrg    dx = 0;
15043f32c10Smrg    dy = 0;
15143f32c10Smrg    new_width = width;
15243f32c10Smrg    new_height = height;
15343f32c10Smrg
15443f32c10Smrg    if(crop) {
15543f32c10Smrg        int empty;
15643f32c10Smrg        while(new_width > 0) {
15743f32c10Smrg            empty = 1;
15843f32c10Smrg            x = new_width - 1;
15943f32c10Smrg            for(y = 0; y < new_height; y++) {
16043f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
16143f32c10Smrg                    empty = 0;
16243f32c10Smrg                    break;
16343f32c10Smrg                }
16443f32c10Smrg            }
16543f32c10Smrg            if(empty)
16643f32c10Smrg                new_width--;
16743f32c10Smrg            else
16843f32c10Smrg                break;
16943f32c10Smrg        }
17043f32c10Smrg        while(new_height > 0) {
17143f32c10Smrg            empty = 1;
17243f32c10Smrg            y = new_height - 1;
17343f32c10Smrg            for(x = 0; x < new_width; x++) {
17443f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
17543f32c10Smrg                    empty = 0;
17643f32c10Smrg                    break;
17743f32c10Smrg                }
17843f32c10Smrg            }
17943f32c10Smrg            if(empty)
18043f32c10Smrg                new_height--;
18143f32c10Smrg            else
18243f32c10Smrg                break;
18343f32c10Smrg        }
18443f32c10Smrg        while(new_width > 0) {
18543f32c10Smrg            empty = 1;
18643f32c10Smrg            x = 0;
18743f32c10Smrg            for(y = 0; y < new_height; y++) {
18843f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
18943f32c10Smrg                    empty = 0;
19043f32c10Smrg                    break;
19143f32c10Smrg                }
19243f32c10Smrg            }
19343f32c10Smrg            if(empty) {
19443f32c10Smrg                dx++;
19543f32c10Smrg                new_width--;
19643f32c10Smrg            } else
19743f32c10Smrg                break;
19843f32c10Smrg        }
19943f32c10Smrg        while(new_height > 0) {
20043f32c10Smrg            empty = 1;
20143f32c10Smrg            y = 0;
20243f32c10Smrg            for(x = 0; x < new_width; x++) {
20343f32c10Smrg                if(BITREF(raster, stride, x + dx, y + dy)) {
20443f32c10Smrg                    empty = 0;
20543f32c10Smrg                    break;
20643f32c10Smrg                }
20743f32c10Smrg            }
20843f32c10Smrg            if(empty) {
20943f32c10Smrg                dy++;
21043f32c10Smrg                new_height--;
21143f32c10Smrg            } else
21243f32c10Smrg                break;
21343f32c10Smrg        }
21443f32c10Smrg    }
21543f32c10Smrg
21643f32c10Smrg
21743f32c10Smrg    bitmap->advanceWidth = advanceWidth;
21843f32c10Smrg    bitmap->horiBearingX = horiBearingX + dx;
21943f32c10Smrg    bitmap->horiBearingY = horiBearingY - dy;
22043f32c10Smrg    bitmap->width = new_width;
22143f32c10Smrg    bitmap->height = new_height;
22243f32c10Smrg    bitmap->stride = (new_width + 7) / 8;
22343f32c10Smrg
22443f32c10Smrg    bitmap->raster = malloc(bitmap->height * bitmap->stride);
22543f32c10Smrg    if(bitmap->raster == NULL) {
22643f32c10Smrg        free(bitmap);
22743f32c10Smrg        return NULL;
22843f32c10Smrg    }
22943f32c10Smrg    memset(bitmap->raster, 0, bitmap->height * bitmap->stride);
23043f32c10Smrg    for(y = 0; y < new_height; y++) {
23143f32c10Smrg        for(x = 0; x < new_width; x++) {
23243f32c10Smrg            if(BITREF(raster, stride, x + dx, y + dy))
23343f32c10Smrg                bitmap->raster[y * bitmap->stride + x / 8] |=
23443f32c10Smrg                    1 << (7 - (x % 8));
23543f32c10Smrg        }
23643f32c10Smrg    }
23743f32c10Smrg    strike->bitmaps[i][j] = bitmap;
23843f32c10Smrg    strike->numSbits++;
23943f32c10Smrg
24043f32c10Smrg    return bitmap;
24143f32c10Smrg}
24243f32c10Smrg
24343f32c10SmrgIndexSubTablePtr
24443f32c10SmrgmakeIndexSubTables(StrikePtr strike, CmapPtr cmap)
24543f32c10Smrg{
24643f32c10Smrg    IndexSubTablePtr table, first, last;
24743f32c10Smrg    BitmapPtr bitmap0, bitmap;
24843f32c10Smrg    int index, n;
24943f32c10Smrg
25043f32c10Smrg    first = NULL;
25143f32c10Smrg    last = NULL;
25243f32c10Smrg
25343f32c10Smrg    /* Assuming that we're writing bit-aligned data, small metrics
25443f32c10Smrg       and short offsets, a constant metrics segment saves 5 bytes
25543f32c10Smrg       per glyph in the EBDT table, and 2 bytes per glyph in the EBLC
25643f32c10Smrg       table.  On the other hand, the overhead for a supplementary
25743f32c10Smrg       type 2 indexSubTable is 8 bytes for the indexSubTableArray
25843f32c10Smrg       entry and 20 bytes for the subtable itself.  It's worth
25943f32c10Smrg       splitting at 5 glyphs.  There's no analogue of a type 2
26043f32c10Smrg       indexSubTable with byte-aligned data, so we don't bother
26143f32c10Smrg       splitting when byte-aligning. */
26243f32c10Smrg    index = 0;
26343f32c10Smrg    while(index < 0xFFFF) {
26443f32c10Smrg        int constantMetrics = 1;
26543f32c10Smrg        bitmap0 = strikeBitmapIndex(strike, cmap, index);
26643f32c10Smrg        if(bitmap0 == NULL) {
26743f32c10Smrg            index++;
26843f32c10Smrg            continue;
26943f32c10Smrg        }
27043f32c10Smrg        n = 1;
27143f32c10Smrg        while((bitmap = strikeBitmapIndex(strike, cmap, index + n)) != NULL) {
27243f32c10Smrg            if(constantMetrics) {
27343f32c10Smrg                if(!SAME_METRICS(bitmap0, bitmap)) {
27443f32c10Smrg                    if(bit_aligned_flag && n >= 4)
27543f32c10Smrg                        break;
27643f32c10Smrg                    else
27743f32c10Smrg                        constantMetrics = 0;
27843f32c10Smrg                }
27943f32c10Smrg            } else if(bit_aligned_flag) {
28043f32c10Smrg                BitmapPtr b1 = strikeBitmapIndex(strike, cmap, index + n + 1);
28143f32c10Smrg                BitmapPtr b2 = strikeBitmapIndex(strike, cmap, index + n + 2);
28243f32c10Smrg                BitmapPtr b3 = strikeBitmapIndex(strike, cmap, index + n + 3);
28343f32c10Smrg                BitmapPtr b4 = strikeBitmapIndex(strike, cmap, index + n + 4);
28443f32c10Smrg                if(b1 && b2 && b3 && b4 &&
28543f32c10Smrg                   SAME_METRICS(bitmap, b1) &&
28643f32c10Smrg                   SAME_METRICS(bitmap, b2) &&
28743f32c10Smrg                   SAME_METRICS(bitmap, b3) &&
28843f32c10Smrg                   SAME_METRICS(bitmap, b4)) {
28943f32c10Smrg                    break;
29043f32c10Smrg                }
29143f32c10Smrg            }
29243f32c10Smrg            n++;
29343f32c10Smrg        }
29443f32c10Smrg        if(n <= 1)
29543f32c10Smrg            constantMetrics = 0;
29643f32c10Smrg
29743f32c10Smrg        table = malloc(sizeof(IndexSubTableRec));
29843f32c10Smrg        table->firstGlyphIndex = index;
29943f32c10Smrg        table->lastGlyphIndex = index + n - 1;
30043f32c10Smrg        table->constantMetrics = constantMetrics;
30143f32c10Smrg        table->location = 0xDEADFACE;
30243f32c10Smrg        table->lastLocation = 0xDEADFACE;
30343f32c10Smrg        table->next = NULL;
30443f32c10Smrg
30543f32c10Smrg        if(first == NULL) {
30643f32c10Smrg            first = table;
30743f32c10Smrg            last = table;
30843f32c10Smrg        } else {
30943f32c10Smrg            last->next = table;
31043f32c10Smrg            last = table;
31143f32c10Smrg        }
31243f32c10Smrg        index += n;
31343f32c10Smrg    }
31443f32c10Smrg    return first;
31543f32c10Smrg}
31643f32c10Smrg
31743f32c10Smrgint
31843f32c10SmrgfontIndex(FontPtr font, int code)
31943f32c10Smrg{
32043f32c10Smrg    StrikePtr strike;
32143f32c10Smrg    BitmapPtr bitmap;
32243f32c10Smrg
32343f32c10Smrg    if(code == 0)
32443f32c10Smrg        return 0;
32543f32c10Smrg    strike = font->strikes;
32643f32c10Smrg    while(strike) {
32743f32c10Smrg        bitmap = STRIKE_BITMAP(strike, code);
32843f32c10Smrg        if(bitmap)
32943f32c10Smrg            return bitmap->index;
33043f32c10Smrg        strike = strike->next;
33143f32c10Smrg    }
33243f32c10Smrg    return -1;
33343f32c10Smrg}
33443f32c10Smrg
33543f32c10SmrgCmapPtr
33643f32c10SmrgmakeCmap(FontPtr font)
33743f32c10Smrg{
33843f32c10Smrg    CmapPtr cmap_head = NULL;
33943f32c10Smrg    CmapPtr cmap_last = NULL;
34043f32c10Smrg    CmapPtr cmap;
34143f32c10Smrg    int code, i, index, maxindex = 0;
34243f32c10Smrg
34343f32c10Smrg    code = 0;
34443f32c10Smrg    while(code < FONT_CODES) {
34543f32c10Smrg        index = fontIndex(font, code);
34643f32c10Smrg        if(index < 0) {
34743f32c10Smrg            code++;
34843f32c10Smrg            continue;
34943f32c10Smrg        }
35043f32c10Smrg        i = 1;
35143f32c10Smrg        while(code + i < FONT_CODES &&
35243f32c10Smrg              fontIndex(font, code + i) == index + i) {
35343f32c10Smrg            i++;
35443f32c10Smrg        }
35543f32c10Smrg        cmap = malloc(sizeof(CmapRec));
35643f32c10Smrg        if(cmap == NULL)
35743f32c10Smrg            return NULL;
35843f32c10Smrg        cmap->startCode = code;
35943f32c10Smrg        cmap->endCode = code + i - 1;
36043f32c10Smrg        cmap->index = index;
36143f32c10Smrg        cmap->next = NULL;
36243f32c10Smrg        cmap->maxindex = 0;
36343f32c10Smrg        if(maxindex < index + i - 1)
36443f32c10Smrg            maxindex = index + i - 1;
36543f32c10Smrg        if(cmap_head == NULL)
36643f32c10Smrg            cmap_head = cmap;
36743f32c10Smrg        else
36843f32c10Smrg            cmap_last->next = cmap;
36943f32c10Smrg        cmap_last = cmap;
37043f32c10Smrg
37143f32c10Smrg        code += i;
37243f32c10Smrg    }
37343f32c10Smrg    cmap_head->maxindex = maxindex;
37443f32c10Smrg    cmap_head->inverse = calloc(maxindex + 1, sizeof(int));
37543f32c10Smrg    cmap = cmap_head;
37643f32c10Smrg    while(cmap) {
37743f32c10Smrg        for(i = cmap->index;
37843f32c10Smrg            i <= cmap->endCode - cmap->startCode + cmap->index; i++) {
37943f32c10Smrg            cmap_head->inverse[i] =
38043f32c10Smrg                i - cmap->index + cmap->startCode;
38143f32c10Smrg        }
38243f32c10Smrg        cmap = cmap->next;
38343f32c10Smrg    }
38443f32c10Smrg
38543f32c10Smrg    return cmap_head;
38643f32c10Smrg}
38743f32c10Smrg
38843f32c10Smrgint
38943f32c10SmrgfindIndex(CmapPtr cmap_head, int code)
39043f32c10Smrg{
39143f32c10Smrg    CmapPtr cmap;
39243f32c10Smrg    cmap = cmap_head;
39343f32c10Smrg    while(cmap) {
39443f32c10Smrg        if(cmap->endCode > code)
39543f32c10Smrg            return -1;
39643f32c10Smrg        if(cmap->startCode <= code)
39743f32c10Smrg            return cmap->index + code - cmap->startCode;
39843f32c10Smrg        cmap = cmap->next;
39943f32c10Smrg    }
40043f32c10Smrg    return -1;
40143f32c10Smrg}
40243f32c10Smrg
40343f32c10Smrgint
40443f32c10SmrgfindCode(CmapPtr cmap_head, int index)
40543f32c10Smrg{
40643f32c10Smrg    if(index < 0 || index > cmap_head->maxindex)
40743f32c10Smrg        return -1;
40843f32c10Smrg    return cmap_head->inverse[index];
40943f32c10Smrg
41043f32c10Smrg}
41143f32c10Smrg
41243f32c10Smrgint
41343f32c10SmrgmaxIndex(CmapPtr cmap_head)
41443f32c10Smrg{
41543f32c10Smrg    return cmap_head->maxindex;
41643f32c10Smrg}
41743f32c10Smrg
41843f32c10SmrgBitmapPtr
41943f32c10SmrgstrikeBitmapIndex(StrikePtr strike, CmapPtr cmap, int index)
42043f32c10Smrg{
42143f32c10Smrg    int code = findCode(cmap, index);
42243f32c10Smrg    if(code < 0)
42343f32c10Smrg        return NULL;
42443f32c10Smrg
42543f32c10Smrg    return STRIKE_BITMAP(strike, code);
42643f32c10Smrg}
42743f32c10Smrg
4283ef3f551Smrgint
4293ef3f551SmrgstrikeMaxWidth(StrikePtr strike)
43043f32c10Smrg{
43143f32c10Smrg    BitmapPtr bitmap;
43243f32c10Smrg    int i;
43343f32c10Smrg    int width_max = 0;
43443f32c10Smrg
43543f32c10Smrg    for(i = 0; i < FONT_CODES; i++) {
43643f32c10Smrg        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    BitmapPtr bitmap;
45443f32c10Smrg
45543f32c10Smrg    strike = font->strikes;
45643f32c10Smrg    while(strike) {
45743f32c10Smrg        bitmap = STRIKE_BITMAP(strike, code);
45843f32c10Smrg        if(bitmap) {
45943f32c10Smrg            if(width_return)
46043f32c10Smrg                *width_return =
4613ef3f551Smrg                    (((float)bitmap->advanceWidth) / strike->sizeX) *
46243f32c10Smrg                    TWO_SIXTEENTH;
46343f32c10Smrg            if(x_min_return)
46443f32c10Smrg                *x_min_return =
46543f32c10Smrg                    ((float)bitmap->horiBearingX / strike->sizeX) *
46643f32c10Smrg                    TWO_SIXTEENTH;
46743f32c10Smrg            if(y_min_return)
46843f32c10Smrg                *y_min_return =
46943f32c10Smrg                    (((float)bitmap->horiBearingY - bitmap->height)
47043f32c10Smrg                     / strike->sizeY) * TWO_SIXTEENTH;
47143f32c10Smrg            if(x_max_return)
47243f32c10Smrg                *x_max_return =
4733ef3f551Smrg                    (((float)bitmap->horiBearingX + bitmap->width)
47443f32c10Smrg                     / strike->sizeX) * TWO_SIXTEENTH;
47543f32c10Smrg            if(y_max_return)
47643f32c10Smrg                *y_max_return =
4773ef3f551Smrg                    (((float)bitmap->horiBearingY) / strike->sizeY) *
47843f32c10Smrg                    TWO_SIXTEENTH;
47943f32c10Smrg            return 1;
48043f32c10Smrg        }
48143f32c10Smrg        strike = strike->next;
48243f32c10Smrg    }
48343f32c10Smrg
48443f32c10Smrg    return -1;
48543f32c10Smrg}
486