diff options
Diffstat (limited to 'kioslave/thumbnail/textcreator.cpp')
-rw-r--r-- | kioslave/thumbnail/textcreator.cpp | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/kioslave/thumbnail/textcreator.cpp b/kioslave/thumbnail/textcreator.cpp new file mode 100644 index 000000000..b0424e228 --- /dev/null +++ b/kioslave/thumbnail/textcreator.cpp @@ -0,0 +1,195 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000,2002 Carsten Pfeiffer <pfeiffer@kde.org> + 2000 Malte Starostik <malte@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qfile.h> +#include <qpixmap.h> +#include <qimage.h> + +#include <kstandarddirs.h> +#include <kpixmapsplitter.h> +#include <kmimetype.h> + +#include "textcreator.h" + +extern "C" +{ + KDE_EXPORT ThumbCreator *new_creator() + { + return new TextCreator; + } +} + +TextCreator::TextCreator() + : m_splitter(0), + m_data(0), + m_dataSize(0) +{ +} + +TextCreator::~TextCreator() +{ + delete m_splitter; + delete [] m_data; +} + +bool TextCreator::create(const QString &path, int width, int height, QImage &img) +{ + // Filter out unwanted mimetypes + KMimeType::Ptr mimeType = KMimeType::findByPath( path ); + if ( mimeType->is( "text/rtf" ) ) + return false; + + if ( !m_splitter ) + { + m_splitter = new KPixmapSplitter; + QString pixmap = locate( "data", "konqueror/pics/thumbnailfont_7x4.png" ); + if ( !pixmap.isEmpty() ) + { + // FIXME: make font/glyphsize configurable... + m_splitter->setPixmap( QPixmap( pixmap )); + m_splitter->setItemSize( QSize( 4, 7 )); + } + } + + bool ok = false; + + // determine some sizes... + // example: width: 60, height: 64 + QSize pixmapSize( width, height ); + if (height * 3 > width * 4) + pixmapSize.setHeight( width * 4 / 3 ); + else + pixmapSize.setWidth( height * 3 / 4 ); + + if ( pixmapSize != m_pixmap.size() ) + m_pixmap.resize( pixmapSize ); + + // one pixel for the rectangle, the rest. whitespace + int xborder = 1 + pixmapSize.width()/16; // minimum x-border + int yborder = 1 + pixmapSize.height()/16; // minimum y-border + + QSize chSize = m_splitter->itemSize(); // the size of one char + int xOffset = chSize.width(); + int yOffset = chSize.height(); + + // calculate a better border so that the text is centered + int canvasWidth = pixmapSize.width() - 2*xborder; + int canvasHeight = pixmapSize.height() - 2*yborder; + int numCharsPerLine = (int) (canvasWidth / chSize.width()); + int numLines = (int) (canvasHeight / chSize.height()); + + // assumes an average line length of <= 120 chars + const int bytesToRead = 120 * numLines; + + // create text-preview + QFile file( path ); + if ( file.open( IO_ReadOnly )) + { + if ( !m_data || m_dataSize < bytesToRead + 1 ) + { + delete [] m_data; + m_data = new char[bytesToRead+1]; + m_dataSize = bytesToRead + 1; + } + + int read = file.readBlock( m_data, bytesToRead ); + if ( read > 0 ) + { + ok = true; + m_data[read] = '\0'; + QString text = QString::fromLocal8Bit( m_data ); + // FIXME: maybe strip whitespace and read more? + + m_pixmap.fill( QColor( 245, 245, 245 ) ); // light-grey background + + QRect rect; + + int rest = m_pixmap.width() - (numCharsPerLine * chSize.width()); + xborder = QMAX( xborder, rest/2); // center horizontally + rest = m_pixmap.height() - (numLines * chSize.height()); + yborder = QMAX( yborder, rest/2); // center vertically + // end centering + + int x = xborder, y = yborder; // where to paint the characters + int posNewLine = m_pixmap.width() - (chSize.width() + xborder); + int posLastLine = m_pixmap.height() - (chSize.height() + yborder); + bool newLine = false; + Q_ASSERT( posNewLine > 0 ); + const QPixmap *fontPixmap = &(m_splitter->pixmap()); + + for ( uint i = 0; i < text.length(); i++ ) + { + if ( x > posNewLine || newLine ) // start a new line? + { + x = xborder; + y += yOffset; + + if ( y > posLastLine ) // more text than space + break; + + // after starting a new line, we also jump to the next + // physical newline in the file if we don't come from one + if ( !newLine ) + { + int pos = text.find( '\n', i ); + if ( pos == -1 ) + break; + i = pos + 1; + } + + newLine = false; + } + + // check for newlines in the text (unix,dos) + QChar ch = text.at( i ); + if ( ch == '\n' ) + { + newLine = true; + continue; + } + else if ( ch == '\r' && text.at(i+1) == '\n' ) + { + newLine = true; + i++; // skip the next character (\n) as well + continue; + } + + rect = m_splitter->coordinates( ch ); + if ( !rect.isEmpty() ) + { + bitBlt( &m_pixmap, QPoint(x,y), fontPixmap, rect, Qt::CopyROP ); + } + + x += xOffset; // next character + } + if (ok) + img = m_pixmap.convertToImage(); + } + + file.close(); + } + return ok; +} + +ThumbCreator::Flags TextCreator::flags() const +{ + return (Flags)(DrawFrame | BlendIcon); +} + |