Theme Editor: WorkingWorking on speeding up the renderer, replaced for-loops with...
[kugel-rb.git] / utils / themeeditor / graphics / rbfont.cpp
blob07308fac7efe5a62214e8130e3450872fdf3c1cf
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>
30 #include <QSettings>
32 quint16 RBFont::maxFontSizeFor16BitOffsets = 0xFFDB;
34 RBFont::RBFont(QString file)
35 : valid(false), imageData(0), offsetData(0), widthData(0)
38 /* Attempting to locate the correct file name */
39 if(!QFile::exists(file))
41 /* Checking in the fonts repository */
42 QSettings settings;
43 settings.beginGroup("RBFont");
45 file = file.split("/").last();
46 file = settings.value("fontDir", "").toString() + "/" + file;
48 settings.endGroup();
50 if(!QFile::exists(file))
51 file = ":/fonts/08-Schumacher-Clean.fnt";
53 header.insert("filename", file);
55 /* Opening the file */
56 QFile fin(file);
57 fin.open(QFile::ReadOnly);
59 /* Loading the header info */
60 quint8 byte;
61 quint16 word;
62 quint32 dword;
64 QDataStream data(&fin);
65 data.setByteOrder(QDataStream::LittleEndian);
67 /* Grabbing the magic number and version */
68 data >> dword;
69 header.insert("version", dword);
71 /* Max font width */
72 data >> word;
73 header.insert("maxwidth", word);
75 /* Font height */
76 data >> word;
77 header.insert("height", word);
79 /* Ascent */
80 data >> word;
81 header.insert("ascent", word);
83 /* Padding */
84 data >> word;
86 /* First character code */
87 data >> dword;
88 header.insert("firstchar", dword);
90 /* Default character code */
91 data >> dword;
92 header.insert("defaultchar", dword);
94 /* Number of characters */
95 data >> dword;
96 header.insert("size", dword);
98 /* Bytes of imagebits in file */
99 data >> dword;
100 header.insert("nbits", dword);
102 /* Longs (dword) of offset data in file */
103 data >> dword;
104 header.insert("noffset", dword);
106 /* Bytes of width data in file */
107 data >> dword;
108 header.insert("nwidth", dword);
110 /* Loading the image data */
111 imageData = new quint8[header.value("nbits").toInt()];
112 data.readRawData(reinterpret_cast<char*>(imageData),
113 header.value("nbits").toInt());
115 /* Aligning on 16-bit boundary */
116 if(header.value("nbits").toInt() % 2 == 1)
117 data >> byte;
119 /* Loading the offset table if necessary */
120 if(header.value("noffset").toInt() > 0)
122 offsetData = new quint16[header.value("noffset").toInt()];
123 data.readRawData(reinterpret_cast<char*>(offsetData),
124 header.value("noffset").toInt() * 2);
127 /* Loading the width table if necessary */
128 if(header.value("nwidth").toInt() > 0)
130 widthData = new quint8[header.value("nwidth").toInt()];
131 data.readRawData(reinterpret_cast<char*>(widthData),
132 header.value("nwidth").toInt());
135 fin.close();
139 RBFont::~RBFont()
141 if(imageData)
142 delete[] imageData;
143 if(offsetData)
144 delete[] offsetData;
145 if(widthData)
146 delete[] widthData;
149 RBText* RBFont::renderText(QString text, QColor color, int viewWidth,
150 QGraphicsItem *parent)
152 int firstChar = header.value("firstchar").toInt();
153 int height = header.value("height").toInt();
154 int maxWidth = header.value("maxwidth").toInt();
156 /* First we determine the width of the combined text */
157 QList<int> widths;
158 for(int i = 0; i < text.length(); i++)
160 if(widthData)
161 widths.append(widthData[text[i].unicode() - firstChar]);
162 else
163 widths.append(maxWidth);
166 int totalWidth = 0;
167 for(int i = 0; i < widths.count(); i++)
168 totalWidth += widths[i];
170 QImage image(totalWidth, height, QImage::Format_Indexed8);
172 image.setColor(0, qRgba(0,0,0,0));
173 image.setColor(1, color.rgb());
175 /* Drawing the text */
176 int startX = 0;
177 for(int i = 0; i < text.length(); i++)
179 unsigned int offset;
180 if(offsetData)
181 offset = offsetData[text[i].unicode() - firstChar];
182 else
183 offset = (text[i].unicode() - firstChar) * maxWidth;
185 int bytesHigh = height / 8;
186 if(height % 8 > 0)
187 bytesHigh++;
189 int bytes = bytesHigh * widths[i];
191 for(int byte = 0; byte < bytes; byte++)
193 int x = startX + byte % widths[i];
194 int y = byte / widths[i] * 8;
195 quint8 data = imageData[offset];
196 quint8 mask = 0x1;
197 for(int bit = 0; bit < 8; bit++)
199 if(mask & data)
200 image.setPixel(x, y, 1);
201 else
202 image.setPixel(x, y, 0);
204 y++;
205 mask <<= 1;
206 if(y >= height)
207 break;
210 offset++;
213 startX += widths[i];
216 return new RBText(image, viewWidth, parent);