summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2009-08-19 08:39:40 (GMT)
committerBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2009-08-19 08:39:40 (GMT)
commit928f902015a0ad97279ce6e2ac4cb85e5baed684 (patch)
treec3afd6f5b72b32136ab9d40788e1cf05d7b91763 /src/gui/painting
parent17d6f2a59fe2b170087cdf7074807c6a2dce1043 (diff)
parent5fb5c01bd0ac234eaca890d97053c7b0772861a3 (diff)
downloadQt-928f902015a0ad97279ce6e2ac4cb85e5baed684.zip
Qt-928f902015a0ad97279ce6e2ac4cb85e5baed684.tar.gz
Qt-928f902015a0ad97279ce6e2ac4cb85e5baed684.tar.bz2
Merge commit 'qt/master' into kinetic-graphicseffect
Conflicts: src/gui/graphicsview/qgraphicsitem_p.h
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/painting.pri3
-rw-r--r--src/gui/painting/qblendfunctions.cpp633
-rw-r--r--src/gui/painting/qbrush.cpp10
-rw-r--r--src/gui/painting/qcolor.cpp4
-rw-r--r--src/gui/painting/qcolormap.qdoc152
-rw-r--r--src/gui/painting/qdrawhelper_p.h9
-rw-r--r--src/gui/painting/qmatrix.cpp2
-rw-r--r--src/gui/painting/qpaintdevice.cpp2
-rw-r--r--src/gui/painting/qpaintdevice.qdoc289
-rw-r--r--src/gui/painting/qpaintdevice_qws.cpp33
-rw-r--r--src/gui/painting/qpaintengine.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp85
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp16
-rw-r--r--src/gui/painting/qpainter.cpp4
-rw-r--r--src/gui/painting/qpainterpath.cpp4
-rw-r--r--src/gui/painting/qpen.cpp4
-rw-r--r--src/gui/painting/qpolygon.cpp4
-rw-r--r--src/gui/painting/qprinter.cpp6
-rw-r--r--src/gui/painting/qprinterinfo.qdoc139
-rw-r--r--src/gui/painting/qregion.cpp2
-rw-r--r--src/gui/painting/qstylepainter.cpp2
-rw-r--r--src/gui/painting/qtransform.cpp2
22 files changed, 1329 insertions, 78 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index b9d293c..d11e818 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -80,9 +80,6 @@ SOURCES += \
painting/qtransform.cpp \
painting/qwindowsurface.cpp \
- DEFINES += QT_RASTER_IMAGEENGINE
- win32:DEFINES += QT_RASTER_PAINTENGINE
- embedded:DEFINES += QT_RASTER_PAINTENGINE
SOURCES += \
painting/qpaintengine_raster.cpp \
painting/qdrawhelper.cpp \
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 1121c0e..e447301 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -793,8 +793,351 @@ void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
}
}
+struct QTransformImageVertex
+{
+ qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v)
+};
+
+template <class SrcT, class DestT, class Blender>
+void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ const SrcT *srcPixels, int sbpl,
+ const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft,
+ const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight,
+ const QRect &sourceRect,
+ const QRect &clip,
+ qreal topY, qreal bottomY,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+{
+ int fromY = qMax(qRound(topY), clip.top());
+ int toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+ int dx_l = int(leftSlope * 0x10000);
+ int dx_r = int(rightSlope * 0x10000);
+ int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000);
+ int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000);
+
+ int fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+ for (int y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+ fromX = qMax(x_l >> 16, clip.left());
+ toX = qMin(x_r >> 16, clip.left() + clip.width());
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+ // garbage on the screen.
+
+ // Find the first pixel on the current scan line where the source coordinates are within the source rect.
+ x1 = fromX;
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+ int uu = u >> 16;
+ int vv = v >> 16;
+ if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+ && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
+ break;
+ }
+ u += dudx;
+ v += dvdx;
+ }
+
+ // Find the last pixel on the current scan line where the source coordinates are within the source rect.
+ x2 = toX;
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+ int uu = u >> 16;
+ int vv = v >> 16;
+ if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+ && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
+ break;
+ }
+ u -= dudx;
+ v -= dvdx;
+ }
+
+ // Set up values at the beginning of the scan line.
+ u = fromX * dudx + y * dudy + u0;
+ v = fromX * dvdx + y * dvdy + v0;
+ line += fromX;
+
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+ int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+ int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+ ++line;
+ --i;
+ }
+
+ // Middle of the scan line, without checks.
+ // Manual loop unrolling.
+ i = x2 - x1;
+ ii = i >> 3;
+ while (ii) {
+ blender.write(&line[0], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[1], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[2], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[3], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[4], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[5], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[6], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ blender.write(&line[7], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
+ line += 8;
+ --ii;
+ }
+ switch (i & 7) {
+ case 7: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ case 6: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ case 5: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ case 4: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ case 3: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ case 2: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ case 1: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
+ }
+
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+ int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+ int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+ ++line;
+ --i;
+ }
+ }
+ x_l += dx_l;
+ x_r += dx_r;
+ }
+}
+
+template <class SrcT, class DestT, class Blender>
+void qt_transform_image(DestT *destPixels, int dbpl,
+ const SrcT *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ const QTransform &targetRectTransform,
+ Blender blender)
+{
+ enum Corner
+ {
+ TopLeft,
+ TopRight,
+ BottomRight,
+ BottomLeft
+ };
+
+ // map source rectangle to destination.
+ QTransformImageVertex v[4];
+ v[TopLeft].u = v[BottomLeft].u = sourceRect.left();
+ v[TopLeft].v = v[TopRight].v = sourceRect.top();
+ v[TopRight].u = v[BottomRight].u = sourceRect.right();
+ v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom();
+ targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y);
+ targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y);
+ targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y);
+ targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y);
+
+ // find topmost vertex.
+ int topmost = 0;
+ for (int i = 1; i < 4; ++i) {
+ if (v[i].y < v[topmost].y)
+ topmost = i;
+ }
+ // rearrange array such that topmost vertex is at index 0.
+ switch (topmost) {
+ case 1:
+ {
+ QTransformImageVertex t = v[0];
+ for (int i = 0; i < 3; ++i)
+ v[i] = v[i+1];
+ v[3] = t;
+ }
+ break;
+ case 2:
+ qSwap(v[0], v[2]);
+ qSwap(v[1], v[3]);
+ break;
+ case 3:
+ {
+ QTransformImageVertex t = v[3];
+ for (int i = 3; i > 0; --i)
+ v[i] = v[i-1];
+ v[0] = t;
+ }
+ break;
+ }
+
+ // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3.
+ qreal dx1 = v[1].x - v[0].x;
+ qreal dy1 = v[1].y - v[0].y;
+ qreal dx2 = v[3].x - v[0].x;
+ qreal dy2 = v[3].y - v[0].y;
+ if (dx1 * dy2 - dx2 * dy1 > 0)
+ qSwap(v[1], v[3]);
+
+ QTransformImageVertex u = {v[1].x - v[0].x, v[1].y - v[0].y, v[1].u - v[0].u, v[1].v - v[0].v};
+ QTransformImageVertex w = {v[2].x - v[0].x, v[2].y - v[0].y, v[2].u - v[0].u, v[2].v - v[0].v};
+
+ qreal det = u.x * w.y - u.y * w.x;
+ if (det == 0)
+ return;
+
+ qreal invDet = 1.0 / det;
+ qreal m11, m12, m21, m22, mdx, mdy;
+
+ m11 = (u.u * w.y - u.y * w.u) * invDet;
+ m12 = (u.x * w.u - u.u * w.x) * invDet;
+ m21 = (u.v * w.y - u.y * w.v) * invDet;
+ m22 = (u.x * w.v - u.v * w.x) * invDet;
+ mdx = v[0].u - m11 * v[0].x - m12 * v[0].y;
+ mdy = v[0].v - m21 * v[0].x - m22 * v[0].y;
+
+ int dudx = int(m11 * 0x10000);
+ int dvdx = int(m21 * 0x10000);
+ int dudy = int(m12 * 0x10000);
+ int dvdy = int(m22 * 0x10000);
+ int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1;
+ int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1;
+
+ int x1 = qFloor(sourceRect.left());
+ int y1 = qFloor(sourceRect.top());
+ int x2 = qCeil(sourceRect.right());
+ int y2 = qCeil(sourceRect.bottom());
+ QRect sourceRectI(x1, y1, x2 - x1, y2 - y1);
+
+ // rasterize trapezoids.
+ if (v[1].y < v[3].y) {
+ qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
+ qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[0], v[3], sourceRectI, clip, v[1].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
+ qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[3].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
+ } else {
+ qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
+ qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[3], v[2], sourceRectI, clip, v[3].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
+ qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[1].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
+ }
+}
+
+void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ const QTransform &targetRectTransform,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ Blend_RGB16_on_RGB16_NoAlpha noAlpha;
+ qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
+ reinterpret_cast<const quint16 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, noAlpha);
+ } else {
+ Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha);
+ qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
+ reinterpret_cast<const quint16 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, constAlpha);
+ }
+}
+
+void qt_transform_image_argb24_on_rgb16(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ const QTransform &targetRectTransform,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ Blend_ARGB24_on_RGB16_SourceAlpha noAlpha;
+ qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
+ reinterpret_cast<const qargb8565 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, noAlpha);
+ } else {
+ Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
+ qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
+ reinterpret_cast<const qargb8565 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, constAlpha);
+ }
+}
+void qt_transform_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ const QTransform &targetRectTransform,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ Blend_ARGB32_on_RGB16_SourceAlpha noAlpha;
+ qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
+ reinterpret_cast<const quint32 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, noAlpha);
+ } else {
+ Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
+ qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
+ reinterpret_cast<const quint32 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, constAlpha);
+ }
+}
+
+
+void qt_transform_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ const QTransform &targetRectTransform,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ Blend_RGB32_on_RGB32_NoAlpha noAlpha;
+ qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
+ reinterpret_cast<const quint32 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, noAlpha);
+ } else {
+ Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha);
+ qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
+ reinterpret_cast<const quint32 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, constAlpha);
+ }
+}
+
+void qt_transform_image_argb32_on_argb32(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ const QTransform &targetRectTransform,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha;
+ qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
+ reinterpret_cast<const quint32 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, sourceAlpha);
+ } else {
+ Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha);
+ qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
+ reinterpret_cast<const quint32 *>(srcPixels), sbpl,
+ targetRect, sourceRect, clip, targetRectTransform, constAlpha);
+ }
+}
+
SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = {
{ // Format_Invalid
0, // Format_Invalid,
@@ -1378,5 +1721,295 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
}
};
+SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats] = {
+ { // Format_Invalid
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_Mono
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_MonoLSB
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_Indexed8
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_RGB32
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ qt_transform_image_rgb32_on_rgb32, // Format_RGB32,
+ 0, // Format_ARGB32,
+ qt_transform_image_argb32_on_argb32, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_ARGB32
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_ARGB32_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ qt_transform_image_rgb32_on_rgb32, // Format_RGB32,
+ 0, // Format_ARGB32,
+ qt_transform_image_argb32_on_argb32, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_RGB16
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ qt_transform_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied,
+ qt_transform_image_rgb16_on_rgb16, // Format_RGB16,
+ qt_transform_image_argb24_on_rgb16, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_ARGB8565_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_RGB666
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_ARGB6666_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_RGB555
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_ARGB8555_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_RGB888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_RGB444
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ },
+ { // Format_ARGB4444_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0 // Format_ARGB4444_Premultiplied,
+ }
+};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index be5db6b..931d7ff 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -233,7 +233,7 @@ struct QGradientBrushData : public QBrushData
/*!
\class QBrush
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
\brief The QBrush class defines the fill pattern of shapes drawn
@@ -1153,7 +1153,7 @@ QDataStream &operator>>(QDataStream &s, QBrush &b)
/*!
\class QGradient
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
\brief The QGradient class is used in combination with QBrush to
@@ -1517,7 +1517,7 @@ bool QGradient::operator==(const QGradient &gradient)
/*!
\class QLinearGradient
- \ingroup multimedia
+ \ingroup painting
\brief The QLinearGradient class is used in combination with QBrush to
specify a linear gradient brush.
@@ -1696,7 +1696,7 @@ void QLinearGradient::setFinalStop(const QPointF &stop)
/*!
\class QRadialGradient
- \ingroup multimedia
+ \ingroup painting
\brief The QRadialGradient class is used in combination with QBrush to
specify a radial gradient brush.
@@ -1953,7 +1953,7 @@ void QRadialGradient::setFocalPoint(const QPointF &focalPoint)
/*!
\class QConicalGradient
- \ingroup multimedia
+ \ingroup painting
\brief The QConicalGradient class is used in combination with QBrush to
specify a conical gradient brush.
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 11a9ae7..4e93f04 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -66,9 +66,9 @@ QT_BEGIN_NAMESPACE
\class QColor
\brief The QColor class provides colors based on RGB, HSV or CMYK values.
- \ingroup multimedia
+ \ingroup painting
\ingroup appearance
- \mainclass
+
A color is normally specified in terms of RGB (red, green, and
blue) components, but it is also possible to specify it in terms
diff --git a/src/gui/painting/qcolormap.qdoc b/src/gui/painting/qcolormap.qdoc
new file mode 100644
index 0000000..e4a88f0
--- /dev/null
+++ b/src/gui/painting/qcolormap.qdoc
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QColormap
+ \ingroup painting
+
+ \brief The QColormap class maps device independent QColors to device
+ dependent pixel values.
+*/
+
+/*! \enum QColormap::Mode
+
+ This enum describes how QColormap maps device independent RGB
+ values to device dependent pixel values.
+
+ \value Direct Pixel values are derived directly from the RGB
+ values, also known as "True Color."
+
+ \value Indexed Pixel values represent indexes into a vector of
+ available colors, i.e. QColormap uses the index of the color that
+ most closely matches an RGB value.
+
+ \value Gray Similar to \c Indexed, pixel values represent a vector
+ of available gray tones. QColormap uses the index of the gray
+ tone that most closely matches the computed gray tone of an RGB
+ value.
+*/
+
+/*!
+ \fn QColormap QColormap::instance(int screen)
+
+ Returns the colormap for the specified \a screen. If \a screen is
+ -1, this function returns the colormap for the default screen.
+*/
+
+/*!
+ \fn QColormap::QColormap(const QColormap &colormap)
+
+ Constructs a copy of another \a colormap.
+*/
+
+/*!
+ \fn QColormap::~QColormap()
+
+ Destroys the colormap.
+*/
+
+/*!
+ \fn int QColormap::size() const
+
+ Returns the size of the colormap for \c Indexed and \c Gray modes;
+ Returns -1 for \c Direct mode.
+
+ \sa colormap()
+*/
+
+/*!
+ \fn uint QColormap::pixel(const QColor &color) const
+
+ Returns a device dependent pixel value for the \a color.
+
+ \sa colorAt()
+*/
+
+/*!
+ \fn int QColormap::depth() const
+
+ Returns the depth of the device.
+
+ \sa size()
+*/
+
+/*!
+ \fn QColormap::Mode QColormap::mode() const
+
+ Returns the mode of this colormap.
+
+ \sa QColormap::Mode
+*/
+
+/*!
+ \fn const QColor QColormap::colorAt(uint pixel) const
+
+ Returns a QColor for the \a pixel.
+
+ \sa pixel()
+*/
+
+/*!
+ \fn const QVector<QColor> QColormap::colormap() const
+
+ Returns a vector of colors which represents the devices colormap
+ for \c Indexed and \c Gray modes. This function returns an empty
+ vector for \c Direct mode.
+
+ \sa size()
+*/
+
+/*! \fn HPALETTE QColormap::hPal()
+
+ This function is only available on Windows.
+
+ Returns an handle to the HPALETTE used by this colormap. If no
+ HPALETTE is being used, this function returns zero.
+*/
+
+/*! \since 4.2
+
+ \fn QColormap &QColormap::operator=(const QColormap &colormap)
+
+ Assigns the given \a colormap to \e this color map and returns
+ a reference to \e this color map.
+*/
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 18c3358..83d2671 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -146,6 +146,14 @@ typedef void (*SrcOverScaleFunc)(uchar *destPixels, int dbpl,
const QRect &clipRect,
int const_alpha);
+typedef void (*SrcOverTransformFunc)(uchar *destPixels, int dbpl,
+ const uchar *src, int spbl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clipRect,
+ const QTransform &targetRectTransform,
+ int const_alpha);
+
struct DrawHelper {
ProcessSpans blendColor;
@@ -158,6 +166,7 @@ struct DrawHelper {
extern SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats];
extern SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats];
+extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats];
extern DrawHelper qDrawHelper[QImage::NImageFormats];
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index ce71a84..abff9bf 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
coordinate system.
\obsolete
- \ingroup multimedia
+ \ingroup painting
A matrix specifies how to translate, scale, shear or rotate the
coordinate system, and is typically used when rendering graphics.
diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp
index 6477952..6a2a4c4 100644
--- a/src/gui/painting/qpaintdevice.cpp
+++ b/src/gui/painting/qpaintdevice.cpp
@@ -64,3 +64,5 @@ int QPaintDevice::metric(PaintDeviceMetric) const
qWarning("QPaintDevice::metrics: Device has no metric information");
return 0;
}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc
new file mode 100644
index 0000000..5933484
--- /dev/null
+++ b/src/gui/painting/qpaintdevice.qdoc
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QPaintDevice
+ \brief The QPaintDevice class is the base class of objects that
+ can be painted.
+
+ \ingroup painting
+
+ A paint device is an abstraction of a two-dimensional space that
+ can be drawn using a QPainter. Its default coordinate system has
+ its origin located at the top-left position. X increases to the
+ right and Y increases downwards. The unit is one pixel.
+
+ The drawing capabilities of QPaintDevice are currently implemented
+ by the QWidget, QImage, QPixmap, QGLPixelBuffer, QPicture, and
+ QPrinter subclasses.
+
+ To implement support for a new backend, you must derive from
+ QPaintDevice and reimplement the virtual paintEngine() function to
+ tell QPainter which paint engine should be used to draw on this
+ particular device. Note that you also must create a corresponding
+ paint engine to be able to draw on the device, i.e derive from
+ QPaintEngine and reimplement its virtual functions.
+
+ \warning Qt requires that a QApplication object exists before
+ any paint devices can be created. Paint devices access window
+ system resources, and these resources are not initialized before
+ an application object is created.
+
+ The QPaintDevice class provides several functions returning the
+ various device metrics: The depth() function returns its bit depth
+ (number of bit planes). The height() function returns its height
+ in default coordinate system units (e.g. pixels for QPixmap and
+ QWidget) while heightMM() returns the height of the device in
+ millimeters. Similiarily, the width() and widthMM() functions
+ return the width of the device in default coordinate system units
+ and in millimeters, respectively. Alternatively, the protected
+ metric() function can be used to retrieve the metric information
+ by specifying the desired PaintDeviceMetric as argument.
+
+ The logicalDpiX() and logicalDpiY() functions return the
+ horizontal and vertical resolution of the device in dots per
+ inch. The physicalDpiX() and physicalDpiY() functions also return
+ the resolution of the device in dots per inch, but note that if
+ the logical and vertical resolution differ, the corresponding
+ QPaintEngine must handle the mapping. Finally, the numColors()
+ function returns the number of different colors available for the
+ paint device.
+
+ \sa QPaintEngine, QPainter, {The Coordinate System}, {The Paint
+ System}
+*/
+
+/*!
+ \enum QPaintDevice::PaintDeviceMetric
+
+ Describes the various metrics of a paint device.
+
+ \value PdmWidth The width of the paint device in default
+ coordinate system units (e.g. pixels for QPixmap and QWidget). See
+ also width().
+
+ \value PdmHeight The height of the paint device in default
+ coordinate system units (e.g. pixels for QPixmap and QWidget). See
+ also height().
+
+ \value PdmWidthMM The width of the paint device in millimeters. See
+ also widthMM().
+
+ \value PdmHeightMM The height of the paint device in millimeters. See
+ also heightMM().
+
+ \value PdmNumColors The number of different colors available for
+ the paint device. See also numColors().
+
+ \value PdmDepth The bit depth (number of bit planes) of the paint
+ device. See also depth().
+
+ \value PdmDpiX The horizontal resolution of the device in dots per
+ inch. See also logicalDpiX().
+
+ \value PdmDpiY The vertical resolution of the device in dots per inch. See
+ also logicalDpiY().
+
+ \value PdmPhysicalDpiX The horizontal resolution of the device in
+ dots per inch. See also physicalDpiX().
+
+ \value PdmPhysicalDpiY The vertical resolution of the device in
+ dots per inch. See also physicalDpiY().
+
+ \sa metric()
+*/
+
+/*!
+ \fn QPaintDevice::QPaintDevice()
+
+ Constructs a paint device. This constructor can be invoked only from
+ subclasses of QPaintDevice.
+*/
+
+/*!
+ \fn QPaintDevice::~QPaintDevice()
+
+ Destroys the paint device and frees window system resources.
+*/
+
+/*!
+ \fn int QPaintDevice::devType() const
+
+ \internal
+
+ Returns the device type identifier, which is QInternal::Widget
+ if the device is a QWidget, QInternal::Pixmap if it's a
+ QPixmap, QInternal::Printer if it's a QPrinter,
+ QInternal::Picture if it's a QPicture, or
+ QInternal::UnknownDevice in other cases.
+*/
+
+/*!
+ \fn bool QPaintDevice::paintingActive() const
+
+ Returns true if the device is currently being painted on, i.e. someone has
+ called QPainter::begin() but not yet called QPainter::end() for
+ this device; otherwise returns false.
+
+ \sa QPainter::isActive()
+*/
+
+/*!
+ \fn QPaintEngine *QPaintDevice::paintEngine() const
+
+ Returns a pointer to the paint engine used for drawing on the
+ device.
+*/
+
+/*!
+ \fn int QPaintDevice::metric(PaintDeviceMetric metric) const
+
+ Returns the metric information for the given paint device \a metric.
+
+ \sa PaintDeviceMetric
+*/
+
+/*!
+ \fn int QPaintDevice::width() const
+
+ Returns the width of the paint device in default coordinate system
+ units (e.g. pixels for QPixmap and QWidget).
+
+ \sa widthMM()
+*/
+
+/*!
+ \fn int QPaintDevice::height() const
+
+ Returns the height of the paint device in default coordinate
+ system units (e.g. pixels for QPixmap and QWidget).
+
+ \sa heightMM()
+*/
+
+/*!
+ \fn int QPaintDevice::widthMM() const
+
+ Returns the width of the paint device in millimeters. Due to platform
+ limitations it may not be possible to use this function to determine
+ the actual physical size of a widget on the screen.
+
+ \sa width()
+*/
+
+/*!
+ \fn int QPaintDevice::heightMM() const
+
+ Returns the height of the paint device in millimeters. Due to platform
+ limitations it may not be possible to use this function to determine
+ the actual physical size of a widget on the screen.
+
+ \sa height()
+*/
+
+/*!
+ \fn int QPaintDevice::numColors() const
+
+ Returns the number of different colors available for the paint
+ device. Since this value is an int, it will not be sufficient to represent
+ the number of colors on 32 bit displays, in this case INT_MAX is
+ returned instead.
+*/
+
+/*!
+ \fn int QPaintDevice::depth() const
+
+ Returns the bit depth (number of bit planes) of the paint device.
+*/
+
+/*!
+ \fn int QPaintDevice::logicalDpiX() const
+
+ Returns the horizontal resolution of the device in dots per inch,
+ which is used when computing font sizes. For X11, this is usually
+ the same as could be computed from widthMM().
+
+ Note that if the logicalDpiX() doesn't equal the physicalDpiX(),
+ the corresponding QPaintEngine must handle the resolution mapping.
+
+ \sa logicalDpiY(), physicalDpiX()
+*/
+
+/*!
+ \fn int QPaintDevice::logicalDpiY() const
+
+ Returns the vertical resolution of the device in dots per inch,
+ which is used when computing font sizes. For X11, this is usually
+ the same as could be computed from heightMM().
+
+ Note that if the logicalDpiY() doesn't equal the physicalDpiY(),
+ the corresponding QPaintEngine must handle the resolution mapping.
+
+ \sa logicalDpiX(), physicalDpiY()
+*/
+
+/*!
+ \fn int QPaintDevice::physicalDpiX() const
+
+ Returns the horizontal resolution of the device in dots per inch.
+ For example, when printing, this resolution refers to the physical
+ printer's resolution. The logical DPI on the other hand, refers to
+ the resolution used by the actual paint engine.
+
+ Note that if the physicalDpiX() doesn't equal the logicalDpiX(),
+ the corresponding QPaintEngine must handle the resolution mapping.
+
+ \sa physicalDpiY(), logicalDpiX()
+*/
+
+/*!
+ \fn int QPaintDevice::physicalDpiY() const
+
+ Returns the horizontal resolution of the device in dots per inch.
+ For example, when printing, this resolution refers to the physical
+ printer's resolution. The logical DPI on the other hand, refers to
+ the resolution used by the actual paint engine.
+
+ Note that if the physicalDpiY() doesn't equal the logicalDpiY(),
+ the corresponding QPaintEngine must handle the resolution mapping.
+
+ \sa physicalDpiX(), logicalDpiY()
+*/
diff --git a/src/gui/painting/qpaintdevice_qws.cpp b/src/gui/painting/qpaintdevice_qws.cpp
index 9a6a3d3..b161cb8 100644
--- a/src/gui/painting/qpaintdevice_qws.cpp
+++ b/src/gui/painting/qpaintdevice_qws.cpp
@@ -48,39 +48,6 @@
QT_BEGIN_NAMESPACE
-QPaintDevice::QPaintDevice()
-{
- painters = 0;
-}
-
-extern void qt_painter_removePaintDevice(QPaintDevice *); //qpainter.cpp
-
-
-QPaintDevice::~QPaintDevice()
-{
- if (paintingActive())
- qWarning("QPaintDevice: Cannot destroy paint device that is being "
- "painted");
- qt_painter_removePaintDevice(this);
-}
-
-
-int QPaintDevice::metric(PaintDeviceMetric m) const
-{
- qWarning("QPaintDevice::metrics: Device has no metric information");
- if (m == PdmDpiX) {
- return 72;
- } else if (m == PdmDpiY) {
- return 72;
- } else if (m == PdmNumColors) {
- // FIXME: does this need to be a real value?
- return 256;
- } else {
- qDebug("Unrecognised metric %d!",m);
- return 0;
- }
-}
-
QWSDisplay *QPaintDevice::qwsDisplay()
{
return qt_fbdpy;
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index a8518ea..07fec96 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -145,7 +145,7 @@ QFont QTextItem::font() const
/*!
\class QPaintEngine
- \ingroup multimedia
+ \ingroup painting
\brief The QPaintEngine class provides an abstract definition of how
QPainter draws to a given device on a given platform.
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index d00329b..63c4e32 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2495,10 +2495,7 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)
const QClipData *clip = d->clip();
QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy());
- // ### TODO: remove this eventually...
- static bool NO_BLEND_FUNC = !qgetenv("QT_NO_BLEND_FUNCTIONS").isNull();
-
- if (s->flags.fast_images && !NO_BLEND_FUNC) {
+ if (s->flags.fast_images) {
SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
if (func) {
if (!clip) {
@@ -2511,6 +2508,8 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)
}
}
+
+
d->image_filler.clip = clip;
d->image_filler.initTexture(&img, s->intOpacity, QTextureData::Plain, img.rect());
if (!d->image_filler.blend)
@@ -2545,12 +2544,44 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
const bool aa = s->flags.antialiased || s->flags.bilinear;
- if (!aa && sr.size() == QSize(1, 1)) {
+ int sr_l = qFloor(sr.left());
+ int sr_r = qCeil(sr.right()) - 1;
+ int sr_t = qFloor(sr.top());
+ int sr_b = qCeil(sr.bottom()) - 1;
+
+ if (!aa && sr_l == sr_r && sr_t == sr_b) {
// as fillRect will apply the aliased coordinate delta we need to
// subtract it here as we don't use it for image drawing
QTransform old = s->matrix;
s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);
- fillRect(r, QColor::fromRgba(img.pixel(sr.x(), sr.y())));
+
+ // Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied.
+ QRgb color = img.pixel(sr_l, sr_t);
+ switch (img.format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ case QImage::Format_ARGB6666_Premultiplied:
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB4444_Premultiplied:
+ // Combine premultiplied color with the opacity set on the painter.
+ d->solid_color_filler.solid.color =
+ ((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff)
+ | ((((color & 0xff00ff00) >> 8) * s->intOpacity) & 0xff00ff00);
+ break;
+ default:
+ d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color, s->intOpacity));
+ break;
+ }
+
+ if ((d->solid_color_filler.solid.color & 0xff000000) == 0
+ && s->composition_mode == QPainter::CompositionMode_SourceOver) {
+ return;
+ }
+
+ d->solid_color_filler.clip = d->clip();
+ d->solid_color_filler.adjustSpanMethods();
+ fillRect(r, &d->solid_color_filler);
+
s->matrix = old;
return;
}
@@ -2562,14 +2593,24 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) {
if (s->flags.fast_images) {
- SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()];
- if (func && (!clip || clip->hasRectClip)) {
- func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(),
- img.bits(), img.bytesPerLine(),
- qt_mapRect_non_normalizing(r, s->matrix), sr,
- !clip ? d->deviceRect : clip->clipRect,
- s->intOpacity);
- return;
+ if (s->matrix.type() > QTransform::TxScale) {
+ SrcOverTransformFunc func = qTransformFunctions[d->rasterBuffer->format][img.format()];
+ if (func && (!clip || clip->hasRectClip)) {
+ func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(), img.bits(),
+ img.bytesPerLine(), r, sr, !clip ? d->deviceRect : clip->clipRect,
+ s->matrix, s->intOpacity);
+ return;
+ }
+ } else {
+ SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()];
+ if (func && (!clip || clip->hasRectClip)) {
+ func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(),
+ img.bits(), img.bytesPerLine(),
+ qt_mapRect_non_normalizing(r, s->matrix), sr,
+ !clip ? d->deviceRect : clip->clipRect,
+ s->intOpacity);
+ return;
+ }
}
}
@@ -4056,7 +4097,7 @@ void QRasterPaintEnginePrivate::recalculateFastImages()
s->flags.fast_images = !(s->renderHints & QPainter::SmoothPixmapTransform)
&& rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
- && s->matrix.type() <= QTransform::TxScale;
+ && s->matrix.type() <= QTransform::TxShear;
}
@@ -5189,6 +5230,13 @@ static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans spa
dy = -dy;
}
+ int x_lower_limit = - 128;
+ if (x1 < x_lower_limit) {
+ int cy = dy * (x_lower_limit - x1) / dx + y1;
+ drawLine_midpoint_i(x_lower_limit, cy, x2, y2, span_func, data, style, devRect);
+ return;
+ }
+
if (style == LineDrawNormal)
--x2;
@@ -5326,6 +5374,13 @@ static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans spa
dx = -dx;
}
+ int y_lower_limit = - 128;
+ if (y1 < y_lower_limit) {
+ int cx = dx * (y_lower_limit - y1) / dy + x1;
+ drawLine_midpoint_i(cx, y_lower_limit, x2, y2, span_func, data, style, devRect);
+ return;
+ }
+
if (style == LineDrawNormal)
--y2;
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index 6816aac..a4d34b5 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -2459,15 +2459,23 @@ void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti)
XRectangle rects[rectcount];
int num_rects = 0;
+ QPoint delta(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
+ QRect clip(d->polygonClipper.boundingRect());
for (int i=0; i < path.elementCount(); i+=5) {
int x = qRound(path.elementAt(i).x);
int y = qRound(path.elementAt(i).y);
int w = qRound(path.elementAt(i+1).x) - x;
int h = qRound(path.elementAt(i+2).y) - y;
- rects[num_rects].x = x + qRound(d->matrix.dx());
- rects[num_rects].y = y + qRound(d->matrix.dy());
- rects[num_rects].width = w;
- rects[num_rects].height = h;
+
+ QRect rect = QRect(x + delta.x(), y + delta.y(), w, h);
+ rect = rect.intersected(clip);
+ if (rect.isEmpty())
+ continue;
+
+ rects[num_rects].x = short(rect.x());
+ rects[num_rects].y = short(rect.y());
+ rects[num_rects].width = ushort(rect.width());
+ rects[num_rects].height = ushort(rect.height());
++num_rects;
if (num_rects == rectcount) {
XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 0762138..ab35ead 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -924,8 +924,8 @@ void QPainterPrivate::updateState(QPainterState *newState)
\brief The QPainter class performs low-level painting on widgets and
other paint devices.
- \ingroup multimedia
- \mainclass
+ \ingroup painting
+
\reentrant
QPainter provides highly optimized functions to do most of the
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index ed57e63..5bc4bdb 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -153,7 +153,7 @@ static void qt_debug_path(const QPainterPath &path)
/*!
\class QPainterPath
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
\brief The QPainterPath class provides a container for painting operations,
@@ -2396,7 +2396,7 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y,
/*!
\since 4.1
\class QPainterPathStroker
- \ingroup multimedia
+ \ingroup painting
\brief The QPainterPathStroker class is used to generate fillable
outlines for a given painter path.
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 047fd9b..51929a2 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -52,9 +52,9 @@ typedef QPenPrivate QPenData;
/*!
\class QPen
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
- \mainclass
+
\brief The QPen class defines how a QPainter should draw lines and outlines
of shapes.
diff --git a/src/gui/painting/qpolygon.cpp b/src/gui/painting/qpolygon.cpp
index 87a9848..044b2c5 100644
--- a/src/gui/painting/qpolygon.cpp
+++ b/src/gui/painting/qpolygon.cpp
@@ -91,7 +91,7 @@ static void qt_polygon_isect_line(const QPointF &p1, const QPointF &p2, const QP
\reentrant
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
A QPolygon object is a QVector<QPoint>. The easiest way to add
@@ -489,7 +489,7 @@ QDebug operator<<(QDebug dbg, const QPolygon &a)
floating point precision.
\reentrant
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
A QPolygonF is a QVector<QPointF>. The easiest way to add points
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index f8399af..666719f 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -268,8 +268,8 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke
\brief The QPrinter class is a paint device that paints on a printer.
- \ingroup multimedia
- \mainclass
+ \ingroup printing
+
This device represents a series of pages of printed output, and is
used in almost exactly the same way as other paint devices such as
@@ -2204,7 +2204,7 @@ bool QPrinter::isOptionEnabled( PrinterOption option ) const
\class QPrintEngine
\reentrant
- \ingroup multimedia
+ \ingroup printing
\brief The QPrintEngine class defines an interface for how QPrinter
interacts with a given printing subsystem.
diff --git a/src/gui/painting/qprinterinfo.qdoc b/src/gui/painting/qprinterinfo.qdoc
new file mode 100644
index 0000000..e3cbe96
--- /dev/null
+++ b/src/gui/painting/qprinterinfo.qdoc
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QPrinterInfo
+
+ \brief The QPrinterInfo class gives access to information about
+ existing printers.
+
+ \ingroup printing
+
+ Use the static functions to generate a list of QPrinterInfo
+ objects. Each QPrinterInfo object in the list represents a single
+ printer and can be queried for name, supported paper sizes, and
+ whether or not it is the default printer.
+
+ \since 4.4
+*/
+
+/*!
+ \fn QList<QPrinterInfo> QPrinterInfo::availablePrinters()
+
+ Returns a list of available printers on the system.
+*/
+
+/*!
+ \fn QPrinterInfo QPrinterInfo::defaultPrinter()
+
+ Returns the default printer on the system.
+
+ The return value should be checked using isNull() before being
+ used, in case there is no default printer.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QPrinterInfo::QPrinterInfo()
+
+ Constructs an empty QPrinterInfo object.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QPrinterInfo::QPrinterInfo(const QPrinterInfo& src)
+
+ Constructs a copy of \a src.
+*/
+
+/*!
+ \fn QPrinterInfo::QPrinterInfo(const QPrinter& printer)
+
+ Constructs a QPrinterInfo object from \a printer.
+*/
+
+/*!
+ \fn QPrinterInfo::~QPrinterInfo()
+
+ Destroys the QPrinterInfo object. References to the values in the
+ object become invalid.
+*/
+
+/*!
+ \fn QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src)
+
+ Sets the QPrinterInfo object to be equal to \a src.
+*/
+
+/*!
+ \fn QString QPrinterInfo::printerName() const
+
+ Returns the name of the printer.
+
+ \sa QPrinter::setPrinterName()
+*/
+
+/*!
+ \fn bool QPrinterInfo::isNull() const
+
+ Returns whether this QPrinterInfo object holds a printer definition.
+
+ An empty QPrinterInfo object could result for example from calling
+ defaultPrinter() when there are no printers on the system.
+*/
+
+/*!
+ \fn bool QPrinterInfo::isDefault() const
+
+ Returns whether this printer is the default printer.
+*/
+
+/*!
+ \fn QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
+ \since 4.4
+
+ Returns a list of supported paper sizes by the printer.
+
+ Not all printer drivers support this query, so the list may be empty.
+ On Mac OS X 10.3, this function always returns an empty list.
+*/
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index 4e75911..4ddc8f3 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
\class QRegion
\brief The QRegion class specifies a clip region for a painter.
- \ingroup multimedia
+ \ingroup painting
\ingroup shared
QRegion is used with QPainter::setClipRegion() to limit the paint
diff --git a/src/gui/painting/qstylepainter.cpp b/src/gui/painting/qstylepainter.cpp
index 959caa9..93512d0 100644
--- a/src/gui/painting/qstylepainter.cpp
+++ b/src/gui/painting/qstylepainter.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
elements inside a widget.
\ingroup appearance
- \ingroup multimedia
+ \ingroup painting
QStylePainter extends QPainter with a set of high-level \c
draw...() functions implemented on top of QStyle's API. The
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 8832a3d..859767b 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -93,7 +93,7 @@ QT_BEGIN_NAMESPACE
\class QTransform
\brief The QTransform class specifies 2D transformations of a coordinate system.
\since 4.3
- \ingroup multimedia
+ \ingroup painting
A transformation specifies how to translate, scale, shear, rotate
or project the coordinate system, and is typically used when