Theme Editor: Rockbox FNT files now supported. Theme editor will currently load...
[kugel-rb.git] / utils / themeeditor / graphics / rbfont.cpp
blobe59c79a970b650ab0941d159c99f34cc68c1be4a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Robert Bieber
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "rbfont.h"
24 #include <QFont>
25 #include <QBrush>
26 #include <QFile>
27 #include <QPainter>
28 #include <QBitmap>
29 #include <QImage>
31 quint16 RBFont::maxFontSizeFor16BitOffsets = 0xFFDB;
33 RBFont::RBFont(QString file)
34 : valid(false), imageData(0), offsetData(0), widthData(0)
37 /* Attempting to locate the correct file name */
38 if(!QFile::exists(file))
39 file = ":/fonts/08-Schumacher-Clean.fnt";
40 header.insert("filename", file);
42 /* Opening the file */
43 QFile fin(file);
44 fin.open(QFile::ReadOnly);
46 /* Loading the header info */
47 quint8 byte;
48 quint16 word;
49 quint32 dword;
51 QDataStream data(&fin);
52 data.setByteOrder(QDataStream::LittleEndian);
54 /* Grabbing the magic number and version */
55 data >> dword;
56 header.insert("version", dword);
58 /* Max font width */
59 data >> word;
60 header.insert("maxwidth", word);
62 /* Font height */
63 data >> word;
64 header.insert("height", word);
66 /* Ascent */
67 data >> word;
68 header.insert("ascent", word);
70 /* Padding */
71 data >> word;
73 /* First character code */
74 data >> dword;
75 header.insert("firstchar", dword);
77 /* Default character code */
78 data >> dword;
79 header.insert("defaultchar", dword);
81 /* Number of characters */
82 data >> dword;
83 header.insert("size", dword);
85 /* Bytes of imagebits in file */
86 data >> dword;
87 header.insert("nbits", dword);
89 /* Longs (dword) of offset data in file */
90 data >> dword;
91 header.insert("noffset", dword);
93 /* Bytes of width data in file */
94 data >> dword;
95 header.insert("nwidth", dword);
97 /* Loading the image data */
98 imageData = new quint8[header.value("nbits").toInt()];
99 for(int i = 0; i < header.value("nbits").toInt(); i++)
101 data >> byte;
102 imageData[i] = byte;
105 /* Aligning on 16-bit boundary */
106 if(header.value("nbits").toInt() % 2 == 1)
107 data >> byte;
109 /* Loading the offset table if necessary */
110 if(header.value("noffset").toInt() > 0)
112 offsetData = new quint16[header.value("noffset").toInt()];
113 for(int i = 0; i < header.value("noffset").toInt(); i++)
115 data >> word;
116 offsetData[i] = word;
120 /* Loading the width table if necessary */
121 if(header.value("nwidth").toInt() > 0)
123 widthData = new quint8[header.value("nwidth").toInt()];
124 for(int i = 0; i < header.value("nwidth").toInt(); i++)
126 data >> byte;
127 widthData[i] = byte;
131 fin.close();
135 RBFont::~RBFont()
137 if(imageData)
138 delete[] imageData;
139 if(offsetData)
140 delete[] offsetData;
141 if(widthData)
142 delete[] widthData;
145 RBText* RBFont::renderText(QString text, QColor color, QGraphicsItem *parent)
147 int firstChar = header.value("firstchar").toInt();
148 int height = header.value("height").toInt();
149 int maxWidth = header.value("maxwidth").toInt();
151 /* First we determine the width of the combined text */
152 QList<int> widths;
153 for(int i = 0; i < text.length(); i++)
155 if(widthData)
156 widths.append(widthData[text[i].unicode() - firstChar]);
157 else
158 widths.append(maxWidth);
161 int totalWidth = 0;
162 for(int i = 0; i < widths.count(); i++)
163 totalWidth += widths[i];
165 QImage image(totalWidth, height, QImage::Format_Indexed8);
167 image.setColor(0, qRgba(0,0,0,0));
168 image.setColor(1, color.rgb());
170 /* Drawing the text */
171 int startX = 0;
172 for(int i = 0; i < text.length(); i++)
174 unsigned int offset;
175 if(offsetData)
176 offset = offsetData[text[i].unicode() - firstChar];
177 else
178 offset = (text[i].unicode() - firstChar) * maxWidth;
180 int bytesHigh = height / 8;
181 if(height % 8 > 0)
182 bytesHigh++;
184 int bytes = bytesHigh * widths[i];
186 for(int byte = 0; byte < bytes; byte++)
188 int x = startX + byte % widths[i];
189 int y = byte / widths[i] * 8;
190 quint8 data = imageData[offset];
191 quint8 mask = 0x1;
192 for(int bit = 0; bit < 8; bit++)
194 if(mask & data)
195 image.setPixel(x, y, 1);
196 else
197 image.setPixel(x, y, 0);
199 y++;
200 mask <<= 1;
201 if(y >= height)
202 break;
205 offset++;
208 startX += widths[i];
211 return new RBText(image, parent);