add more spacing
[personal-kdebase.git] / runtime / kioslave / thumbnail / textcreator.cpp
blob5e5601ad0699b5686d7846e23deffa575dae2402
1 /* This file is part of the KDE libraries
2 Copyright (C) 2000,2002 Carsten Pfeiffer <pfeiffer@kde.org>
3 2000 Malte Starostik <malte@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 #include "textcreator.h"
23 #include <QFile>
24 #include <QPixmap>
25 #include <QImage>
26 #include <QPainter>
28 #include <kstandarddirs.h>
30 class FontSplitter {
31 public:
32 FontSplitter() {}
33 virtual ~FontSplitter() {}
35 protected:
36 int m_width;
37 QSize m_itemSize;
38 QPixmap m_pixmap;
40 public:
41 void setPixmap(const QPixmap &pixmap) { m_pixmap = pixmap; }
42 const QPixmap& pixmap() const { return m_pixmap; }
44 void setItemSize(const QSize &size) { m_itemSize = size; }
45 const QSize& itemSize() const { return m_itemSize; }
47 QRect coordinates(const QChar& ch) const {
48 int pos = (unsigned char)ch.toLatin1();
49 int numCols = m_pixmap.width() / m_itemSize.width();
50 if ( numCols == 0 )
51 return QRect();
52 int row = pos / numCols;
53 int col = pos % numCols;
54 return QRect( QPoint( col * m_itemSize.width(), row * m_itemSize.height() ),
55 m_itemSize );
59 extern "C"
61 KDE_EXPORT ThumbCreator *new_creator()
63 return new TextCreator;
67 TextCreator::TextCreator()
68 : m_splitter(0),
69 m_data(0),
70 m_dataSize(0)
74 TextCreator::~TextCreator()
76 delete m_splitter;
77 delete [] m_data;
80 bool TextCreator::create(const QString &path, int width, int height, QImage &img)
82 if ( !m_splitter )
84 m_splitter = new FontSplitter;
85 QString pixmap = KStandardDirs::locate( "data", "kio_thumbnail/pics/thumbnailfont_7x4.png" );
86 if ( !pixmap.isEmpty() )
88 // FIXME: make font/glyphsize configurable...
89 m_splitter->setPixmap( QPixmap( pixmap ));
90 m_splitter->setItemSize( QSize( 4, 7 ));
94 bool ok = false;
96 // determine some sizes...
97 // example: width: 60, height: 64
98 QSize pixmapSize( width, height );
99 if (height * 3 > width * 4)
100 pixmapSize.setHeight( width * 4 / 3 );
101 else
102 pixmapSize.setWidth( height * 3 / 4 );
104 if ( pixmapSize != m_pixmap.size() )
105 m_pixmap = QPixmap( pixmapSize );
107 // one pixel for the rectangle, the rest. whitespace
108 int xborder = 1 + pixmapSize.width()/16; // minimum x-border
109 int yborder = 1 + pixmapSize.height()/16; // minimum y-border
111 QSize chSize = m_splitter->itemSize(); // the size of one char
112 int xOffset = chSize.width();
113 int yOffset = chSize.height();
115 // calculate a better border so that the text is centered
116 int canvasWidth = pixmapSize.width() - 2*xborder;
117 int canvasHeight = pixmapSize.height() - 2*yborder;
118 int numCharsPerLine = (int) (canvasWidth / chSize.width());
119 int numLines = (int) (canvasHeight / chSize.height());
121 // assumes an average line length of <= 120 chars
122 const int bytesToRead = 120 * numLines;
124 // create text-preview
125 QFile file( path );
126 if ( file.open( QIODevice::ReadOnly ))
128 if ( !m_data || m_dataSize < bytesToRead + 1 )
130 delete [] m_data;
131 m_data = new char[bytesToRead+1];
132 m_dataSize = bytesToRead + 1;
135 int read = file.read( m_data, bytesToRead );
136 if ( read > 0 )
138 ok = true;
139 m_data[read] = '\0';
140 QString text = QString::fromLocal8Bit( m_data );
141 // FIXME: maybe strip whitespace and read more?
143 m_pixmap.fill( QColor( 245, 245, 245 ) ); // light-grey background
145 QRect rect;
147 int rest = m_pixmap.width() - (numCharsPerLine * chSize.width());
148 xborder = qMax( xborder, rest/2); // center horizontally
149 rest = m_pixmap.height() - (numLines * chSize.height());
150 yborder = qMax( yborder, rest/2); // center vertically
151 // end centering
153 int x = xborder, y = yborder; // where to paint the characters
154 int posNewLine = m_pixmap.width() - (chSize.width() + xborder);
155 int posLastLine = m_pixmap.height() - (chSize.height() + yborder);
156 bool newLine = false;
157 Q_ASSERT( posNewLine > 0 );
158 const QPixmap *fontPixmap = &(m_splitter->pixmap());
159 QPainter painter( &m_pixmap );
161 for ( int i = 0; i < text.length(); i++ )
163 if ( x > posNewLine || newLine ) // start a new line?
165 x = xborder;
166 y += yOffset;
168 if ( y > posLastLine ) // more text than space
169 break;
171 // after starting a new line, we also jump to the next
172 // physical newline in the file if we don't come from one
173 if ( !newLine )
175 int pos = text.indexOf( '\n', i );
176 if ( pos == -1 )
177 break;
178 i = pos + 1;
181 newLine = false;
184 if (i>=text.length()) continue;
185 // check for newlines in the text (unix,dos)
186 QChar ch = text.at( i );
187 if ( ch == '\n' )
189 newLine = true;
190 continue;
192 else if ( ch == '\r' && text.at(i+1) == '\n' )
194 newLine = true;
195 i++; // skip the next character (\n) as well
196 continue;
199 rect = m_splitter->coordinates( ch );
200 if ( !rect.isEmpty() )
202 painter.drawPixmap( QPoint(x,y), *fontPixmap, rect );
205 x += xOffset; // next character
207 if (ok)
208 img = m_pixmap.toImage();
211 file.close();
213 return ok;
216 ThumbCreator::Flags TextCreator::flags() const
218 return (Flags)(DrawFrame | BlendIcon);