1 |
/* |
2 |
* PearPC |
3 |
* font.cc |
4 |
* |
5 |
* Copyright (C) 1999-2003 Sebastian Biallas (sb@biallas.net) |
6 |
* |
7 |
* This program is free software; you can redistribute it and/or modify |
8 |
* it under the terms of the GNU General Public License version 2 as |
9 |
* published by the Free Software Foundation. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 |
*/ |
20 |
|
21 |
#include <cstdlib> |
22 |
#include <cstring> |
23 |
#include "system/font.h" |
24 |
|
25 |
struct FFH { |
26 |
byte magic[4]; |
27 |
byte height; |
28 |
byte dist; |
29 |
byte res0[11]; |
30 |
} PACKED; |
31 |
|
32 |
struct FChar { |
33 |
byte width; |
34 |
uint16 data[0]; |
35 |
}; |
36 |
|
37 |
Font::Font() |
38 |
{ |
39 |
mData = NULL; |
40 |
} |
41 |
|
42 |
Font::~Font() |
43 |
{ |
44 |
free(mData); |
45 |
} |
46 |
|
47 |
bool Font::loadFromFile(File &file) |
48 |
{ |
49 |
free(mData); |
50 |
mData = NULL; |
51 |
FFH hdr; |
52 |
file.readx(&hdr, sizeof hdr); |
53 |
unsigned int c = 256 * (2 * hdr.height + 1); |
54 |
mData = (byte*)malloc(c); |
55 |
memset(mData, 0, c); |
56 |
mCharWidth = 1; |
57 |
mCharHeight = hdr.height; |
58 |
mBytes = 2; |
59 |
file.readx(mData, c); |
60 |
for (int i=0; i<256; i++) { |
61 |
byte width = mData[(mCharHeight*2+1)*i]; |
62 |
if (width > mCharWidth) mCharWidth = width; |
63 |
} |
64 |
mPadX = 0; |
65 |
mPadY = 0; |
66 |
mRealWidth = mCharWidth; |
67 |
mRealHeight = mCharHeight; |
68 |
return true; |
69 |
} |
70 |
|
71 |
void Font::setPadding(int px, int py) |
72 |
{ |
73 |
mRealWidth = mRealWidth-mPadX+px; |
74 |
mRealHeight = mRealHeight-mPadY+py; |
75 |
} |
76 |
|
77 |
void Font::drawChar(int x, int y, byte c, uint fgcolor, uint bgcolor, byte *tobuf, int bufwidth, int bufheight, int bufcolorbytes) |
78 |
{ |
79 |
byte width = mData[(mCharHeight*2+1)*c]; |
80 |
int jshift = (mCharWidth - width)/2; |
81 |
int bufsize = bufwidth * bufheight * bufcolorbytes; |
82 |
uint o = (x + y * bufwidth)*bufcolorbytes; |
83 |
for (int i=0; i < mCharHeight; i++) { |
84 |
byte *chr = mData + (mCharHeight*2+1)*c + i*2 + 1; |
85 |
uint16 cdata = (chr[1] << 8) | chr[0]; |
86 |
int a = o + i * bufwidth * bufcolorbytes; |
87 |
for (int j=0; j< mCharWidth; j++) { |
88 |
if (a < bufsize) { |
89 |
uint c; |
90 |
if ((cdata << jshift) & (1 << j)) { |
91 |
c = fgcolor; |
92 |
} else { |
93 |
c = bgcolor; |
94 |
} |
95 |
switch (bufcolorbytes) { |
96 |
case 1: |
97 |
tobuf[a] = c; |
98 |
break; |
99 |
case 2: |
100 |
tobuf[a+0]=(((c>>8)>>1)&0x7c)|(((c>>16)>>6) & 3); |
101 |
tobuf[a+1]=(((c>>16)<<2)&0xe0)|(((c>>24)>>3) & 0x1f); |
102 |
break; |
103 |
case 4: |
104 |
tobuf[a+0]=0; |
105 |
tobuf[a+1]=c>>8; |
106 |
tobuf[a+2]=c>>16; |
107 |
tobuf[a+3]=c>>24; |
108 |
break; |
109 |
} |
110 |
} |
111 |
a += bufcolorbytes; |
112 |
} |
113 |
} |
114 |
} |
115 |
|
116 |
void Font::drawFixedChar(int x, int y, int dx, int dy, byte c, uint fgcolor, uint bgcolor, byte *tobuf, int bufwidth, int bufheight, int bufcolorbytes) |
117 |
{ |
118 |
drawChar(dx+x*mRealWidth, dy+y*mRealHeight, c, fgcolor, bgcolor, tobuf, bufwidth, bufheight, bufcolorbytes); |
119 |
} |
120 |
|
121 |
void Font::drawChar2(SystemDisplay *toDisplay, int x, int y, byte c, RGBA fgcolor, RGBA bgcolor) |
122 |
{ |
123 |
byte width = mData[(mCharHeight*2+1)*c]; |
124 |
int jshift = (mCharWidth - width)/2; |
125 |
for (int i=0; i < mCharHeight; i++) { |
126 |
byte *chr = mData + (mCharHeight*2+1)*c + i*2 + 1; |
127 |
uint16 cdata = (chr[1] << 8) | chr[0]; |
128 |
for (int j=0; j< mCharWidth; j++) { |
129 |
RGBA c; |
130 |
if ((cdata << jshift) & (1 << j)) { |
131 |
c = fgcolor; |
132 |
} else { |
133 |
c = bgcolor; |
134 |
} |
135 |
toDisplay->putPixelRGBA(x+j, y+i, c); |
136 |
} |
137 |
} |
138 |
} |
139 |
|
140 |
void Font::drawFixedChar2(SystemDisplay *toDisplay, int x, int y, int dx, int dy, byte c, RGBA fgcolor, RGBA bgcolor) |
141 |
{ |
142 |
drawChar2(toDisplay, dx+x*mRealWidth, dy+y*mRealHeight, c, fgcolor, bgcolor); |
143 |
} |