Ticket #2172: font-wip.diff

File font-wip.diff, 22.9 KB (added by eriktorbjorn, 18 years ago)

Patch against current SVN

  • tools/convbdf.c

     
    3737#include <string.h>
    3838#include <time.h>
    3939
     40int READ_UINT16(void *addr) {
     41        unsigned char *buf = addr;
     42        return (buf[0] << 8) | buf[1];
     43}
     44
     45void WRITE_UINT16(void *addr, int value) {
     46        unsigned char *buf = addr;
     47        buf[0] = (value >> 8) & 0xFF;
     48        buf[1] = value & 0xFF;
     49}
     50
    4051/* BEGIN font.h*/
    4152/* bitmap_t helper macros*/
    4253#define BITMAP_WORDS(x)                 (((x)+15)/16)   /* image size in words*/
     
    4960
    5061typedef unsigned short bitmap_t; /* bitmap image unit size*/
    5162
     63typedef struct {
     64        int w;
     65        int h;
     66        int x;
     67        int y;
     68} BBX;
     69
    5270/* builtin C-based proportional/fixed font structure */
    5371/* based on The Microwindows Project http://microwindows.org */
    5472struct font {
    5573        char *  name;           /* font name*/
    5674        int             maxwidth;       /* max width in pixels*/
    5775        int             height;         /* height in pixels*/
     76        int     fbbw, fbbh, fbbx, fbby; /* max bounding box */
    5877        int             ascent;         /* ascent (baseline) height*/
    5978        int             firstchar;      /* first character in bitmap*/
    6079        int             size;           /* font size in glyphs*/
    6180        bitmap_t*       bits;           /* 16-bit right-padded bitmap data*/
    6281        unsigned long* offset;  /* offsets into bitmap data*/
    6382        unsigned char* width;   /* character widths or NULL if fixed*/
     83        BBX*    bbx;            /* character bounding box or NULL if fixed*/
    6484        int             defaultchar;    /* default char (not glyph index)*/
    6585        long    bits_size;      /* # words of bitmap_t bits*/
    6686       
     
    6989        char *  copyright;      /* copyright info for loadable fonts*/
    7090        int             pixel_size;
    7191        int             descent;
    72         int             fbbw, fbbh, fbbx, fbby;
    7392};
    7493/* END font.h*/
    7594
     
    93112int bdf_read_header(FILE *fp, struct font* pf);
    94113int bdf_read_bitmaps(FILE *fp, struct font* pf);
    95114char * bdf_getline(FILE *fp, char *buf, int len);
    96 bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2);
     115bitmap_t bdf_hexval(unsigned char *buf);
    97116
    98117int gen_c_source(struct font* pf, char *path);
    99118
     
    446465        pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
    447466        pf->offset = (unsigned long *)malloc(pf->size * sizeof(unsigned long));
    448467        pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
     468        pf->bbx = (BBX *)malloc(pf->size * sizeof(BBX));
    449469       
    450470        if (!pf->bits || !pf->offset || !pf->width) {
    451471                fprintf(stderr, "Error: no memory for font load\n");
     
    463483        int i, k, encoding, width;
    464484        int bbw, bbh, bbx, bby;
    465485        int proportional = 0;
     486        int need_bbx = 0;
    466487        int encodetable = 0;
    467488        long l;
    468489        char buf[256];
     
    523544                                continue;
    524545                        }
    525546                        pf->offset[encoding-pf->firstchar] = ofs;
     547                        pf->width[encoding-pf->firstchar] = width;
    526548
    527                         /* calc char width*/
    528                         if (bbx < 0) {
    529                                 width -= bbx;
    530                                 /*if (width > maxwidth)
    531                                         width = maxwidth;*/
    532                                 bbx = 0;
    533                         }
     549                        pf->bbx[encoding-pf->firstchar].w = bbw;
     550                        pf->bbx[encoding-pf->firstchar].h = bbh;
     551                        pf->bbx[encoding-pf->firstchar].x = bbx;
     552                        pf->bbx[encoding-pf->firstchar].y = bby;
     553
    534554                        if (width > maxwidth)
    535555                                maxwidth = width;
    536                         pf->width[encoding-pf->firstchar] = width;
    537556
    538557                        /* clear bitmap*/
    539                         memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height);
     558                        memset(ch_bitmap, 0, BITMAP_BYTES(bbw) * bbh);
    540559
    541                         ch_words = BITMAP_WORDS(width);
    542 #define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col)))
    543 #define BITMAP_NIBBLES  (BITMAP_BITSPERIMAGE/4)
     560                        ch_words = BITMAP_WORDS(bbw);
    544561
    545562                        /* read bitmaps*/
    546                         for (i = 0; ; ++i) {
    547                                 int hexnibbles;
    548 
     563                        for (i = 0; i < bbh; ++i) {
    549564                                if (!bdf_getline(fp, buf, sizeof(buf))) {
    550565                                        fprintf(stderr, "Error: EOF reading BITMAP data\n");
    551566                                        return 0;
     
    553568                                if (isprefix(buf, "ENDCHAR"))
    554569                                        break;
    555570
    556                                 hexnibbles = strlen(buf);
    557571                                for (k = 0; k < ch_words; ++k) {
    558                                         int ndx = k * BITMAP_NIBBLES;
    559                                         int padnibbles = hexnibbles - ndx;
    560572                                        bitmap_t value;
    561573                                       
    562                                         if (padnibbles <= 0)
    563                                                 break;
    564                                         if (padnibbles >= BITMAP_NIBBLES)
    565                                                 padnibbles = 0;
     574                                        value = bdf_hexval((unsigned char *)buf);
    566575
    567                                         value = bdf_hexval((unsigned char *)buf,
    568                                                                            ndx, ndx+BITMAP_NIBBLES-1-padnibbles);
    569                                         value <<= padnibbles * BITMAP_NIBBLES;
    570 
    571                                         BM(pf->height - pf->descent - bby - bbh + i, k) |=
    572                                                 value >> bbx;
    573                                         /* handle overflow into next image word*/
    574                                         if (bbx) {
    575                                                 BM(pf->height - pf->descent - bby - bbh + i, k+1) =
    576                                                         value << (BITMAP_BITSPERIMAGE - bbx);
     576                                        if (bbw > 8) {
     577                                                WRITE_UINT16(ch_bitmap, value);
     578                                        } else {
     579                                                WRITE_UINT16(ch_bitmap, value << 8);
    577580                                        }
     581                                        ch_bitmap++;
    578582                                }
    579583                        }
    580584
    581                         ofs += BITMAP_WORDS(width) * pf->height;
    582 
     585                        ofs += BITMAP_WORDS(width) * bbh;
    583586                        continue;
    584587                }
    585588                if (strequal(buf, "ENDFONT"))
     
    596599                if (pf->offset[i] == (unsigned long)-1) {
    597600                        pf->offset[i] = pf->offset[defchar];
    598601                        pf->width[i] = pf->width[defchar];
     602                        pf->bbx[i].w = pf->bbx[defchar].w;
     603                        pf->bbx[i].h = pf->bbx[defchar].h;
     604                        pf->bbx[i].x = pf->bbx[defchar].x;
     605                        pf->bbx[i].y = pf->bbx[defchar].y;
    599606                }
    600607        }
    601608
     
    606613                        encodetable = 1;
    607614                        break;
    608615                }
    609                 l += BITMAP_WORDS(pf->width[i]) * pf->height;
     616                l += BITMAP_WORDS(pf->bbx[i].w) * pf->bbx[i].h;
    610617        }
    611618        if (!encodetable) {
    612619                free(pf->offset);
     
    625632                pf->width = NULL;
    626633        }
    627634
     635        /* determine if the font needs a bbx table */
     636        for (i = 0; i < pf->size; ++i) {
     637                if (pf->bbx[i].w != pf->fbbw || pf->bbx[i].h != pf->fbbh || pf->bbx[i].x != pf->fbbx || pf->bbx[i].y != pf->fbby) {
     638                        need_bbx = 1;
     639                        break;
     640                }
     641        }
     642        if (!need_bbx) {
     643                free(pf->bbx);
     644                pf->bbx = NULL;
     645        }
     646
    628647        /* reallocate bits array to actual bits used*/
    629648        if (ofs < pf->bits_size) {
    630649                pf->bits = realloc(pf->bits, ofs * sizeof(bitmap_t));
     
    670689        return buf;
    671690}
    672691
    673 /* return hex value of portion of buffer*/
    674 bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2)
    675 {
     692/* return hex value of buffer */
     693bitmap_t bdf_hexval(unsigned char *buf) {
    676694        bitmap_t val = 0;
    677         int i, c;
     695        unsigned char *ptr;
    678696
    679         for (i = ndx1; i <= ndx2; ++i) {
    680                 c = buf[i];
     697        for (ptr = buf; *ptr; ptr++) {
     698                int c = *ptr;
     699
    681700                if (c >= '0' && c <= '9')
    682701                        c -= '0';
     702                else if (c >= 'A' && c <= 'F')
     703                        c = c - 'A' + 10;
     704                else if (c >= 'a' && c <= 'f')
     705                        c = c - 'a' + 10;
    683706                else
    684                         if (c >= 'A' && c <= 'F')
    685                                 c = c - 'A' + 10;
    686                         else
    687                                 if (c >= 'a' && c <= 'f')
    688                                         c = c - 'a' + 10;
    689                                 else
    690                                         c = 0;
     707                        c = 0;
    691708                val = (val << 4) | c;
    692709        }
    693710        return val;
     
    704721        bitmap_t *ofs = pf->bits;
    705722        char buf[256];
    706723        char obuf[256];
     724        char bbuf[256];
    707725        char hdr1[] = {
    708726                "/* Generated by convbdf on %s. */\n"
    709727                "#include \"common/stdafx.h\"\n"
     
    713731                "   name: %s\n"
    714732                "   facename: %s\n"
    715733                "   w x h: %dx%d\n"
     734                "   bbx: %d %d %d %d\n"
    716735                "   size: %d\n"
    717736                "   ascent: %d\n"
    718737                "   descent: %d\n"
     
    742761                        pf->name,
    743762                        pf->facename? pf->facename: "",
    744763                        pf->maxwidth, pf->height,
     764                        pf->fbbw, pf->fbbh, pf->fbbx, pf->fbby,
    745765                        pf->size,
    746766                        pf->ascent, pf->descent,
    747767                        pf->firstchar, pf->firstchar,
     
    754774        for (i = 0; i < pf->size; ++i) {
    755775                int x;
    756776                int bitcount = 0;
    757                 int width = pf->width ? pf->width[i] : pf->maxwidth;
    758                 int height = pf->height;
     777                int width = pf->bbx ? pf->bbx[i].w : pf->fbbw;
     778                int height = pf->bbx ? pf->bbx[i].h : pf->fbbh;
     779                int xoff = pf->bbx ? pf->bbx[i].x : pf->fbbx;
     780                int yoff = pf->bbx ? pf->bbx[i].y : pf->fbby;
    759781                bitmap_t *bits = pf->bits + (pf->offset? pf->offset[i]: (height * i));
    760782                bitmap_t bitvalue = 0;
    761783
     
    771793                        did_defaultchar = 1;
    772794                }
    773795
    774                 fprintf(ofp, "\n/* Character %d (0x%02x):\n   width %d",
    775                                 i+pf->firstchar, i+pf->firstchar, width);
     796                fprintf(ofp, "\n/* Character %d (0x%02x):\n   width %d\n   bbx ( %d, %d, %d, %d )\n",
     797                                i+pf->firstchar, i+pf->firstchar,
     798                                pf->width ? pf->width[i+pf->firstchar] : pf->maxwidth,
     799                                width, height, xoff, yoff);
    776800
    777801                if (gen_map) {
    778802                        fprintf(ofp, "\n   +");
     
    780804                        fprintf(ofp, "+\n");
    781805
    782806                        x = 0;
    783                         while (height > 0) {
     807                        int h = height;
     808                        while (h > 0) {
    784809                                if (x == 0) fprintf(ofp, "   |");
    785810
    786811                                if (bitcount <= 0) {
    787812                                        bitcount = BITMAP_BITSPERIMAGE;
    788                                         bitvalue = *bits++;
     813                                        bitvalue = READ_UINT16(bits);
     814                                        bits++;
    789815                                }
    790816
    791817                                fprintf(ofp, BITMAP_TESTBIT(bitvalue)? "*": " ");
     
    794820                                --bitcount;
    795821                                if (++x == width) {
    796822                                        fprintf(ofp, "|\n");
    797                                         --height;
     823                                        --h;
    798824                                        x = 0;
    799825                                        bitcount = 0;
    800826                                }
     
    806832                } else
    807833                        fprintf(ofp, "\n*/\n");
    808834
    809                 bits = pf->bits + (pf->offset? pf->offset[i]: (pf->height * i));
    810                 for (x = BITMAP_WORDS(width) * pf->height; x > 0; --x) {
    811                         fprintf(ofp, "0x%04x,\n", *bits);
     835                bits = pf->bits + (pf->offset? pf->offset[i]: (height * i));
     836                for (x = BITMAP_WORDS(width) * height; x > 0; --x) {
     837                        fprintf(ofp, "0x%04x,\n", READ_UINT16(bits));
    812838                        if (!did_syncmsg && *bits++ != *ofs++) {
    813839                                fprintf(stderr, "Warning: found encoding values in non-sorted order (not an error).\n");
    814840                                did_syncmsg = 1;
     
    839865                fprintf(ofp, "};\n\n");
    840866        }
    841867
     868        /* output bbox table */
     869        if (pf->bbx) {
     870                fprintf(ofp, "/* Bounding box data. */\n"
     871                                "static const BBX _sysfont_bbx[] = {\n");
     872
     873                for (i = 0; i < pf->size; ++i)
     874                        fprintf(ofp, "  { %d, %d, %d, %d },\t/* (0x%02x) */\n",
     875                                pf->bbx[i].w, pf->bbx[i].h, pf->bbx[i].x, pf->bbx[i].y, i+pf->firstchar);
     876                fprintf(ofp, "};\n\n");
     877        }
     878
    842879        /* output struct font struct*/
    843880        if (pf->offset)
    844881                sprintf(obuf, "_sysfont_offset,");
     
    850887        else
    851888                sprintf(buf, "0,  /* fixed width*/");
    852889
     890        if (pf->width)
     891                sprintf(bbuf, "_sysfont_bbx,");
     892        else
     893                sprintf(bbuf, "0,  /* fixed bbox*/");
     894
    853895        fprintf(ofp,
    854896                        "/* Exported structure definition. */\n"
    855897                        "static const FontDesc desc = {\n"
    856898                        "\t" "\"%s\",\n"
    857899                        "\t" "%d,\n"
    858900                        "\t" "%d,\n"
     901                        "\t" "%d, %d, %d, %d,\n"
    859902                        "\t" "%d,\n"
    860903                        "\t" "%d,\n"
    861904                        "\t" "%d,\n"
    862905                        "\t" "_font_bits,\n"
    863906                        "\t" "%s\n"
    864907                        "\t" "%s\n"
     908                        "\t" "%s\n"
    865909                        "\t" "%d,\n"
    866910                        "\t" "sizeof(_font_bits)/sizeof(bitmap_t)\n"
    867911                        "};\n",
    868912                        pf->name,
    869913                        pf->maxwidth, pf->height,
     914                        pf->fbbw, pf->fbbh, pf->fbbx, pf->fbby,
    870915                        pf->ascent,
    871916                        pf->firstchar,
    872917                        pf->size,
    873918                        obuf,
    874919                        buf,
     920                        bbuf,
    875921                        pf->defaultchar);
    876922
    877         fprintf(ofp, "\n" "extern const NewFont g_sysfont(desc);\n");
     923        fprintf(ofp, "\n" "#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))\n");
     924        fprintf(ofp, "extern const NewFont g_sysfont(desc);\n");
     925        fprintf(ofp, "#else\n");
     926        fprintf(ofp, "DEFINE_FONT(g_sysfont)\n");
     927        fprintf(ofp, "#endif\n");
    878928        fprintf(ofp, "\n} // End of namespace Graphics\n");
    879929 
    880930        return 0;
  • graphics/font.cpp

     
    4848
    4949void NewFont::drawChar(Surface *dst, byte chr, int tx, int ty, uint32 color) const {
    5050        assert(dst != 0);
    51         byte *ptr = (byte *)dst->getBasePtr(tx, ty);
    5251
    5352        assert(desc.bits != 0 && desc.maxwidth <= 17);
    5453        assert(dst->bytesPerPixel == 1 || dst->bytesPerPixel == 2);
     
    5857                chr = desc.defaultchar;
    5958        }
    6059
    61         const int w = getCharWidth(chr);
    6260        chr -= desc.firstchar;
    63         const bitmap_t *tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.height));
    6461
    65         for (int y = 0; y < desc.height; y++, ptr += dst->pitch) {
    66                 const bitmap_t buffer = *tmp++;
     62        int bbw, bbh, bbx, bby;
     63
     64        // Get the bounding box of the character
     65        if (!desc.bbx) {
     66                bbw = desc.fbbw;
     67                bbh = desc.fbbh;
     68                bbx = desc.fbbx;
     69                bby = desc.fbby;
     70        } else {
     71                bbw = desc.bbx[chr].w;
     72                bbh = desc.bbx[chr].h;
     73                bbx = desc.bbx[chr].x;
     74                bby = desc.bbx[chr].y;
     75        }
     76
     77        byte *ptr = (byte *)dst->getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
     78
     79        const bitmap_t *tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
     80
     81        for (int y = 0; y < bbh; y++, ptr += dst->pitch) {
     82                const bitmap_t buffer = READ_UINT16(tmp);
     83                tmp++;
    6784                bitmap_t mask = 0x8000;
    6885                if (ty + y < 0 || ty + y >= dst->h)
    6986                        continue;
    7087
    71                 for (int x = 0; x < w; x++, mask >>= 1) {
     88                for (int x = 0; x < bbw; x++, mask >>= 1) {
    7289                        if (tx + x < 0 || tx + x >= dst->w)
    7390                                continue;
    7491                        if ((buffer & mask) != 0) {
     
    94111#define BITMAP_TESTBIT(m)       ((m) & BITMAP_FIRSTBIT)
    95112#define BITMAP_SHIFTBIT(m)      ((bitmap_t) ((m) << 1))
    96113
    97 typedef unsigned short bitmap_t; /* bitmap image unit size*/
    98 
    99114/* builtin C-based proportional/fixed font structure */
    100115/* based on The Microwindows Project http://microwindows.org */
    101116struct NewFontData {
     
    108123        bitmap_t*       bits;           /* 16-bit right-padded bitmap data*/
    109124        unsigned long* offset;  /* offsets into bitmap data*/
    110125        unsigned char* width;   /* character widths or NULL if fixed*/
     126        BBX*            bbx;    /* character bounding box or NULL if fixed */
    111127        int             defaultchar;    /* default char (not glyph index)*/
    112128        long    bits_size;      /* # words of bitmap_t bits*/
    113129       
     
    132148int bdf_read_header(Common::SeekableReadStream &fp, NewFontData* pf);
    133149int bdf_read_bitmaps(Common::SeekableReadStream &fp, NewFontData* pf);
    134150char * bdf_getline(Common::SeekableReadStream &fp, char *buf, int len);
    135 bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2);
     151bitmap_t bdf_hexval(unsigned char *buf);
    136152
    137153void free_font(NewFontData* pf) {
    138154        if (!pf)
     
    148164/* build incore structure from .bdf file*/
    149165NewFontData* bdf_read_font(Common::SeekableReadStream &fp) {
    150166        NewFontData* pf;
     167        uint32 pos = fp.pos();
    151168       
    152169        pf = (NewFontData*)calloc(1, sizeof(NewFontData));
    153170        if (!pf)
     
    158175                goto errout;
    159176        }
    160177
     178        fp.seek(pos, SEEK_SET);
     179
    161180        if (!bdf_read_bitmaps(fp, pf)) {
    162181                fprintf(stderr, "Error reading font bitmaps\n");
    163182                goto errout;
     
    173192/* read bdf font header information, return 0 on error*/
    174193int bdf_read_header(Common::SeekableReadStream &fp, NewFontData* pf) {
    175194        int encoding = 0;
    176         int nchars = 0, maxwidth;
     195        int nchars = 0, maxwidth, maxheight;
    177196        int firstchar = 65535;
    178197        int lastchar = -1;
    179198        char buf[256];
     
    287306        /* use the font boundingbox to get initial maxwidth*/
    288307        /*maxwidth = pf->fbbw - pf->fbbx;*/
    289308        maxwidth = pf->fbbw;
     309        maxheight = pf->fbbh;
    290310
    291         /* initially use font maxwidth * height for bits allocation*/
    292         pf->bits_size = nchars * BITMAP_WORDS(maxwidth) * pf->height;
     311        /* initially use font bounding box for bits allocation*/
     312        pf->bits_size = nchars * BITMAP_WORDS(maxwidth) * maxheight;
    293313
    294314        /* allocate bits, offset, and width arrays*/
    295315        pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
    296316        pf->offset = (unsigned long *)malloc(pf->size * sizeof(unsigned long));
    297317        pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
     318        pf->bbx = (BBX *)malloc(pf->size * sizeof(BBX));
    298319       
    299320        if (!pf->bits || !pf->offset || !pf->width) {
    300321                fprintf(stderr, "Error: no memory for font load\n");
     
    311332        int i, k, encoding = 0, width = 0;
    312333        int bbw, bbh = 0, bbx = 0, bby = 0;
    313334        int proportional = 0;
     335        int need_bbx = 0;
    314336        int encodetable = 0;
    315337        long l;
    316338        char buf[256];
    317339
    318         /* reset file pointer*/
    319         fp.seek(0, SEEK_SET);
    320 
    321340        /* initially mark offsets as not used*/
    322341        for (i = 0; i < pf->size; ++i)
    323342                pf->offset[i] = (unsigned long)-1;
     
    371390                                continue;
    372391                        }
    373392                        pf->offset[encoding-pf->firstchar] = ofs;
     393                        pf->width[encoding-pf->firstchar] = width;
    374394
    375                         /* calc char width*/
    376                         if (bbx < 0) {
    377                                 width -= bbx;
    378                                 /*if (width > maxwidth)
    379                                         width = maxwidth;*/
    380                                 bbx = 0;
    381                         }
     395                        pf->bbx[encoding-pf->firstchar].w = bbw;
     396                        pf->bbx[encoding-pf->firstchar].h = bbh;
     397                        pf->bbx[encoding-pf->firstchar].x = bbx;
     398                        pf->bbx[encoding-pf->firstchar].y = bby;
     399
    382400                        if (width > maxwidth)
    383401                                maxwidth = width;
    384                         pf->width[encoding-pf->firstchar] = width;
    385402
    386403                        /* clear bitmap*/
    387                         memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height);
     404                        memset(ch_bitmap, 0, BITMAP_BYTES(bbw) * bbh);
    388405
    389                         ch_words = BITMAP_WORDS(width);
    390 #define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col)))
    391 #define BITMAP_NIBBLES  (BITMAP_BITSPERIMAGE/4)
     406                        ch_words = BITMAP_WORDS(bbw);
    392407
    393408                        /* read bitmaps*/
    394                         for (i = 0; ; ++i) {
    395                                 int hexnibbles;
    396 
     409                        for (i = 0; i < bbh; ++i) {
    397410                                if (!bdf_getline(fp, buf, sizeof(buf))) {
    398411                                        fprintf(stderr, "Error: EOF reading BITMAP data\n");
    399412                                        return 0;
     
    401414                                if (isprefix(buf, "ENDCHAR"))
    402415                                        break;
    403416
    404                                 hexnibbles = strlen(buf);
    405417                                for (k = 0; k < ch_words; ++k) {
    406                                         int ndx = k * BITMAP_NIBBLES;
    407                                         uint padnibbles = hexnibbles - ndx;
    408418                                        bitmap_t value;
    409419                                       
    410                                         if (padnibbles <= 0)
    411                                                 break;
    412                                         if (padnibbles >= BITMAP_NIBBLES)
    413                                                 padnibbles = 0;
    414 
    415                                         value = bdf_hexval((unsigned char *)buf,
    416                                                                            ndx, ndx+BITMAP_NIBBLES-1-padnibbles);
    417                                         value <<= padnibbles * BITMAP_NIBBLES;
    418 
    419                                         BM(pf->height - pf->descent - bby - bbh + i, k) |=
    420                                                 value >> bbx;
    421                                         /* handle overflow into next image word*/
    422                                         if (bbx) {
    423                                                 BM(pf->height - pf->descent - bby - bbh + i, k+1) =
    424                                                         value << (BITMAP_BITSPERIMAGE - bbx);
     420                                        value = bdf_hexval((unsigned char *)buf);
     421                                        if (bbw > 8) {
     422                                                WRITE_UINT16(ch_bitmap, value);
     423                                        } else {
     424                                                WRITE_UINT16(ch_bitmap, value << 8);
    425425                                        }
     426                                        ch_bitmap++;
    426427                                }
    427428                        }
    428429
    429                         ofs += BITMAP_WORDS(width) * pf->height;
    430 
     430                        ofs += BITMAP_WORDS(bbw) * bbh;
    431431                        continue;
    432432                }
    433433                if (strequal(buf, "ENDFONT"))
     
    444444                if (pf->offset[i] == (unsigned long)-1) {
    445445                        pf->offset[i] = pf->offset[defchar];
    446446                        pf->width[i] = pf->width[defchar];
     447                        pf->bbx[i].w = pf->bbx[defchar].w;
     448                        pf->bbx[i].h = pf->bbx[defchar].h;
     449                        pf->bbx[i].x = pf->bbx[defchar].x;
     450                        pf->bbx[i].y = pf->bbx[defchar].y;
    447451                }
    448452        }
    449453
     
    454458                        encodetable = 1;
    455459                        break;
    456460                }
    457                 l += BITMAP_WORDS(pf->width[i]) * pf->height;
     461                l += BITMAP_WORDS(pf->bbx[i].w) * pf->bbx[i].h;
    458462        }
    459463        if (!encodetable) {
    460464                free(pf->offset);
     
    473477                pf->width = NULL;
    474478        }
    475479
     480        /* determine if the font needs a bbx table */
     481        for (i = 0; i < pf->size; ++i) {
     482                if (pf->bbx[i].w != pf->fbbw || pf->bbx[i].h != pf->fbbh || pf->bbx[i].x != pf->fbbx || pf->bbx[i].y != pf->fbby) {
     483                        need_bbx = 1;
     484                        break;
     485                }
     486        }
     487        if (!need_bbx) {
     488                free(pf->bbx);
     489                pf->bbx = NULL;
     490        }
     491
    476492        /* reallocate bits array to actual bits used*/
    477493        if (ofs < pf->bits_size) {
    478494                pf->bits = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t));
     
    518534        return buf;
    519535}
    520536
    521 /* return hex value of portion of buffer*/
    522 bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2) {
     537/* return hex value of buffer */
     538bitmap_t bdf_hexval(unsigned char *buf) {
    523539        bitmap_t val = 0;
    524         int i, c;
    525540
    526         for (i = ndx1; i <= ndx2; ++i) {
    527                 c = buf[i];
     541        for (unsigned char *ptr = buf; *ptr; ptr++) {
     542                int c = *ptr;
     543
    528544                if (c >= '0' && c <= '9')
    529545                        c -= '0';
     546                else if (c >= 'A' && c <= 'F')
     547                        c = c - 'A' + 10;
     548                else if (c >= 'a' && c <= 'f')
     549                        c = c - 'a' + 10;
    530550                else
    531                         if (c >= 'A' && c <= 'F')
    532                                 c = c - 'A' + 10;
    533                         else
    534                                 if (c >= 'a' && c <= 'f')
    535                                         c = c - 'a' + 10;
    536                                 else
    537                                         c = 0;
     551                        c = 0;
    538552                val = (val << 4) | c;
    539553        }
    540554        return val;
     
    549563        desc.name = data->name;
    550564        desc.maxwidth = data->maxwidth;
    551565        desc.height = data->height;
     566        desc.fbbw = data->fbbw;
     567        desc.fbbh = data->fbbh;
     568        desc.fbbx = data->fbbx;
     569        desc.fbby = data->fbby;
    552570        desc.ascent = data->ascent;
    553571        desc.firstchar = data->firstchar;
    554572        desc.size = data->size;
    555573        desc.bits = data->bits;
    556574        desc.offset = data->offset;
    557575        desc.width = data->width;
     576        desc.bbx = data->bbx;
    558577        desc.defaultchar = data->defaultchar;
    559578        desc.bits_size = data->bits_size;
    560579
     
    570589
    571590        cacheFile.writeUint16BE(font.desc.maxwidth);
    572591        cacheFile.writeUint16BE(font.desc.height);
     592        cacheFile.writeUint16BE(font.desc.fbbw);
     593        cacheFile.writeUint16BE(font.desc.fbbh);
     594        cacheFile.writeUint16BE(font.desc.fbbx);
     595        cacheFile.writeUint16BE(font.desc.fbby);
    573596        cacheFile.writeUint16BE(font.desc.ascent);
    574597        cacheFile.writeUint16BE(font.desc.firstchar);
    575598        cacheFile.writeUint16BE(font.desc.size);
     
    598621                cacheFile.writeByte(0);
    599622        }
    600623
     624        if (font.desc.bbx) {
     625                cacheFile.writeByte(1);
     626                for (int i = 0; i < font.desc.size; ++i) {
     627                        cacheFile.writeByte(font.desc.bbx[i].w);
     628                        cacheFile.writeByte(font.desc.bbx[i].h);
     629                        cacheFile.writeByte(font.desc.bbx[i].x);
     630                        cacheFile.writeByte(font.desc.bbx[i].y);
     631                }
     632        } else {
     633                cacheFile.writeByte(0);
     634        }
     635
    601636        return !cacheFile.ioFailed();
    602637}
    603638
     
    605640        NewFont *font = 0;
    606641
    607642        NewFontData *data = (NewFontData *)malloc(sizeof(NewFontData));
    608         if (!data) return 0;
     643        if (!data)
     644                return 0;
    609645
    610646        memset(data, 0, sizeof(NewFontData));
    611647
    612648        data->maxwidth = stream.readUint16BE();
    613649        data->height = stream.readUint16BE();
     650        data->fbbw = stream.readUint16BE();
     651        data->fbbh = stream.readUint16BE();
     652        data->fbbx = stream.readUint16BE();
     653        data->fbby = stream.readUint16BE();
    614654        data->ascent = stream.readUint16BE();
    615655        data->firstchar = stream.readUint16BE();
    616656        data->size = stream.readUint16BE();
     
    656696                }
    657697        }
    658698
     699        bool hasBBXTable = (stream.readByte() != 0);
     700        if (hasBBXTable) {
     701                data->bbx = (BBX *)malloc(sizeof(BBX)*data->size);
     702                if (!data->bbx) {
     703                        free(data->bits);
     704                        free(data->offset);
     705                        free(data->width);
     706                        free(data);
     707                        return 0;
     708                }
     709
     710                for (int i = 0; i < data->size; ++i) {
     711                        data->bbx[i].w = stream.readByte();
     712                        data->bbx[i].h = stream.readByte();
     713                        data->bbx[i].x = stream.readByte();
     714                        data->bbx[i].y = stream.readByte();
     715                }
     716        }
     717
    659718        FontDesc desc;
    660719        desc.name = data->name;
    661720        desc.maxwidth = data->maxwidth;
    662721        desc.height = data->height;
     722        desc.fbbw = data->fbbw;
     723        desc.fbbh = data->fbbh;
     724        desc.fbbx = data->fbbx;
     725        desc.fbby = data->fbby;
    663726        desc.ascent = data->ascent;
    664727        desc.firstchar = data->firstchar;
    665728        desc.size = data->size;
    666729        desc.bits = data->bits;
    667730        desc.offset = data->offset;
    668731        desc.width = data->width;
     732        desc.bbx = data->bbx;
    669733        desc.defaultchar = data->defaultchar;
    670734        desc.bits_size = data->bits_size;
    671735
     
    843907                        }
    844908                }
    845909
    846 
    847910                tmpWidth += w;
    848911                tmpStr += c;
    849912        }
  • graphics/font.h

     
    8787        virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
    8888};
    8989
     90typedef unsigned short bitmap_t; /* bitmap image unit size*/
    9091
     92struct BBX {
     93        int w;
     94        int h;
     95        int x;
     96        int y;
     97};
    9198
    92 typedef unsigned short bitmap_t; /* bitmap image unit size*/
    93 
    9499/* builtin C-based proportional/fixed font structure */
    95100/* based on The Microwindows Project http://microwindows.org */
    96101struct FontDesc {
    97102        const char *    name;           /* font name*/
    98103        int             maxwidth;       /* max width in pixels*/
    99104        int     height;         /* height in pixels*/
     105        int     fbbw, fbbh, fbbx, fbby; /* max bounding box */
    100106        int             ascent;         /* ascent (baseline) height*/
    101107        int             firstchar;      /* first character in bitmap*/
    102108        int             size;           /* font size in glyphs*/
    103109        const bitmap_t* bits;           /* 16-bit right-padded bitmap data*/
    104110        const unsigned long* offset;    /* offsets into bitmap data*/
    105111        const unsigned char* width;     /* character widths or NULL if fixed*/
     112        const BBX* bbx;                 /* character bounding box or NULL if fixed */
    106113        int             defaultchar;    /* default char (not glyph index)*/
    107114        long    bits_size;      /* # words of bitmap_t bits*/
    108115};