forked from len0rd/rockbox
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
This commit is contained in:
parent
5de6ddcaa1
commit
39e252019f
6 changed files with 217 additions and 19 deletions
|
@ -24,10 +24,14 @@
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QBitmap>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
#include <QDebug>
|
quint16 RBFont::maxFontSizeFor16BitOffsets = 0xFFDB;
|
||||||
|
|
||||||
RBFont::RBFont(QString file)
|
RBFont::RBFont(QString file)
|
||||||
|
: valid(false), imageData(0), offsetData(0), widthData(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Attempting to locate the correct file name */
|
/* Attempting to locate the correct file name */
|
||||||
|
@ -40,6 +44,7 @@ RBFont::RBFont(QString file)
|
||||||
fin.open(QFile::ReadOnly);
|
fin.open(QFile::ReadOnly);
|
||||||
|
|
||||||
/* Loading the header info */
|
/* Loading the header info */
|
||||||
|
quint8 byte;
|
||||||
quint16 word;
|
quint16 word;
|
||||||
quint32 dword;
|
quint32 dword;
|
||||||
|
|
||||||
|
@ -89,23 +94,120 @@ RBFont::RBFont(QString file)
|
||||||
data >> dword;
|
data >> dword;
|
||||||
header.insert("nwidth", 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()
|
RBFont::~RBFont()
|
||||||
{
|
{
|
||||||
|
if(imageData)
|
||||||
|
delete[] imageData;
|
||||||
|
if(offsetData)
|
||||||
|
delete[] offsetData;
|
||||||
|
if(widthData)
|
||||||
|
delete[] widthData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QGraphicsSimpleTextItem* RBFont::renderText(QString text, QColor color,
|
RBText* RBFont::renderText(QString text, QColor color, QGraphicsItem *parent)
|
||||||
QGraphicsItem *parent)
|
|
||||||
{
|
{
|
||||||
QGraphicsSimpleTextItem* retval = new QGraphicsSimpleTextItem(text, parent);
|
int firstChar = header.value("firstchar").toInt();
|
||||||
QFont font;
|
int height = header.value("height").toInt();
|
||||||
font.setFixedPitch(true);
|
int maxWidth = header.value("maxwidth").toInt();
|
||||||
font.setPixelSize(8);
|
|
||||||
retval->setFont(font);
|
/* First we determine the width of the combined text */
|
||||||
retval->setBrush(QBrush(color));
|
QList<int> widths;
|
||||||
return retval;
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,21 +24,29 @@
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QGraphicsSimpleTextItem>
|
#include <QGraphicsPixmapItem>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
|
#include "rbtext.h"
|
||||||
|
|
||||||
class RBFont
|
class RBFont
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RBFont(QString file);
|
RBFont(QString file);
|
||||||
virtual ~RBFont();
|
virtual ~RBFont();
|
||||||
|
|
||||||
QGraphicsSimpleTextItem* renderText(QString text, QColor color,
|
RBText* renderText(QString text, QColor color,
|
||||||
QGraphicsItem* parent = 0);
|
QGraphicsItem* parent = 0);
|
||||||
int lineHeight(){ return 8; }
|
int lineHeight(){ return header.value("height", 0).toInt(); }
|
||||||
|
|
||||||
|
static quint16 maxFontSizeFor16BitOffsets;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QString, QVariant> header;
|
QHash<QString, QVariant> header;
|
||||||
|
bool valid;
|
||||||
|
quint8* imageData;
|
||||||
|
quint16* offsetData;
|
||||||
|
quint8* widthData;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RBFONT_H
|
#endif // RBFONT_H
|
||||||
|
|
40
utils/themeeditor/graphics/rbtext.cpp
Normal file
40
utils/themeeditor/graphics/rbtext.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id: rbfont.cpp 27301 2010-07-05 22:15:17Z bieber $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Robert Bieber
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "rbtext.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
RBText::RBText(const QImage &image, QGraphicsItem *parent)
|
||||||
|
:QGraphicsItem(parent), image(image)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF RBText::boundingRect() const
|
||||||
|
{
|
||||||
|
return QRectF(0, 0, image.width(), image.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RBText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
|
QWidget *widget)
|
||||||
|
{
|
||||||
|
painter->drawImage(0, 0, image, 0, 0, image.width(), image.height());
|
||||||
|
}
|
42
utils/themeeditor/graphics/rbtext.h
Normal file
42
utils/themeeditor/graphics/rbtext.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id: rbfont.cpp 27301 2010-07-05 22:15:17Z bieber $
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Robert Bieber
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef RBTEXT_H
|
||||||
|
#define RBTEXT_H
|
||||||
|
|
||||||
|
#include <QGraphicsItem>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
class RBText : public QGraphicsItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RBText(const QImage& image, QGraphicsItem* parent);
|
||||||
|
|
||||||
|
QRectF boundingRect() const;
|
||||||
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
|
QWidget *widget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage image;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RBTEXT_H
|
|
@ -30,8 +30,7 @@
|
||||||
#include "skin_parser.h"
|
#include "skin_parser.h"
|
||||||
|
|
||||||
RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info)
|
RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info)
|
||||||
: QGraphicsItem(info.screen()), font(info.screen()->getFont(0)),
|
: QGraphicsItem(info.screen()), foreground(info.screen()->foreground()),
|
||||||
foreground(info.screen()->foreground()),
|
|
||||||
background(info.screen()->background()), textOffset(0,0),
|
background(info.screen()->background()), textOffset(0,0),
|
||||||
screen(info.screen()), textAlign(Left), showStatusBar(false),
|
screen(info.screen()), textAlign(Left), showStatusBar(false),
|
||||||
statusBarTexture(":/render/statusbar.png")
|
statusBarTexture(":/render/statusbar.png")
|
||||||
|
@ -42,6 +41,7 @@ RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info)
|
||||||
size = QRectF(0, 0, info.screen()->getWidth(),
|
size = QRectF(0, 0, info.screen()->getWidth(),
|
||||||
info.screen()->getHeight());
|
info.screen()->getHeight());
|
||||||
customUI = false;
|
customUI = false;
|
||||||
|
font = screen->getFont(1);
|
||||||
|
|
||||||
if(info.model()->rowCount(QModelIndex()) > 1)
|
if(info.model()->rowCount(QModelIndex()) > 1)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,10 @@ RBViewport::RBViewport(skin_element* node, const RBRenderInfo& info)
|
||||||
y -= screen->parentItem()->pos().y();
|
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);
|
setPos(x, y);
|
||||||
size = QRectF(0, 0, w, h);
|
size = QRectF(0, 0, w, h);
|
||||||
|
|
|
@ -43,7 +43,8 @@ HEADERS += models/parsetreemodel.h \
|
||||||
gui/devicestate.h \
|
gui/devicestate.h \
|
||||||
graphics/rbalbumart.h \
|
graphics/rbalbumart.h \
|
||||||
graphics/rbprogressbar.h \
|
graphics/rbprogressbar.h \
|
||||||
gui/findreplacedialog.h
|
gui/findreplacedialog.h \
|
||||||
|
graphics/rbtext.h
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
models/parsetreemodel.cpp \
|
models/parsetreemodel.cpp \
|
||||||
models/parsetreenode.cpp \
|
models/parsetreenode.cpp \
|
||||||
|
@ -63,7 +64,8 @@ SOURCES += main.cpp \
|
||||||
gui/devicestate.cpp \
|
gui/devicestate.cpp \
|
||||||
graphics/rbalbumart.cpp \
|
graphics/rbalbumart.cpp \
|
||||||
graphics/rbprogressbar.cpp \
|
graphics/rbprogressbar.cpp \
|
||||||
gui/findreplacedialog.cpp
|
gui/findreplacedialog.cpp \
|
||||||
|
graphics/rbtext.cpp
|
||||||
OTHER_FILES += README \
|
OTHER_FILES += README \
|
||||||
resources/windowicon.png \
|
resources/windowicon.png \
|
||||||
resources/appicon.xcf \
|
resources/appicon.xcf \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue