/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * 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 "rbfont.h" #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 */ if(!QFile::exists(file)) { /* Checking in the fonts repository */ QSettings settings; settings.beginGroup("RBFont"); file = file.split("/").last(); file = settings.value("fontDir", "").toString() + "/" + file; settings.endGroup(); if(!QFile::exists(file)) file = ":/fonts/08-Schumacher-Clean.fnt"; } header.insert("filename", file); /* Opening the file */ QFile fin(file); fin.open(QFile::ReadOnly); /* Loading the header info */ quint8 byte; quint16 word; quint32 dword; QDataStream data(&fin); data.setByteOrder(QDataStream::LittleEndian); /* Grabbing the magic number and version */ data >> dword; header.insert("version", dword); /* Max font width */ data >> word; header.insert("maxwidth", word); /* Font height */ data >> word; header.insert("height", word); /* Ascent */ data >> word; header.insert("ascent", word); /* Padding */ data >> word; /* First character code */ data >> dword; header.insert("firstchar", dword); /* Default character code */ data >> dword; header.insert("defaultchar", dword); /* Number of characters */ data >> dword; header.insert("size", dword); /* Bytes of imagebits in file */ data >> dword; header.insert("nbits", dword); /* Longs (dword) of offset data in file */ data >> dword; header.insert("noffset", dword); /* Bytes of width data in file */ data >> dword; header.insert("nwidth", dword); /* 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(); } RBFont::~RBFont() { if(imageData) delete[] imageData; if(offsetData) delete[] offsetData; if(widthData) delete[] widthData; } RBText* RBFont::renderText(QString text, QColor color, QGraphicsItem *parent) { 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); }