rev |
line source |
paulo@0
|
1 /*
|
paulo@0
|
2 Variable width font drawing library for DS (and GBA)
|
paulo@0
|
3
|
paulo@0
|
4 Copyright 2007-2008 Damian Yerrick <pinoandchester@pineight.com>
|
paulo@0
|
5
|
paulo@0
|
6 This work is provided 'as-is', without any express or implied
|
paulo@0
|
7 warranty. In no event will the authors be held liable for any
|
paulo@0
|
8 damages arising from the use of this work.
|
paulo@0
|
9
|
paulo@0
|
10 Permission is granted to anyone to use this work for any purpose,
|
paulo@0
|
11 including commercial applications, and to alter it and redistribute
|
paulo@0
|
12 it freely, subject to the following restrictions:
|
paulo@0
|
13
|
paulo@0
|
14 1. The origin of this work must not be misrepresented; you must
|
paulo@0
|
15 not claim that you wrote the original work. If you use
|
paulo@0
|
16 this work in a product, an acknowledgment in the product
|
paulo@0
|
17 documentation would be appreciated but is not required.
|
paulo@0
|
18 2. Altered source versions must be plainly marked as such, and must
|
paulo@0
|
19 not be misrepresented as being the original work.
|
paulo@0
|
20 3. This notice may not be removed or altered from any source
|
paulo@0
|
21 distribution.
|
paulo@0
|
22
|
paulo@0
|
23 "Source" is the preferred form of a work for making changes to it.
|
paulo@0
|
24
|
paulo@0
|
25 */
|
paulo@0
|
26 /*
|
paulo@0
|
27
|
paulo@0
|
28 Set FONTDRAW_SPLIT_COMPILE when compiling the time-sensitve parts
|
paulo@0
|
29 into a separate file to be placed in "fast" memory.
|
paulo@0
|
30
|
paulo@0
|
31 */
|
paulo@0
|
32
|
paulo@0
|
33
|
paulo@0
|
34 #ifdef FONTDRAW_SPLIT_COMPILE
|
paulo@0
|
35 typedef unsigned int u32;
|
paulo@0
|
36 extern const unsigned char vwfont_bin[];
|
paulo@0
|
37
|
paulo@0
|
38 typedef struct GlyphRec {
|
paulo@0
|
39 unsigned short dataOffset;
|
paulo@0
|
40 unsigned char glyphWidth;
|
paulo@0
|
41 unsigned char reserved;
|
paulo@0
|
42 } GlyphRec;
|
paulo@0
|
43 #endif
|
paulo@0
|
44
|
paulo@0
|
45 unsigned int fontdraw_putchar(u32 *dst, unsigned int colStride, int wid, int x, int glyph) {
|
paulo@0
|
46 glyph &= 0xFF;
|
paulo@0
|
47 if (glyph < vwfont_bin[1]) {
|
paulo@0
|
48 return 0;
|
paulo@0
|
49 }
|
paulo@0
|
50 glyph -= vwfont_bin[1];
|
paulo@0
|
51 if (vwfont_bin[2] != 0 && glyph >= vwfont_bin[2]) {
|
paulo@0
|
52 return 0;
|
paulo@0
|
53 }
|
paulo@0
|
54 const GlyphRec *glyphRec =
|
paulo@0
|
55 ((const GlyphRec *)(vwfont_bin + vwfont_bin[0])) + glyph;
|
paulo@0
|
56 const unsigned char *data = vwfont_bin + glyphRec->dataOffset;
|
paulo@0
|
57 unsigned int dataShift = 2;
|
paulo@0
|
58 unsigned int dataBits = *data++;
|
paulo@0
|
59 unsigned int pixelCode = dataBits & 0x03;
|
paulo@0
|
60
|
paulo@0
|
61 // Convert x to tile column address and bit address within tile
|
paulo@0
|
62 dst += colStride * (x >> 3);
|
paulo@0
|
63 x = (x & 0x07) << 2;
|
paulo@0
|
64
|
paulo@0
|
65 if (dataShift >= 8) {
|
paulo@0
|
66 dataShift = 2;
|
paulo@0
|
67 dataBits = *data++;
|
paulo@0
|
68 }
|
paulo@0
|
69
|
paulo@0
|
70 for (unsigned int height = vwfont_bin[3];
|
paulo@0
|
71 height > 0;
|
paulo@0
|
72 --height, ++dst) {
|
paulo@0
|
73 int eol = 0;
|
paulo@0
|
74 int xLine = x;
|
paulo@0
|
75 int widLeft = wid;
|
paulo@0
|
76 u32 *dstLine = dst;
|
paulo@0
|
77 u32 dstBits = *dstLine;
|
paulo@0
|
78 while (!eol) {
|
paulo@0
|
79
|
paulo@0
|
80 // Process a pixel instruction
|
paulo@0
|
81 if (pixelCode == 0) {
|
paulo@0
|
82 eol = 1;
|
paulo@0
|
83 } else if (widLeft > 0) {
|
paulo@0
|
84
|
paulo@0
|
85 // Change pixel and move to next pixel
|
paulo@0
|
86 if (pixelCode > 1) {
|
paulo@0
|
87 //dstBits &= ~(0x0F << xLine);
|
paulo@0
|
88 dstBits |= (pixelCode - 1) << xLine;
|
paulo@0
|
89 }
|
paulo@0
|
90 xLine += 4;
|
paulo@0
|
91 --widLeft;
|
paulo@0
|
92 }
|
paulo@0
|
93
|
paulo@0
|
94 // If finished with this tile, write back changed bits
|
paulo@0
|
95 if (xLine >= 32) {
|
paulo@0
|
96 xLine = 0;
|
paulo@0
|
97 *dstLine = dstBits;
|
paulo@0
|
98 dstLine += colStride;
|
paulo@0
|
99 dstBits = *dstLine;
|
paulo@0
|
100 }
|
paulo@0
|
101
|
paulo@0
|
102 // Decode next pixel instruction
|
paulo@0
|
103 if (dataShift >= 8) {
|
paulo@0
|
104 dataShift = 0;
|
paulo@0
|
105 dataBits = *data++;
|
paulo@0
|
106 }
|
paulo@0
|
107
|
paulo@0
|
108 // Decode a byte into pixel instructions
|
paulo@0
|
109 pixelCode = (dataBits >> dataShift) & 0x03;
|
paulo@0
|
110 dataShift += 2;
|
paulo@0
|
111 }
|
paulo@0
|
112
|
paulo@0
|
113 // Write back changed bits
|
paulo@0
|
114 if (xLine > 0) {
|
paulo@0
|
115 *dstLine = dstBits;
|
paulo@0
|
116 }
|
paulo@0
|
117 }
|
paulo@0
|
118 return glyphRec->glyphWidth;
|
paulo@0
|
119 }
|
paulo@0
|
120
|
paulo@0
|
121 void vwfRectfillColumn(u32 *dst, unsigned int colStride,
|
paulo@0
|
122 unsigned int l, unsigned int t,
|
paulo@0
|
123 unsigned int r, unsigned int b,
|
paulo@0
|
124 unsigned int c)
|
paulo@0
|
125 {
|
paulo@0
|
126 u32 mask = 0xffffffffU << (4 * l);
|
paulo@0
|
127 mask &= 0xffffffffU >> (4 * (8 - r));
|
paulo@0
|
128 c &= mask;
|
paulo@0
|
129 mask = ~mask;
|
paulo@0
|
130
|
paulo@0
|
131 for (; t < b; t++) {
|
paulo@0
|
132 dst[t] = (dst[t] & mask) | c;
|
paulo@0
|
133 }
|
paulo@0
|
134 }
|
paulo@0
|
135
|