get rid of PaintUtils
the only one using it was PlasmaCore.IconItem, move the transition() function there
This commit is contained in:
parent
8df5da1c50
commit
99bab1825e
@ -19,15 +19,141 @@
|
|||||||
|
|
||||||
#include "iconitem.h"
|
#include "iconitem.h"
|
||||||
|
|
||||||
#include <KIconLoader>
|
#include <QDebug>
|
||||||
#include <KIconEffect>
|
#include <QPaintEngine>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
#include <KIconLoader>
|
||||||
|
#include <KIconEffect>
|
||||||
|
|
||||||
#include <plasma/paintutils.h>
|
#include <plasma/paintutils.h>
|
||||||
#include <plasma/svg.h>
|
#include <plasma/svg.h>
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
|
||||||
|
{
|
||||||
|
if (from.isNull() && to.isNull()) {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qFuzzyCompare(amount + 1, qreal(1.0))) {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect startRect(from.rect());
|
||||||
|
QRect targetRect(to.rect());
|
||||||
|
QSize pixmapSize = startRect.size().expandedTo(targetRect.size());
|
||||||
|
QRect toRect = QRect(QPoint(0,0), pixmapSize);
|
||||||
|
targetRect.moveCenter(toRect.center());
|
||||||
|
startRect.moveCenter(toRect.center());
|
||||||
|
|
||||||
|
//paint to in the center of from
|
||||||
|
QColor color;
|
||||||
|
color.setAlphaF(amount);
|
||||||
|
|
||||||
|
// If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus
|
||||||
|
QPaintEngine *paintEngine = from.paintEngine();
|
||||||
|
if (paintEngine &&
|
||||||
|
paintEngine->hasFeature(QPaintEngine::PorterDuff) &&
|
||||||
|
paintEngine->hasFeature(QPaintEngine::BlendModes)) {
|
||||||
|
QPixmap startPixmap(pixmapSize);
|
||||||
|
startPixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QPixmap targetPixmap(pixmapSize);
|
||||||
|
targetPixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QPainter p;
|
||||||
|
p.begin(&targetPixmap);
|
||||||
|
p.drawPixmap(targetRect, to);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||||
|
p.fillRect(targetRect, color);
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
p.begin(&startPixmap);
|
||||||
|
p.drawPixmap(startRect, from);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
||||||
|
p.fillRect(startRect, color);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
||||||
|
p.drawPixmap(targetRect, targetPixmap);
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
return startPixmap;
|
||||||
|
}
|
||||||
|
#warning Cannot use XRender with QPixmap anymore. Find equivalent with Qt API.
|
||||||
|
#if 0 // HAVE_X11 && defined(HAVE_XRENDER)
|
||||||
|
// We have Xrender support
|
||||||
|
else if (paintEngine && paintEngine->hasFeature(QPaintEngine::PorterDuff)) {
|
||||||
|
// QX11PaintEngine doesn't implement CompositionMode_Plus in Qt 4.3,
|
||||||
|
// which we need to be able to do a transition from one pixmap to
|
||||||
|
// another.
|
||||||
|
//
|
||||||
|
// In order to avoid the overhead of converting the pixmaps to images
|
||||||
|
// and doing the operation entirely in software, this function has a
|
||||||
|
// specialized path for X11 that uses Xrender directly to do the
|
||||||
|
// transition. This operation can be fully accelerated in HW.
|
||||||
|
//
|
||||||
|
// This specialization can be removed when QX11PaintEngine supports
|
||||||
|
// CompositionMode_Plus.
|
||||||
|
QPixmap source(targetPixmap), destination(startPixmap);
|
||||||
|
|
||||||
|
source.detach();
|
||||||
|
destination.detach();
|
||||||
|
|
||||||
|
Display *dpy = QX11Info::display();
|
||||||
|
|
||||||
|
XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
|
||||||
|
XRenderPictureAttributes pa;
|
||||||
|
pa.repeat = 1; // RepeatNormal
|
||||||
|
|
||||||
|
// Create a 1x1 8 bit repeating alpha picture
|
||||||
|
Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
|
||||||
|
Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
|
||||||
|
XFreePixmap(dpy, pixmap);
|
||||||
|
|
||||||
|
// Fill the alpha picture with the opacity value
|
||||||
|
XRenderColor xcolor;
|
||||||
|
xcolor.alpha = quint16(0xffff * amount);
|
||||||
|
XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
// Reduce the alpha of the destination with 1 - opacity
|
||||||
|
XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
|
||||||
|
0, 0, 0, 0, 0, 0, destination.width(), destination.height());
|
||||||
|
|
||||||
|
// Add source * opacity to the destination
|
||||||
|
XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
|
||||||
|
destination.x11PictureHandle(),
|
||||||
|
toRect.x(), toRect.y(), 0, 0, 0, 0, destination.width(), destination.height());
|
||||||
|
|
||||||
|
XRenderFreePicture(dpy, alpha);
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
// Fall back to using QRasterPaintEngine to do the transition.
|
||||||
|
QImage under(pixmapSize, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
under.fill(Qt::transparent);
|
||||||
|
QImage over(pixmapSize, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
over.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QPainter p;
|
||||||
|
p.begin(&over);
|
||||||
|
p.drawPixmap(targetRect, to);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||||
|
p.fillRect(over.rect(), color);
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
p.begin(&under);
|
||||||
|
p.drawPixmap(startRect, from);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
||||||
|
p.fillRect(startRect, color);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
||||||
|
p.drawImage(toRect.topLeft(), over);
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
return QPixmap::fromImage(under);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IconItem::IconItem(QQuickItem *parent)
|
IconItem::IconItem(QQuickItem *parent)
|
||||||
: QQuickPaintedItem(parent),
|
: QQuickPaintedItem(parent),
|
||||||
@ -193,8 +319,8 @@ void IconItem::paint(QPainter *painter)
|
|||||||
|
|
||||||
if (m_animation->state() == QAbstractAnimation::Running) {
|
if (m_animation->state() == QAbstractAnimation::Running) {
|
||||||
QPixmap result = m_iconPixmaps.first();
|
QPixmap result = m_iconPixmaps.first();
|
||||||
result = Plasma::PaintUtils::transition(result,
|
result = transition(result,
|
||||||
m_iconPixmaps.last(), m_animValue);
|
m_iconPixmaps.last(), m_animValue);
|
||||||
painter->drawPixmap(destRect, result);
|
painter->drawPixmap(destRect, result);
|
||||||
//simpler logic for just paint
|
//simpler logic for just paint
|
||||||
} else {
|
} else {
|
||||||
|
@ -111,10 +111,8 @@ set(plasma_LIB_SRCS
|
|||||||
|
|
||||||
#graphics
|
#graphics
|
||||||
framesvg.cpp
|
framesvg.cpp
|
||||||
paintutils.cpp
|
|
||||||
svg.cpp
|
svg.cpp
|
||||||
theme.cpp
|
theme.cpp
|
||||||
private/effects/halopainter.cpp
|
|
||||||
private/theme_p.cpp
|
private/theme_p.cpp
|
||||||
|
|
||||||
#scripting
|
#scripting
|
||||||
@ -176,7 +174,6 @@ set(plasma_LIB_INCLUDES
|
|||||||
datacontainer.h
|
datacontainer.h
|
||||||
dataengine.h
|
dataengine.h
|
||||||
pluginloader.h
|
pluginloader.h
|
||||||
paintutils.h
|
|
||||||
framesvg.h
|
framesvg.h
|
||||||
package.h
|
package.h
|
||||||
packagestructure.h
|
packagestructure.h
|
||||||
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/abstracttoolbox.h"
|
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/paintutils.h"
|
|
@ -1,283 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2005 by Aaron Seigo <aseigo@kde.org>
|
|
||||||
* Copyright 2008 by Andrew Lake <jamboarder@yahoo.com>
|
|
||||||
*
|
|
||||||
* This program 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, 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 Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <paintutils.h>
|
|
||||||
|
|
||||||
#include <QImage>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QPaintEngine>
|
|
||||||
#include <QPixmap>
|
|
||||||
|
|
||||||
#include "private/effects/blur.cpp"
|
|
||||||
#include "private/effects/halopainter_p.h"
|
|
||||||
#include "svg.h"
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace PaintUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
void shadowBlur(QImage &image, int radius, const QColor &color)
|
|
||||||
{
|
|
||||||
if (radius < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (image.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
expblur<16, 7>(image, radius);
|
|
||||||
|
|
||||||
QPainter p(&image);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
|
||||||
p.fillRect(image.rect(), color);
|
|
||||||
p.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap texturedText(const QString &text, const QFont &font, Plasma::Svg *texture)
|
|
||||||
{
|
|
||||||
QFontMetrics fm(font);
|
|
||||||
//the text will be moved a bit from contentsRect
|
|
||||||
QRect contentsRect = fm.boundingRect(text).adjusted(0, 0, 2, 2);
|
|
||||||
contentsRect.moveTo(0,0);
|
|
||||||
|
|
||||||
QPixmap pixmap(contentsRect.size());
|
|
||||||
pixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPainter buffPainter(&pixmap);
|
|
||||||
buffPainter.setPen(Qt::black);
|
|
||||||
|
|
||||||
buffPainter.setFont(font);
|
|
||||||
buffPainter.drawText(contentsRect, Qt::AlignCenter, text);
|
|
||||||
buffPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
|
||||||
texture->paint(&buffPainter, contentsRect, "foreground");
|
|
||||||
buffPainter.end();
|
|
||||||
|
|
||||||
//do the shadow
|
|
||||||
QImage image(pixmap.size() + QSize(2, 2), QImage::Format_ARGB32_Premultiplied);
|
|
||||||
image.fill(Qt::transparent);
|
|
||||||
buffPainter.begin(&image);
|
|
||||||
buffPainter.setFont(font);
|
|
||||||
buffPainter.drawText(contentsRect.translated(1, 1), Qt::AlignCenter, text);
|
|
||||||
buffPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
|
||||||
texture->paint(&buffPainter, contentsRect.adjusted(-1, -1, 1, 1), "shadow");
|
|
||||||
buffPainter.end();
|
|
||||||
|
|
||||||
expblur<16, 7>(image, 1);
|
|
||||||
//hole in the shadow
|
|
||||||
buffPainter.begin(&image);
|
|
||||||
buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
|
||||||
buffPainter.setFont(font);
|
|
||||||
buffPainter.drawText(contentsRect.translated(1, 1), Qt::AlignCenter, text);
|
|
||||||
buffPainter.end();
|
|
||||||
|
|
||||||
QPixmap ret(image.size());
|
|
||||||
ret.fill(Qt::transparent);
|
|
||||||
buffPainter.begin(&ret);
|
|
||||||
buffPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
buffPainter.drawImage(QPoint(0,0), image);
|
|
||||||
buffPainter.drawPixmap(QPoint(1,1), pixmap);
|
|
||||||
buffPainter.end();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawHalo(QPainter *painter, const QRectF &rect)
|
|
||||||
{
|
|
||||||
HaloPainter::instance()->drawHalo(painter, rect.toRect());
|
|
||||||
}
|
|
||||||
|
|
||||||
QPainterPath roundedRectangle(const QRectF &rect, qreal radius)
|
|
||||||
{
|
|
||||||
QPainterPath path(QPointF(rect.left(), rect.top() + radius));
|
|
||||||
path.quadTo(rect.left(), rect.top(), rect.left() + radius, rect.top()); // Top left corner
|
|
||||||
path.lineTo(rect.right() - radius, rect.top()); // Top side
|
|
||||||
path.quadTo(rect.right(), rect.top(), rect.right(), rect.top() + radius); // Top right corner
|
|
||||||
path.lineTo(rect.right(), rect.bottom() - radius); // Right side
|
|
||||||
path.quadTo(rect.right(), rect.bottom(), rect.right() - radius, rect.bottom()); // Bottom right corner
|
|
||||||
path.lineTo(rect.left() + radius, rect.bottom()); // Bottom side
|
|
||||||
path.quadTo(rect.left(), rect.bottom(), rect.left(), rect.bottom() - radius); // Bottom left corner
|
|
||||||
path.closeSubpath();
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void centerPixmaps(QPixmap &from, QPixmap &to)
|
|
||||||
{
|
|
||||||
if (from.size() == to.size() && from.hasAlphaChannel() && to.hasAlphaChannel()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect fromRect(from.rect());
|
|
||||||
QRect toRect(to.rect());
|
|
||||||
|
|
||||||
QRect actualRect = QRect(QPoint(0,0), fromRect.size().expandedTo(toRect.size()));
|
|
||||||
fromRect.moveCenter(actualRect.center());
|
|
||||||
toRect.moveCenter(actualRect.center());
|
|
||||||
|
|
||||||
if (from.size() != actualRect.size() || !from.hasAlphaChannel()) {
|
|
||||||
QPixmap result(actualRect.size());
|
|
||||||
result.fill(Qt::transparent);
|
|
||||||
QPainter p(&result);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
p.drawPixmap(fromRect.topLeft(), from);
|
|
||||||
p.end();
|
|
||||||
from = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to.size() != actualRect.size() || !to.hasAlphaChannel()) {
|
|
||||||
QPixmap result(actualRect.size());
|
|
||||||
result.fill(Qt::transparent);
|
|
||||||
QPainter p(&result);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
p.drawPixmap(toRect.topLeft(), to);
|
|
||||||
p.end();
|
|
||||||
to = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
|
|
||||||
{
|
|
||||||
if (from.isNull() && to.isNull()) {
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qFuzzyCompare(amount + 1, qreal(1.0))) {
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect startRect(from.rect());
|
|
||||||
QRect targetRect(to.rect());
|
|
||||||
QSize pixmapSize = startRect.size().expandedTo(targetRect.size());
|
|
||||||
QRect toRect = QRect(QPoint(0,0), pixmapSize);
|
|
||||||
targetRect.moveCenter(toRect.center());
|
|
||||||
startRect.moveCenter(toRect.center());
|
|
||||||
|
|
||||||
//paint to in the center of from
|
|
||||||
QColor color;
|
|
||||||
color.setAlphaF(amount);
|
|
||||||
|
|
||||||
// If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus
|
|
||||||
QPaintEngine *paintEngine = from.paintEngine();
|
|
||||||
if (paintEngine &&
|
|
||||||
paintEngine->hasFeature(QPaintEngine::PorterDuff) &&
|
|
||||||
paintEngine->hasFeature(QPaintEngine::BlendModes)) {
|
|
||||||
QPixmap startPixmap(pixmapSize);
|
|
||||||
startPixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPixmap targetPixmap(pixmapSize);
|
|
||||||
targetPixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPainter p;
|
|
||||||
p.begin(&targetPixmap);
|
|
||||||
p.drawPixmap(targetRect, to);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
|
||||||
p.fillRect(targetRect, color);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
p.begin(&startPixmap);
|
|
||||||
p.drawPixmap(startRect, from);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
|
||||||
p.fillRect(startRect, color);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
|
||||||
p.drawPixmap(targetRect, targetPixmap);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
return startPixmap;
|
|
||||||
}
|
|
||||||
#warning Cannot use XRender with QPixmap anymore. Find equivalent with Qt API.
|
|
||||||
#if 0 // HAVE_X11 && defined(HAVE_XRENDER)
|
|
||||||
// We have Xrender support
|
|
||||||
else if (paintEngine && paintEngine->hasFeature(QPaintEngine::PorterDuff)) {
|
|
||||||
// QX11PaintEngine doesn't implement CompositionMode_Plus in Qt 4.3,
|
|
||||||
// which we need to be able to do a transition from one pixmap to
|
|
||||||
// another.
|
|
||||||
//
|
|
||||||
// In order to avoid the overhead of converting the pixmaps to images
|
|
||||||
// and doing the operation entirely in software, this function has a
|
|
||||||
// specialized path for X11 that uses Xrender directly to do the
|
|
||||||
// transition. This operation can be fully accelerated in HW.
|
|
||||||
//
|
|
||||||
// This specialization can be removed when QX11PaintEngine supports
|
|
||||||
// CompositionMode_Plus.
|
|
||||||
QPixmap source(targetPixmap), destination(startPixmap);
|
|
||||||
|
|
||||||
source.detach();
|
|
||||||
destination.detach();
|
|
||||||
|
|
||||||
Display *dpy = QX11Info::display();
|
|
||||||
|
|
||||||
XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
|
|
||||||
XRenderPictureAttributes pa;
|
|
||||||
pa.repeat = 1; // RepeatNormal
|
|
||||||
|
|
||||||
// Create a 1x1 8 bit repeating alpha picture
|
|
||||||
Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
|
|
||||||
Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
|
|
||||||
XFreePixmap(dpy, pixmap);
|
|
||||||
|
|
||||||
// Fill the alpha picture with the opacity value
|
|
||||||
XRenderColor xcolor;
|
|
||||||
xcolor.alpha = quint16(0xffff * amount);
|
|
||||||
XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
|
|
||||||
|
|
||||||
// Reduce the alpha of the destination with 1 - opacity
|
|
||||||
XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
|
|
||||||
0, 0, 0, 0, 0, 0, destination.width(), destination.height());
|
|
||||||
|
|
||||||
// Add source * opacity to the destination
|
|
||||||
XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
|
|
||||||
destination.x11PictureHandle(),
|
|
||||||
toRect.x(), toRect.y(), 0, 0, 0, 0, destination.width(), destination.height());
|
|
||||||
|
|
||||||
XRenderFreePicture(dpy, alpha);
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
|
||||||
// Fall back to using QRasterPaintEngine to do the transition.
|
|
||||||
QImage under(pixmapSize, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
under.fill(Qt::transparent);
|
|
||||||
QImage over(pixmapSize, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
over.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPainter p;
|
|
||||||
p.begin(&over);
|
|
||||||
p.drawPixmap(targetRect, to);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
|
||||||
p.fillRect(over.rect(), color);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
p.begin(&under);
|
|
||||||
p.drawPixmap(startRect, from);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
|
||||||
p.fillRect(startRect, color);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
|
||||||
p.drawImage(toRect.topLeft(), over);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
return QPixmap::fromImage(under);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // PaintUtils namespace
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2005 by Aaron Seigo <aseigo@kde.org>
|
|
||||||
* Copyright 2008 by Andrew Lake <jamboarder@yahoo.com>
|
|
||||||
*
|
|
||||||
* This program 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, 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 Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_PAINTUTILS_H
|
|
||||||
#define PLASMA_PAINTUTILS_H
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QPainterPath>
|
|
||||||
#include <QColor>
|
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
|
||||||
#include "theme.h"
|
|
||||||
|
|
||||||
/** @headerfile plasma/paintutils.h <Plasma/PaintUtils> */
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class Svg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Namespace for all Image Effects specific to Plasma
|
|
||||||
**/
|
|
||||||
namespace PaintUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a blurred shadow of the supplied image.
|
|
||||||
*/
|
|
||||||
PLASMA_EXPORT void shadowBlur(QImage &image, int radius, const QColor &color);
|
|
||||||
|
|
||||||
PLASMA_EXPORT QPixmap texturedText(const QString &text, const QFont &font, Plasma::Svg *texture);
|
|
||||||
|
|
||||||
PLASMA_EXPORT void drawHalo(QPainter *painter, const QRectF &rect);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a nicely rounded rectanglular path for painting.
|
|
||||||
*/
|
|
||||||
PLASMA_EXPORT QPainterPath roundedRectangle(const QRectF &rect, qreal radius);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* center two pixmap together in the biggest rectangle
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
PLASMA_EXPORT void centerPixmaps(QPixmap &from, QPixmap &to);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blends a pixmap into another
|
|
||||||
*/
|
|
||||||
PLASMA_EXPORT QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount);
|
|
||||||
|
|
||||||
} // PaintUtils namespace
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,154 +0,0 @@
|
|||||||
#ifndef BLUR_CPP
|
|
||||||
#define BLUR_CPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2007 Jani Huhtanen <jani.huhtanen@tut.fi>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation
|
|
||||||
*
|
|
||||||
* 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 Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
// Exponential blur, Jani Huhtanen, 2006
|
|
||||||
//
|
|
||||||
template<int aprec, int zprec>
|
|
||||||
static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha);
|
|
||||||
|
|
||||||
template<int aprec,int zprec>
|
|
||||||
static inline void blurrow(QImage &im, int line, int alpha);
|
|
||||||
|
|
||||||
template<int aprec, int zprec>
|
|
||||||
static inline void blurcol(QImage &im, int col, int alpha);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* expblur(QImage &img, int radius)
|
|
||||||
*
|
|
||||||
* In-place blur of image 'img' with kernel
|
|
||||||
* of approximate radius 'radius'.
|
|
||||||
*
|
|
||||||
* Blurs with two sided exponential impulse
|
|
||||||
* response.
|
|
||||||
*
|
|
||||||
* aprec = precision of alpha parameter
|
|
||||||
* in fixed-point format 0.aprec
|
|
||||||
*
|
|
||||||
* zprec = precision of state parameters
|
|
||||||
* zR,zG,zB and zA in fp format 8.zprec
|
|
||||||
*/
|
|
||||||
template<int aprec,int zprec>
|
|
||||||
void expblur(QImage &img, int radius)
|
|
||||||
{
|
|
||||||
if (radius < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
|
||||||
|
|
||||||
/* Calculate the alpha such that 90% of
|
|
||||||
the kernel is within the radius.
|
|
||||||
(Kernel extends to infinity)
|
|
||||||
*/
|
|
||||||
int alpha = (int)((1 << aprec) * (1.0f - std::exp(-2.3f / (radius + 1.f))));
|
|
||||||
|
|
||||||
int height = img.height();
|
|
||||||
int width = img.width();
|
|
||||||
for (int row=0; row<height; row++) {
|
|
||||||
blurrow<aprec,zprec>(img, row, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int col=0; col<width; col++) {
|
|
||||||
blurcol<aprec,zprec>(img, col, alpha);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int aprec, int zprec>
|
|
||||||
static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
|
|
||||||
{
|
|
||||||
int R, G, B, A;
|
|
||||||
R = *bptr;
|
|
||||||
G = *(bptr + 1);
|
|
||||||
B = *(bptr + 2);
|
|
||||||
A = *(bptr + 3);
|
|
||||||
|
|
||||||
zR += (alpha * ((R << zprec) - zR)) >> aprec;
|
|
||||||
zG += (alpha * ((G << zprec) - zG)) >> aprec;
|
|
||||||
zB += (alpha * ((B << zprec) - zB)) >> aprec;
|
|
||||||
zA += (alpha * ((A << zprec) - zA)) >> aprec;
|
|
||||||
|
|
||||||
*bptr = zR >> zprec;
|
|
||||||
*(bptr+1) = zG >> zprec;
|
|
||||||
*(bptr+2) = zB >> zprec;
|
|
||||||
*(bptr+3) = zA >> zprec;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int aprec,int zprec>
|
|
||||||
static inline void blurrow(QImage &im, int line, int alpha)
|
|
||||||
{
|
|
||||||
int zR, zG, zB, zA;
|
|
||||||
|
|
||||||
QRgb *ptr = (QRgb *)im.scanLine(line);
|
|
||||||
int width = im.width();
|
|
||||||
|
|
||||||
zR = *((unsigned char *)ptr ) << zprec;
|
|
||||||
zG = *((unsigned char *)ptr + 1) << zprec;
|
|
||||||
zB = *((unsigned char *)ptr + 2) << zprec;
|
|
||||||
zA = *((unsigned char *)ptr + 3) << zprec;
|
|
||||||
|
|
||||||
for (int index=1; index<width; index++) {
|
|
||||||
blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
|
|
||||||
}
|
|
||||||
for (int index=width-2; index>=0; index--) {
|
|
||||||
blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int aprec, int zprec>
|
|
||||||
static inline void blurcol(QImage &im, int col, int alpha)
|
|
||||||
{
|
|
||||||
int zR, zG, zB, zA;
|
|
||||||
|
|
||||||
QRgb *ptr = (QRgb *)im.bits();
|
|
||||||
ptr += col;
|
|
||||||
int height = im.height();
|
|
||||||
int width = im.width();
|
|
||||||
|
|
||||||
zR = *((unsigned char *)ptr ) << zprec;
|
|
||||||
zG = *((unsigned char *)ptr + 1) << zprec;
|
|
||||||
zB = *((unsigned char *)ptr + 2) << zprec;
|
|
||||||
zA = *((unsigned char *)ptr + 3) << zprec;
|
|
||||||
|
|
||||||
for (int index=width; index<(height-1)*width; index+=width) {
|
|
||||||
blurinner<aprec,zprec>((unsigned char *)&ptr[index], zR, zG, zB, zA, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int index=(height-2)*width; index>=0; index-=width) {
|
|
||||||
blurinner<aprec,zprec>((unsigned char *)&ptr[index], zR, zG, zB, zA, alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline const T &qClamp(const T &x, const T &low, const T &high)
|
|
||||||
{
|
|
||||||
if (x < low) {
|
|
||||||
return low;
|
|
||||||
} else if (x > high) {
|
|
||||||
return high;
|
|
||||||
} else {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,250 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2009 Fredrik Höglund <fredrik@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 "halopainter_p.h"
|
|
||||||
#include <QPainter>
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
static inline qreal gaussian(qreal x, qreal sigma)
|
|
||||||
{
|
|
||||||
return (1.0 / std::sqrt(2.0 * M_PI) * sigma)
|
|
||||||
* std::exp(-((x * x) / (2.0 * sigma * sigma)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gaussianBlur(QImage &image, int radius)
|
|
||||||
{
|
|
||||||
// The gaussian curve is effectively zero after 3 standard deviations.
|
|
||||||
qreal sigma = radius / 3.;
|
|
||||||
int size = radius * 2 + 1;
|
|
||||||
int center = size / 2;
|
|
||||||
qreal *kernel = new qreal[size];
|
|
||||||
qreal total = 0;
|
|
||||||
|
|
||||||
// Generate the gaussian kernel
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
kernel[i] = gaussian(i - center, sigma);
|
|
||||||
total += kernel[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize the kernel
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
kernel[i] = kernel[i] / total;
|
|
||||||
|
|
||||||
quint32 *buf = new quint32[image.width() * image.height()];
|
|
||||||
memset(buf, 0, image.width() * image.height() * sizeof(quint32));
|
|
||||||
|
|
||||||
// Blur the image horizontally
|
|
||||||
for (int y = 0; y < image.height(); y++)
|
|
||||||
{
|
|
||||||
quint32 *src = (quint32*)image.scanLine(y);
|
|
||||||
quint32 *dst = buf + image.width() * y;
|
|
||||||
|
|
||||||
for (int x = 0, start = center; x < center; x++, start--) {
|
|
||||||
double a = 0;
|
|
||||||
for (int i = start; i < size; i++)
|
|
||||||
a += qAlpha(src[x - center + i]) * kernel[i];
|
|
||||||
dst[x] = qRound(a) << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x = center; x < image.width() - center; x++) {
|
|
||||||
double a = 0;
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
a += qAlpha(src[x - center + i]) * kernel[i];
|
|
||||||
dst[x] = qRound(a) << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x = image.width() - center, stop = size - 1; x < image.width(); x++, stop--) {
|
|
||||||
double a = 0;
|
|
||||||
for (int i = 0; i < stop; i++)
|
|
||||||
a += qAlpha(src[x - center + i]) * kernel[i];
|
|
||||||
dst[x] = qRound(a) << 24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blur the image vertically
|
|
||||||
quint32 *src = buf;
|
|
||||||
quint32 *dst = (quint32*)image.bits();
|
|
||||||
|
|
||||||
for (int x = 0; x < image.width(); x++)
|
|
||||||
{
|
|
||||||
int di = x;
|
|
||||||
|
|
||||||
for (int y = 0, start = center; y < center; y++, start--) {
|
|
||||||
double a = 0;
|
|
||||||
int si = (y - center + start) * image.width() + x;
|
|
||||||
for (int i = start; i < size; i++) {
|
|
||||||
a += qAlpha(src[si]) * kernel[i];
|
|
||||||
si += image.width();
|
|
||||||
}
|
|
||||||
dst[di] = qRound(a) << 24;
|
|
||||||
di += image.width();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = center; y < image.height() - center; y++) {
|
|
||||||
double a = 0;
|
|
||||||
int si = (y - center) * image.width() + x;
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
a += qAlpha(src[si]) * kernel[i];
|
|
||||||
si += image.width();
|
|
||||||
}
|
|
||||||
dst[di] = qRound(a) << 24;
|
|
||||||
di += image.width();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = image.height() - center, stop = size - 1; y < image.height(); y++, stop--) {
|
|
||||||
double a = 0;
|
|
||||||
int si = (y - center) * image.width() + x;
|
|
||||||
for (int i = 0; i < stop; i++) {
|
|
||||||
a += qAlpha(src[si]) * kernel[i];
|
|
||||||
si += image.width();
|
|
||||||
}
|
|
||||||
dst[di] = qRound(a) << 24;
|
|
||||||
di += image.width();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] buf;
|
|
||||||
delete [] kernel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TileSet::TileSet(const QPixmap &pixmap)
|
|
||||||
{
|
|
||||||
int tw = pixmap.width() / 3;
|
|
||||||
int th = pixmap.height();
|
|
||||||
|
|
||||||
for (int x = 0; x < 3; x++)
|
|
||||||
tiles[x] = pixmap.copy(x * tw, 0, tw, th);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSet::paint(QPainter *p, const QRect &r)
|
|
||||||
{
|
|
||||||
int tw = tiles[Left].width();
|
|
||||||
int th = tiles[Left].height();
|
|
||||||
int tw2 = tw * 2;
|
|
||||||
|
|
||||||
if (r.width() < tw2) {
|
|
||||||
int sw = r.width() / 2;
|
|
||||||
p->drawPixmap(r.x(), r.y(), tiles[Left], 0, 0, sw, tiles[Left].height());
|
|
||||||
p->drawPixmap(r.x() + sw, r.y(), tiles[Right], tw - sw, 0, sw, tiles[Right].height());
|
|
||||||
} else {
|
|
||||||
p->drawPixmap(r.topLeft(), tiles[Left]);
|
|
||||||
if (r.width() - tw2 > 0)
|
|
||||||
p->drawTiledPixmap(r.x() + tw, r.y(), r.width() - tw2, th, tiles[Center]);
|
|
||||||
p->drawPixmap(r.right() - tw + 1, r.y(), tiles[Right]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HaloPainter *HaloPainter::s_instance = 0;
|
|
||||||
|
|
||||||
|
|
||||||
HaloPainter::HaloPainter()
|
|
||||||
: m_tileCache(16), m_haloCache(30)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
HaloPainter::~HaloPainter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TileSet *HaloPainter::tiles(int height) const
|
|
||||||
{
|
|
||||||
TileSet *tiles = m_tileCache.object(height);
|
|
||||||
|
|
||||||
if (!tiles) {
|
|
||||||
QImage image(64 * 3, height + 16, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
image.fill(0);
|
|
||||||
|
|
||||||
QPainter p(&image);
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(Qt::white);
|
|
||||||
p.drawRoundedRect(image.rect().adjusted(8, 8, -8, -8), height, height / 2);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
gaussianBlur(image, 8);
|
|
||||||
|
|
||||||
p.begin(&image);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
|
||||||
p.fillRect(image.rect(), QColor(255, 255, 255, 255));
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
tiles = new TileSet(QPixmap::fromImage(image));
|
|
||||||
m_tileCache.insert(height, tiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HaloPainter::paint(QPainter *painter, const QRect &textRect) const
|
|
||||||
{
|
|
||||||
int radius = textRect.height() / 2;
|
|
||||||
const QRect hr = textRect.adjusted(-8 - radius, -9, 8 + radius, 9);
|
|
||||||
|
|
||||||
int key = hr.width() << 16 | hr.height();
|
|
||||||
QPixmap *pixmap = m_haloCache.object(key);
|
|
||||||
|
|
||||||
if (!pixmap) {
|
|
||||||
TileSet *halo = tiles(hr.height() - 16);
|
|
||||||
|
|
||||||
pixmap = new QPixmap(hr.size());
|
|
||||||
pixmap->fill(Qt::transparent);
|
|
||||||
QPainter p(pixmap);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
halo->paint(&p, pixmap->rect());
|
|
||||||
QLinearGradient g(0, 0, pixmap->width(), 0);
|
|
||||||
if (hr.width() < 80) {
|
|
||||||
for (int i = 0; i <= 16; i++) {
|
|
||||||
g.setColorAt(i / 16., QColor(0, 0, 0, 164 * (1 - std::pow((i - 8) / 8., 2))));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const qreal pixel = 1. / hr.width();
|
|
||||||
for (int i = 0; i <= 8; i++) {
|
|
||||||
const QColor color(0, 0, 0, 164 * (1 - std::pow((i - 8) / 8., 2)));
|
|
||||||
g.setColorAt(i * (pixel * 40) / 8, color);
|
|
||||||
g.setColorAt(1 - i * (pixel * 40) / 8, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
|
||||||
p.fillRect(pixmap->rect(), g);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
m_haloCache.insert(key, pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->drawPixmap(hr.topLeft(), *pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Plasma
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2009 Fredrik Höglund <fredrik@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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HALOPAINTER_H
|
|
||||||
#define HALOPAINTER_H
|
|
||||||
|
|
||||||
#include <QCache>
|
|
||||||
#include <QPixmap>
|
|
||||||
|
|
||||||
class QRect;
|
|
||||||
class QPainter;
|
|
||||||
|
|
||||||
namespace Plasma {
|
|
||||||
|
|
||||||
class TileSet
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Tile {
|
|
||||||
Left, Center, Right, NTiles
|
|
||||||
};
|
|
||||||
|
|
||||||
TileSet(const QPixmap &pixmap);
|
|
||||||
~TileSet() {}
|
|
||||||
|
|
||||||
void paint(QPainter *painter, const QRect &rect);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QPixmap tiles[NTiles];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
class HaloPainter : public QObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~HaloPainter();
|
|
||||||
static HaloPainter *instance() {
|
|
||||||
if (!s_instance) {
|
|
||||||
s_instance = new HaloPainter;
|
|
||||||
}
|
|
||||||
return s_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawHalo(QPainter *painter, const QRect &textRect) {
|
|
||||||
instance()->paint(painter, textRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HaloPainter();
|
|
||||||
TileSet *tiles(int height) const;
|
|
||||||
void paint(QPainter *painter, const QRect &textRect) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static HaloPainter *s_instance;
|
|
||||||
mutable QCache<int, TileSet> m_tileCache;
|
|
||||||
mutable QCache<int, QPixmap> m_haloCache;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Plasma
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user