From 0eacfb26c4c94c9394fbddd967cc362b06a8d948 Mon Sep 17 00:00:00 2001 From: bieber Date: Tue, 6 Jul 2010 19:19:11 +0000 Subject: [PATCH] Theme Editor: Rockbox FNT files now supported. Theme editor will currently load fonts from the current project directory, or use the built-in font if they're not present git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27318 a1c6a512-1295-4272-9138-f99709370657 --- utils/themeeditor/graphics/rbfont.cpp | 126 +++++++++++++++++++-- utils/themeeditor/graphics/rbfont.h | 14 ++- .../themeeditor/graphics/{rbfont.h => rbtext.cpp} | 34 +++--- utils/themeeditor/graphics/{rbfont.h => rbtext.h} | 28 +++-- utils/themeeditor/graphics/rbviewport.cpp | 8 +- utils/themeeditor/themeeditor.pro | 6 +- 6 files changed, 163 insertions(+), 53 deletions(-) copy utils/themeeditor/graphics/{rbfont.h => rbtext.cpp} (66%) copy utils/themeeditor/graphics/{rbfont.h => rbtext.h} (70%) diff --git a/utils/themeeditor/graphics/rbfont.cpp b/utils/themeeditor/graphics/rbfont.cpp index 3988fbc64..e59c79a97 100644 --- a/utils/themeeditor/graphics/rbfont.cpp +++ b/utils/themeeditor/graphics/rbfont.cpp @@ -24,10 +24,14 @@ #include #include #include +#include +#include +#include -#include +quint16 RBFont::maxFontSizeFor16BitOffsets = 0xFFDB; RBFont::RBFont(QString file) + : valid(false), imageData(0), offsetData(0), widthData(0) { /* Attempting to locate the correct file name */ @@ -40,6 +44,7 @@ RBFont::RBFont(QString file) fin.open(QFile::ReadOnly); /* Loading the header info */ + quint8 byte; quint16 word; quint32 dword; @@ -89,23 +94,120 @@ RBFont::RBFont(QString file) data >> dword; header.insert("nwidth", dword); - fin.close(); + /* Loading the image data */ + imageData = new quint8[header.value("nbits").toInt()]; + for(int i = 0; i < header.value("nbits").toInt(); i++) + { + data >> byte; + imageData[i] = byte; + } + + /* Aligning on 16-bit boundary */ + if(header.value("nbits").toInt() % 2 == 1) + data >> byte; + + /* Loading the offset table if necessary */ + if(header.value("noffset").toInt() > 0) + { + offsetData = new quint16[header.value("noffset").toInt()]; + for(int i = 0; i < header.value("noffset").toInt(); i++) + { + data >> word; + offsetData[i] = word; + } + } + + /* Loading the width table if necessary */ + if(header.value("nwidth").toInt() > 0) + { + widthData = new quint8[header.value("nwidth").toInt()]; + for(int i = 0; i < header.value("nwidth").toInt(); i++) + { + data >> byte; + widthData[i] = byte; + } + } + + fin.close(); - qDebug() << header ; } RBFont::~RBFont() { + if(imageData) + delete[] imageData; + if(offsetData) + delete[] offsetData; + if(widthData) + delete[] widthData; } -QGraphicsSimpleTextItem* RBFont::renderText(QString text, QColor color, - QGraphicsItem *parent) +RBText* RBFont::renderText(QString text, QColor color, QGraphicsItem *parent) { - QGraphicsSimpleTextItem* retval = new QGraphicsSimpleTextItem(text, parent); - QFont font; - font.setFixedPitch(true); - font.setPixelSize(8); - retval->setFont(font); - retval->setBrush(QBrush(color)); - return retval; + int firstChar = header.value("firstchar").toInt(); + int height = header.value("height").toInt(); + int maxWidth = header.value("maxwidth").toInt(); + + /* First we determine the width of the combined text */ + QList widths; + for(int i = 0; i < text.length(); i++) + { + if(widthData) + widths.append(widthData[text[i].unicode() - firstChar]); + else + widths.append(maxWidth); + } + + int totalWidth = 0; + for(int i = 0; i < widths.count(); i++) + totalWidth += widths[i]; + + QImage image(totalWidth, height, QImage::Format_Indexed8); + + image.setColor(0, qRgba(0,0,0,0)); + image.setColor(1, color.rgb()); + + /* Drawing the text */ + int startX = 0; + for(int i = 0; i < text.length(); i++) + { + unsigned int offset; + if(offsetData) + offset = offsetData[text[i].unicode() - firstChar]; + else + offset = (text[i].unicode() - firstChar) * maxWidth; + + int bytesHigh = height / 8; + if(height % 8 > 0) + bytesHigh++; + + int bytes = bytesHigh * widths[i]; + + for(int byte = 0; byte < bytes; byte++) + { + int x = startX + byte % widths[i]; + int y = byte / widths[i] * 8; + quint8 data = imageData[offset]; + quint8 mask = 0x1; + for(int bit = 0; bit < 8; bit++) + { + if(mask & data) + image.setPixel(x, y, 1); + else + image.setPixel(x, y, 0); + + y++; + mask <<= 1; + if(y >= height) + break; + } + + offset++; + } + + startX += widths[i]; + } + + return new RBText(image, parent); + } diff --git a/utils/themeeditor/graphics/rbfont.h b/utils/themeeditor/graphics/rbfont.h index 2c1f8a9dc..bc695a070 100644 --- a/utils/themeeditor/graphics/rbfont.h +++ b/utils/themeeditor/graphics/rbfont.h @@ -24,21 +24,29 @@ #include #include -#include +#include #include +#include "rbtext.h" + class RBFont { public: RBFont(QString file); virtual ~RBFont(); - QGraphicsSimpleTextItem* renderText(QString text, QColor color, + RBText* renderText(QString text, QColor color, QGraphicsItem* parent = 0); - int lineHeight(){ return 8; } + int lineHeight(){ return header.value("height", 0).toInt(); } + + static quint16 maxFontSizeFor16BitOffsets; private: QHash header; + bool valid; + quint8* imageData; + quint16* offsetData; + quint8* widthData; }; #endif // RBFONT_H diff --git a/utils/themeeditor/graphics/rbfont.h b/utils/themeeditor/graphics/rbtext.cpp similarity index 66% copy from utils/themeeditor/graphics/rbfont.h copy to utils/themeeditor/graphics/rbtext.cpp index 2c1f8a9dc..76b817793 100644 --- a/utils/themeeditor/graphics/rbfont.h +++ b/utils/themeeditor/graphics/rbtext.cpp @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id$ + * $Id: rbfont.cpp 27301 2010-07-05 22:15:17Z bieber $ * * Copyright (C) 2010 Robert Bieber * @@ -19,26 +19,22 @@ * ****************************************************************************/ -#ifndef RBFONT_H -#define RBFONT_H +#include "rbtext.h" -#include -#include -#include -#include +#include -class RBFont +RBText::RBText(const QImage &image, QGraphicsItem *parent) + :QGraphicsItem(parent), image(image) { -public: - RBFont(QString file); - virtual ~RBFont(); +} - QGraphicsSimpleTextItem* renderText(QString text, QColor color, - QGraphicsItem* parent = 0); - int lineHeight(){ return 8; } - -private: - QHash header; -}; +QRectF RBText::boundingRect() const +{ + return QRectF(0, 0, image.width(), image.height()); +} -#endif // RBFONT_H +void RBText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + painter->drawImage(0, 0, image, 0, 0, image.width(), image.height()); +} diff --git a/utils/themeeditor/graphics/rbfont.h b/utils/themeeditor/graphics/rbtext.h similarity index 70% copy from utils/themeeditor/graphics/rbfont.h copy to utils/themeeditor/graphics/rbtext.h index 2c1f8a9dc..37b174770 100644 --- a/utils/themeeditor/graphics/rbfont.h +++ b/utils/themeeditor/graphics/rbtext.h @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id$ + * $Id: rbfont.cpp 27301 2010-07-05 22:15:17Z bieber $ * * Copyright (C) 2010 Robert Bieber * @@ -19,26 +19,24 @@ * ****************************************************************************/ -#ifndef RBFONT_H -#define RBFONT_H +#ifndef RBTEXT_H +#define RBTEXT_H -#include -#include -#include -#include +#include +#include -class RBFont +class RBText : public QGraphicsItem { public: - RBFont(QString file); - virtual ~RBFont(); + RBText(const QImage& image, QGraphicsItem* parent); - QGraphicsSimpleTextItem* renderText(QString text, QColor color, - QGraphicsItem* parent = 0); - int lineHeight(){ return 8; } + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget); private: - QHash header; + QImage image; + }; -#endif // RBFONT_H +#endif // RBTEXT_H diff --git a/utils/themeeditor/graphics/rbviewport.cpp b/utils/themeeditor/graphics/rbviewport.cpp index a92825362..3b8a02dd8 100644 --- a/utils/themeeditor/graphics/rbviewport.cpp +++ b/utils/themeeditor/graphics/rbviewport.cpp @@ -30,8 +30,7 @@ #include "skin_parser.h" RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info) - : QGraphicsItem(info.screen()), font(info.screen()->getFont(0)), - foreground(info.screen()->foreground()), + : QGraphicsItem(info.screen()), foreground(info.screen()->foreground()), background(info.screen()->background()), textOffset(0,0), screen(info.screen()), textAlign(Left), showStatusBar(false), statusBarTexture(":/render/statusbar.png") @@ -42,6 +41,7 @@ RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info) size = QRectF(0, 0, info.screen()->getWidth(), info.screen()->getHeight()); customUI = false; + font = screen->getFont(1); if(info.model()->rowCount(QModelIndex()) > 1) { @@ -120,6 +120,10 @@ RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info) y -= screen->parentItem()->pos().y(); } + if(node->params[++param].type == skin_tag_parameter::DEFAULT) + font = screen->getFont(1); + else + font = screen->getFont(node->params[param].data.numeric); setPos(x, y); size = QRectF(0, 0, w, h); diff --git a/utils/themeeditor/themeeditor.pro b/utils/themeeditor/themeeditor.pro index 424159856..8a16fa926 100644 --- a/utils/themeeditor/themeeditor.pro +++ b/utils/themeeditor/themeeditor.pro @@ -43,7 +43,8 @@ HEADERS += models/parsetreemodel.h \ gui/devicestate.h \ graphics/rbalbumart.h \ graphics/rbprogressbar.h \ - gui/findreplacedialog.h + gui/findreplacedialog.h \ + graphics/rbtext.h SOURCES += main.cpp \ models/parsetreemodel.cpp \ models/parsetreenode.cpp \ @@ -63,7 +64,8 @@ SOURCES += main.cpp \ gui/devicestate.cpp \ graphics/rbalbumart.cpp \ graphics/rbprogressbar.cpp \ - gui/findreplacedialog.cpp + gui/findreplacedialog.cpp \ + graphics/rbtext.cpp OTHER_FILES += README \ resources/windowicon.png \ resources/appicon.xcf \ -- 2.11.4.GIT