/* * Asciiquarium - Native KDE Screensaver based on the Asciiquarium program * (c) Kirk Baucom , which you can find at * http://www.robobunny.com/projects/asciiquarium/ * * Ported to KDE by Maksim Orlovich and * Michael Pyne . * * Copyright (c) 2003 Kirk Baucom * Copyright (c) 2005 Maksim Orlovich * Copyright (c) 2005 Michael Pyne * * 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 program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "frame.h" void Frame::convertDataToPixmap(const Screen *screen) { if(!height() || !width()) { // Assume we're not ready to go. return; } int w = screen->cellWidth(), h = screen->cellHeight(); TQPixmap pix(width() * w, height() * h); pix.fill(); TQBitmap mask(pix.size(), true); TQPainter p, p2; p.begin(&pix, true); p2.begin(&mask, true); p.setFont(TDEGlobalSettings::fixedFont()); TQFontMetrics fm(p.font()); int leadHeight = fm.leading() + fm.descent(); for(unsigned j = 0; j < m_data.count(); ++j) { TQValueVector row = m_data[j]; if(row.isEmpty()) continue; unsigned first, last; for (first = 0; first < row.count() && row[first].letter == ' '; ++first) ; last = row.count() - 1; // Assume the end is already stripped. for(unsigned i = first; i <= last; ++i) { if(row[i].letter == m_transparentChar) continue; p2.fillRect(i * w, j * h, w, h, TQt::color1); p.setPen(row[i].color); p.fillRect(i * w, j * h, w, h, TQt::black); p.drawText(i * w, j * h + (h - 1 - leadHeight), TQChar(row[i].letter)); } } pix.setMask(mask); TQPixmap erase(pix); erase.fill(TQt::black); erase.setMask(mask); m_pixmap = pix; m_erasePixmap = erase; // Clear m_data to save a wee bit of memory. m_data.clear(); } Frame::Frame (TQString text, TQString mask, TQRgb defaultColor, TQChar transparent) { //First, process the pixels. TQStringList rows = TQStringList::split('\n', text, true); m_height = rows.size(); m_width = 0; m_transparentChar = transparent; for (TQStringList::iterator i = rows.begin(); i != rows.end(); ++i) { TQValueVector row; for (int pos = 0; pos < (*i).length(); ++pos) { Screen::Pixel p; p.letter = (*i).at(pos).unicode(); p.color = defaultColor; row.append(p); } m_width = TQMAX(m_width, row.size()); m_data.append(row); } //Now, the colors. TQStringList cols = TQStringList::split('\n', mask, true); int y = 0; for (TQStringList::iterator i = cols.begin(); i != cols.end(); ++i) { if (y >= m_data.size()) break; for (int pos = 0; pos < (*i).length() && pos < m_data[y].size(); ++pos) { switch ((*i).at(pos).unicode()) { //Colors stolen from konsole, TEWidget.cpp case 'R': m_data[y][pos].color = 0xFF5454; break; case 'r': m_data[y][pos].color = 0xB21818; break; case 'C': m_data[y][pos].color = 0x54FFFF; break; case 'c': m_data[y][pos].color = 0x18B2B2; break; case 'Y': m_data[y][pos].color = 0xFFFF54; break; case 'y': m_data[y][pos].color = 0xB26818; break; case 'G': m_data[y][pos].color = 0x54FF54; break; case 'g': m_data[y][pos].color = 0x18B218; break; case 'B': m_data[y][pos].color = 0x5454FF; break; case 'b': m_data[y][pos].color = 0x1818B2; break; case 'M': m_data[y][pos].color = 0xFF54FF; break; case 'm': m_data[y][pos].color = 0xB218B2; break; case 'W': m_data[y][pos].color = 0xFFFFFF; break; case 'w': m_data[y][pos].color = 0xB2B2B2; break; case ' ': break; default: tqDebug("dunno about color code:'%c'", (*i).at(pos).unicode()); m_data[y][pos].color = 0xFFFFFF; } } ++y; } } void Frame::paint(Screen* scr, int x, int y) { if(m_pixmap.isNull()) convertDataToPixmap(scr); scr->updateSpan(x, y, m_pixmap); } void Frame::erase(Screen* scr, int x, int y) { if(m_erasePixmap.isNull()) convertDataToPixmap(scr); scr->clearSpan(x, y, m_erasePixmap); } // vim: set et ts=8 sw=4: