1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #include "rbfontcache.h"
24 #include "rbtextcache.h"
36 quint16
RBFont::maxFontSizeFor16BitOffsets
= 0xFFDB;
38 RBFont::RBFont(QString file
)
39 : valid(false), imageData(0), offsetData(0), widthData(0)
44 /* Attempting to locate the correct file name */
45 if(!QFile::exists(file
))
47 /* Checking in the fonts repository */
49 settings
.beginGroup("RBFont");
51 file
= file
.split("/").last();
52 file
= settings
.value("fontDir", "").toString() + "/" + file
;
56 if(!QFile::exists(file
))
58 file
= ":/fonts/08-Schumacher-Clean.fnt";
63 header
.insert("filename", file
);
65 /* Checking for a cache entry */
66 RBFontCache::CacheInfo
* cache
= RBFontCache::lookup(file
);
69 imageData
= cache
->imageData
;
70 offsetData
= cache
->offsetData
;
71 widthData
= cache
->widthData
;
72 header
= cache
->header
;
80 /* Opening the file */
82 fin
.open(QFile::ReadOnly
);
84 /* Loading the header info */
89 QDataStream
data(&fin
);
90 data
.setByteOrder(QDataStream::LittleEndian
);
92 /* Grabbing the magic number and version */
94 header
.insert("version", dword
);
98 header
.insert("maxwidth", word
);
102 header
.insert("height", word
);
106 header
.insert("ascent", word
);
111 /* First character code */
113 header
.insert("firstchar", dword
);
115 /* Default character code */
117 header
.insert("defaultchar", dword
);
119 /* Number of characters */
121 header
.insert("size", dword
);
123 /* Bytes of imagebits in file */
125 header
.insert("nbits", dword
);
127 /* Longs (dword) of offset data in file */
129 header
.insert("noffset", dword
);
131 /* Bytes of width data in file */
133 header
.insert("nwidth", dword
);
135 /* Loading the image data */
136 imageData
= new quint8
[header
.value("nbits").toInt()];
137 data
.readRawData(reinterpret_cast<char*>(imageData
),
138 header
.value("nbits").toInt());
140 /* Aligning on 16-bit boundary */
141 if(header
.value("nbits").toInt() % 2 == 1)
144 /* Loading the offset table if necessary */
145 if(header
.value("noffset").toInt() > 0)
148 if(header
.value("nbits").toInt() > maxFontSizeFor16BitOffsets
)
149 bytesToRead
= 4 * header
.value("noffset").toInt();
151 bytesToRead
= 2 * header
.value("noffset").toInt();
152 offsetData
= new quint16
[bytesToRead
];
153 data
.readRawData(reinterpret_cast<char*>(offsetData
), bytesToRead
);
156 /* Loading the width table if necessary */
157 if(header
.value("nwidth").toInt() > 0)
159 widthData
= new quint8
[header
.value("nwidth").toInt()];
160 data
.readRawData(reinterpret_cast<char*>(widthData
),
161 header
.value("nwidth").toInt());
166 /* Caching the font data */
167 cache
= new RBFontCache::CacheInfo
;
168 cache
->imageData
= imageData
;
169 cache
->offsetData
= offsetData
;
170 cache
->widthData
= widthData
;
171 cache
->header
= header
;
172 RBFontCache::insert(file
, cache
);
183 RBText
* RBFont::renderText(QString text
, QColor color
, int viewWidth
,
184 QGraphicsItem
*parent
)
187 /* Checking for a cache hit first */
188 QImage
* image
= RBTextCache::lookup(header
.value("filename").toString()
191 return new RBText(image
, viewWidth
, parent
);
193 int firstChar
= header
.value("firstchar").toInt();
194 int height
= header
.value("height").toInt();
195 int maxWidth
= header
.value("maxwidth").toInt();
197 bool extendedSet
= header
.value("nbits").
198 toUInt() > maxFontSizeFor16BitOffsets
;
200 /* First we determine the width of the combined text */
202 for(int i
= 0; i
< text
.length(); i
++)
205 widths
.append(widthData
[text
[i
].unicode() - firstChar
]);
207 widths
.append(maxWidth
);
211 for(int i
= 0; i
< widths
.count(); i
++)
212 totalWidth
+= widths
[i
];
214 image
= new QImage(totalWidth
, height
, QImage::Format_Indexed8
);
216 image
->setColor(0, qRgba(0,0,0,0));
217 image
->setColor(1, color
.rgb());
219 /* Drawing the text */
221 for(int i
= 0; i
< text
.length(); i
++)
227 offset
= reinterpret_cast<quint32
*>(offsetData
)[text
[i
].unicode() - firstChar
];
229 offset
= offsetData
[text
[i
].unicode() - firstChar
];
233 offset
= (text
[i
].unicode() - firstChar
) * maxWidth
;
236 int bytesHigh
= height
/ 8;
240 int bytes
= bytesHigh
* widths
[i
];
242 for(int byte
= 0; byte
< bytes
; byte
++)
244 int x
= startX
+ byte
% widths
[i
];
245 int y
= byte
/ widths
[i
] * 8;
246 quint8 data
= imageData
[offset
];
248 for(int bit
= 0; bit
< 8; bit
++)
251 image
->setPixel(x
, y
, 1);
253 image
->setPixel(x
, y
, 0);
267 RBTextCache::insert(header
.value("filename").toString() + text
, image
);
268 return new RBText(image
, viewWidth
, parent
);