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