00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <paintutils.h>
00022
00023 #include <QImage>
00024 #include <QPainter>
00025 #include <QPaintEngine>
00026 #include <QPixmap>
00027
00028 #include "effects/blur.cpp"
00029
00030 namespace Plasma
00031 {
00032
00033 namespace PaintUtils
00034 {
00035
00036 void shadowBlur(QImage &image, int radius, const QColor &color)
00037 {
00038 if (radius < 1) {
00039 return;
00040 }
00041 if (image.isNull()) {
00042 return;
00043 }
00044
00045 expblur<16, 7>(image, radius);
00046
00047 QPainter p(&image);
00048 p.setCompositionMode(QPainter::CompositionMode_SourceIn);
00049 p.fillRect(image.rect(), color);
00050 p.end();
00051 }
00052
00053
00054 QPixmap shadowText(QString text, QColor textColor, QColor shadowColor, QPoint offset, int radius)
00055 {
00056 return shadowText(text, qApp->font(), textColor, shadowColor, offset, radius);
00057 }
00058
00059 QPixmap shadowText(QString text, const QFont &font, QColor textColor, QColor shadowColor, QPoint offset, int radius)
00060 {
00061
00062 if (text.isEmpty()) {
00063 return QPixmap();
00064 }
00065
00066
00067 QFontMetrics fm(font);
00068 QRect textRect = fm.boundingRect(text);
00069 QPixmap textPixmap(textRect.width(), fm.height());
00070 textPixmap.fill(Qt::transparent);
00071 QPainter p(&textPixmap);
00072 p.setPen(textColor);
00073 p.setFont(font);
00074
00075
00076
00077
00078
00079
00080 p.drawText(textPixmap.rect(), Qt::AlignCenter, text);
00081 p.end();
00082
00083
00084 QImage img(textRect.size() + QSize(radius * 2, radius * 2),
00085 QImage::Format_ARGB32_Premultiplied);
00086 img.fill(0);
00087 p.begin(&img);
00088 p.drawImage(QPoint(radius, radius), textPixmap.toImage());
00089 p.end();
00090 shadowBlur(img, radius, shadowColor);
00091
00092
00093 int addSizeX;
00094 int addSizeY;
00095 if (offset.x() > radius) {
00096 addSizeX = abs(offset.x()) - radius;
00097 } else {
00098 addSizeX = 0;
00099 }
00100 if (offset.y() > radius) {
00101 addSizeY = abs(offset.y()) - radius;
00102 } else {
00103 addSizeY = 0;
00104 }
00105
00106 QPixmap finalPixmap(img.size() + QSize(addSizeX, addSizeY));
00107 finalPixmap.fill(Qt::transparent);
00108 p.begin(&finalPixmap);
00109 QPointF offsetF(offset);
00110 QPointF textTopLeft(finalPixmap.rect().topLeft() +
00111 QPointF ((finalPixmap.width() - textPixmap.width()) / 2.0, (finalPixmap.height() - textPixmap.height()) / 2.0) -
00112 (offsetF / 2.0));
00113 QPointF shadowTopLeft(finalPixmap.rect().topLeft() +
00114 QPointF ((finalPixmap.width() - img.width()) / 2.0, (finalPixmap.height() - img.height()) / 2.0) +
00115 (offsetF / 2.0));
00116
00117 p.drawImage(shadowTopLeft, img);
00118 p.drawPixmap(textTopLeft, textPixmap);
00119 p.end();
00120
00121 return finalPixmap;
00122 }
00123
00124 QPainterPath roundedRectangle(const QRectF &rect, qreal radius)
00125 {
00126 QPainterPath path(QPointF(rect.left(), rect.top() + radius));
00127 path.quadTo(rect.left(), rect.top(), rect.left() + radius, rect.top());
00128 path.lineTo(rect.right() - radius, rect.top());
00129 path.quadTo(rect.right(), rect.top(), rect.right(), rect.top() + radius);
00130 path.lineTo(rect.right(), rect.bottom() - radius);
00131 path.quadTo(rect.right(), rect.bottom(), rect.right() - radius, rect.bottom());
00132 path.lineTo(rect.left() + radius, rect.bottom());
00133 path.quadTo(rect.left(), rect.bottom(), rect.left(), rect.bottom() - radius);
00134 path.closeSubpath();
00135
00136 return path;
00137 }
00138
00139 QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
00140 {
00141 if (from.isNull() || to.isNull()) {
00142 return from;
00143 }
00144
00145 int value = int(0xff * amount);
00146
00147 if (value == 0) {
00148 return from;
00149 } else if (value == 1) {
00150 return to;
00151 }
00152
00153 QColor color;
00154 color.setAlphaF(amount);
00155
00156
00157 QRect toRect = to.rect();
00158 toRect.moveCenter(from.rect().center());
00159
00160
00161 QPaintEngine *paintEngine = from.paintEngine();
00162 if (paintEngine &&
00163 paintEngine->hasFeature(QPaintEngine::PorterDuff) &&
00164 paintEngine->hasFeature(QPaintEngine::BlendModes)) {
00165 QPixmap under = from;
00166 QPixmap over = to;
00167
00168 QPainter p;
00169 p.begin(&over);
00170 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00171 p.fillRect(over.rect(), color);
00172 p.end();
00173
00174 p.begin(&under);
00175 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00176 p.fillRect(under.rect(), color);
00177 p.setCompositionMode(QPainter::CompositionMode_Plus);
00178 p.drawPixmap(toRect.topLeft(), over);
00179 p.end();
00180
00181 return under;
00182 }
00183 #if defined(Q_WS_X11) && defined(HAVE_XRENDER)
00184
00185 else if (paintEngine && paintEngine->hasFeature(QPaintEngine::PorterDuff)) {
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 QPixmap source(to), destination(from);
00198
00199 source.detach();
00200 destination.detach();
00201
00202 Display *dpy = QX11Info::display();
00203
00204 XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
00205 XRenderPictureAttributes pa;
00206 pa.repeat = 1;
00207
00208
00209 Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
00210 Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
00211 XFreePixmap(dpy, pixmap);
00212
00213
00214 XRenderColor xcolor;
00215 xcolor.alpha = quint16(0xffff * amount);
00216 XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
00217
00218
00219 XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
00220 0, 0, 0, 0, 0, 0, destination.width(), destination.height());
00221
00222
00223 XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
00224 destination.x11PictureHandle(),
00225 toRect.x(), toRect.y(), 0, 0, 0, 0, destination.width(), destination.height());
00226
00227 XRenderFreePicture(dpy, alpha);
00228 return destination;
00229 }
00230 #endif
00231 else {
00232
00233 QImage under = from.toImage();
00234 QImage over = to.toImage();
00235
00236 QPainter p;
00237 p.begin(&over);
00238 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00239 p.fillRect(over.rect(), color);
00240 p.end();
00241
00242 p.begin(&under);
00243 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00244 p.fillRect(under.rect(), color);
00245 p.setCompositionMode(QPainter::CompositionMode_Plus);
00246 p.drawImage(toRect.topLeft(), over);
00247 p.end();
00248
00249 return QPixmap::fromImage(under);
00250 }
00251 }
00252
00253 }
00254
00255 }
00256