diff src/fontdraw_engine.c @ 0:c84446dfb3f5

initial add
author paulo@localhost
date Fri, 13 Mar 2009 00:39:12 -0700
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/fontdraw_engine.c	Fri Mar 13 00:39:12 2009 -0700
     1.3 @@ -0,0 +1,135 @@
     1.4 +/*
     1.5 +Variable width font drawing library for DS (and GBA)
     1.6 +
     1.7 +Copyright 2007-2008 Damian Yerrick <pinoandchester@pineight.com>
     1.8 +
     1.9 +This work is provided 'as-is', without any express or implied
    1.10 +warranty.  In no event will the authors be held liable for any
    1.11 +damages arising from the use of this work.
    1.12 +
    1.13 +Permission is granted to anyone to use this work for any purpose,
    1.14 +including commercial applications, and to alter it and redistribute
    1.15 +it freely, subject to the following restrictions:
    1.16 +
    1.17 +1. The origin of this work must not be misrepresented; you must
    1.18 +   not claim that you wrote the original work. If you use
    1.19 +   this work in a product, an acknowledgment in the product
    1.20 +   documentation would be appreciated but is not required.
    1.21 +2. Altered source versions must be plainly marked as such, and must
    1.22 +   not be misrepresented as being the original work.
    1.23 +3. This notice may not be removed or altered from any source
    1.24 +   distribution.
    1.25 +
    1.26 +"Source" is the preferred form of a work for making changes to it.
    1.27 +
    1.28 +*/
    1.29 +/*
    1.30 +
    1.31 +Set FONTDRAW_SPLIT_COMPILE when compiling the time-sensitve parts
    1.32 +into a separate file to be placed in "fast" memory.
    1.33 +
    1.34 +*/
    1.35 +
    1.36 +
    1.37 +#ifdef FONTDRAW_SPLIT_COMPILE
    1.38 +typedef unsigned int u32;
    1.39 +extern const unsigned char vwfont_bin[];
    1.40 +
    1.41 +typedef struct GlyphRec {
    1.42 +  unsigned short dataOffset;
    1.43 +  unsigned char glyphWidth;
    1.44 +  unsigned char reserved;
    1.45 +} GlyphRec;
    1.46 +#endif
    1.47 +
    1.48 +unsigned int fontdraw_putchar(u32 *dst, unsigned int colStride, int wid, int x, int glyph) {
    1.49 +  glyph &= 0xFF;
    1.50 +  if (glyph < vwfont_bin[1]) {
    1.51 +    return 0;
    1.52 +  }
    1.53 +  glyph -= vwfont_bin[1];
    1.54 +  if (vwfont_bin[2] != 0 && glyph >= vwfont_bin[2]) {
    1.55 +    return 0;
    1.56 +  }
    1.57 +  const GlyphRec *glyphRec = 
    1.58 +    ((const GlyphRec *)(vwfont_bin + vwfont_bin[0])) + glyph;
    1.59 +  const unsigned char *data = vwfont_bin + glyphRec->dataOffset;
    1.60 +  unsigned int dataShift = 2;
    1.61 +  unsigned int dataBits = *data++;
    1.62 +  unsigned int pixelCode = dataBits & 0x03;
    1.63 +
    1.64 +  // Convert x to tile column address and bit address within tile
    1.65 +  dst += colStride * (x >> 3);
    1.66 +  x = (x & 0x07) << 2;
    1.67 +  
    1.68 +  if (dataShift >= 8) {
    1.69 +    dataShift = 2;
    1.70 +    dataBits = *data++;
    1.71 +  }
    1.72 +
    1.73 +  for (unsigned int height = vwfont_bin[3];
    1.74 +       height > 0;
    1.75 +       --height, ++dst) {
    1.76 +    int eol = 0;
    1.77 +    int xLine = x;
    1.78 +    int widLeft = wid;
    1.79 +    u32 *dstLine = dst;
    1.80 +    u32 dstBits = *dstLine;
    1.81 +    while (!eol) {
    1.82 +
    1.83 +      // Process a pixel instruction
    1.84 +      if (pixelCode == 0) {
    1.85 +        eol = 1;
    1.86 +      } else if (widLeft > 0) {
    1.87 +
    1.88 +        // Change pixel and move to next pixel
    1.89 +        if (pixelCode > 1) {
    1.90 +          //dstBits &= ~(0x0F << xLine);
    1.91 +          dstBits |= (pixelCode - 1) << xLine;
    1.92 +        }
    1.93 +        xLine += 4;
    1.94 +        --widLeft;
    1.95 +      }
    1.96 +
    1.97 +      // If finished with this tile, write back changed bits
    1.98 +      if (xLine >= 32) {
    1.99 +        xLine = 0;
   1.100 +        *dstLine = dstBits;
   1.101 +        dstLine += colStride;
   1.102 +        dstBits = *dstLine;
   1.103 +      }
   1.104 +      
   1.105 +      // Decode next pixel instruction
   1.106 +      if (dataShift >= 8) {
   1.107 +        dataShift = 0;
   1.108 +        dataBits = *data++;
   1.109 +      }
   1.110 +
   1.111 +      // Decode a byte into pixel instructions
   1.112 +      pixelCode = (dataBits >> dataShift) & 0x03;
   1.113 +      dataShift += 2;
   1.114 +    }
   1.115 +
   1.116 +    // Write back changed bits
   1.117 +    if (xLine > 0) {
   1.118 +      *dstLine = dstBits;
   1.119 +    }
   1.120 +  }
   1.121 +  return glyphRec->glyphWidth;
   1.122 +}
   1.123 +
   1.124 +void vwfRectfillColumn(u32 *dst, unsigned int colStride,
   1.125 +                       unsigned int l, unsigned int t,
   1.126 +                       unsigned int r, unsigned int b,
   1.127 +                       unsigned int c)
   1.128 +{
   1.129 +  u32 mask = 0xffffffffU << (4 * l);
   1.130 +  mask &= 0xffffffffU >> (4 * (8 - r));
   1.131 +  c &= mask;
   1.132 +  mask = ~mask;
   1.133 +
   1.134 +  for (; t < b; t++) {
   1.135 +    dst[t] = (dst[t] & mask) | c;
   1.136 +  }
   1.137 +}
   1.138 +