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