From 3879372da9164d7bc6c00b4a00f2dfc03ce7e33e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 9 Dec 2008 21:20:03 +0100 Subject: Use templates to remove code duplication in qdrawhelper. Reviewed-by: Samuel --- src/gui/painting/qdrawhelper.cpp | 427 +++++++++++++-------------------------- 1 file changed, 141 insertions(+), 286 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index efdc778..484d87f 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -425,10 +425,8 @@ static const DestStoreProc destStoreProc[QImage::NImageFormats] = We need 5 fetch methods per surface type: untransformed - transformed - transformed tiled - transformed bilinear - transformed bilinear tiled + transformed (tiled and not tiled) + transformed bilinear (tiled and not tiled) We don't need bounds checks for untransformed, but we need them for the other ones. @@ -671,7 +669,9 @@ qt_fetchUntransformed(uint *, const Operato return ((const uint *)scanLine) + x; } -static const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, +template /* either BlendTransformed or BlendTransformedTiled */ +Q_STATIC_TEMPLATE_FUNCTION +const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { FetchPixelProc fetch = fetchPixelProc[data->texture.format]; @@ -698,84 +698,23 @@ static const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, int px = fx >> 16; int py = fy >> 16; - bool out = (px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height); + if (blendType == BlendTransformedTiled) { + px %= image_width; + py %= image_height; + if (px < 0) px += image_width; + if (py < 0) py += image_height; - const uchar *scanLine = data->texture.scanLine(py); - *b = out ? uint(0) : fetch(scanLine, px, data->texture.colorTable); - fx += fdx; - fy += fdy; - ++b; - } - } else { - const qreal fdx = data->m11; - const qreal fdy = data->m12; - const qreal fdw = data->m13; - - qreal fx = data->m21 * cy + data->m11 * cx + data->dx; - qreal fy = data->m22 * cy + data->m12 * cx + data->dy; - qreal fw = data->m23 * cy + data->m13 * cx + data->m33; - - while (b < end) { - const qreal iw = fw == 0 ? 1 : 1 / fw; - const qreal tx = fx * iw; - const qreal ty = fy * iw; - const int px = int(tx) - (tx < 0); - const int py = int(ty) - (ty < 0); - - bool out = (px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height); - - const uchar *scanLine = data->texture.scanLine(py); - *b = out ? uint(0) : fetch(scanLine, px, data->texture.colorTable); - fx += fdx; - fy += fdy; - fw += fdw; - //force increment to avoid /0 - if (!fw) { - fw += fdw; + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } else { + if ((px < 0) || (px >= image_width) + || (py < 0) || (py >= image_height)) { + *b = uint(0); + } else { + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } } - ++b; - } - } - - return buffer; -} - -static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) -{ - FetchPixelProc fetch = fetchPixelProc[data->texture.format]; - - int image_width = data->texture.width; - int image_height = data->texture.height; - - const qreal cx = x + 0.5; - const qreal cy = y + 0.5; - - const uint *end = buffer + length; - uint *b = buffer; - if (data->fast_matrix) { - // The increment pr x in the scanline - int fdx = (int)(data->m11 * fixed_scale); - int fdy = (int)(data->m12 * fixed_scale); - - int fx = int((data->m21 * cy - + data->m11 * cx + data->dx) * fixed_scale); - int fy = int((data->m22 * cy - + data->m12 * cx + data->dy) * fixed_scale); - - while (b < end) { - int px = fx >> 16; - int py = fy >> 16; - - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; - - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); fx += fdx; fy += fdy; ++b; @@ -796,13 +735,23 @@ static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operat int px = int(tx) - (tx < 0); int py = int(ty) - (ty < 0); - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; + if (blendType == BlendTransformedTiled) { + px %= image_width; + py %= image_height; + if (px < 0) px += image_width; + if (py < 0) py += image_height; - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } else { + if ((px < 0) || (px >= image_width) + || (py < 0) || (py >= image_height)) { + *b = uint(0); + } else { + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } + } fx += fdx; fy += fdy; fw += fdw; @@ -817,8 +766,10 @@ static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operat return buffer; } -static const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +template /* BlendTransformedBilinear or BlendTransformedBilinearTiled */ +Q_STATIC_TEMPLATE_FUNCTION +const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data, + int y, int x, int length) { FetchPixelProc fetch = fetchPixelProc[data->texture.format]; @@ -853,130 +804,27 @@ static const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Ope int idistx = 256 - distx; int idisty = 256 - disty; - x1 = qBound(0, x1, image_width - 1); - x2 = qBound(0, x2, image_width - 1); - y1 = qBound(0, y1, image_height - 1); - y2 = qBound(0, y2, image_height - 1); - - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); - - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); - - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); - - fx += fdx; - fy += fdy; - ++b; - } - } else { - const qreal fdx = data->m11; - const qreal fdy = data->m12; - const qreal fdw = data->m13; - - qreal fx = data->m21 * cy + data->m11 * cx + data->dx; - qreal fy = data->m22 * cy + data->m12 * cx + data->dy; - qreal fw = data->m23 * cy + data->m13 * cx + data->m33; - - while (b < end) { - const qreal iw = fw == 0 ? 1 : 1 / fw; - const qreal px = fx * iw - 0.5; - const qreal py = fy * iw - 0.5; - - int x1 = int(px) - (px < 0); - int x2 = x1 + 1; - int y1 = int(py) - (py < 0); - int y2 = y1 + 1; - - int distx = int((px - x1) * 256); - int disty = int((py - y1) * 256); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 = qBound(0, x1, image_width - 1); - x2 = qBound(0, x2, image_width - 1); - y1 = qBound(0, y1, image_height - 1); - y2 = qBound(0, y2, image_height - 1); - - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); - - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); - - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); - - fx += fdx; - fy += fdy; - fw += fdw; - //force increment to avoid /0 - if (!fw) { - fw += fdw; + if (blendType == BlendTransformedBilinearTiled) { + x1 %= image_width; + x2 %= image_width; + y1 %= image_height; + y2 %= image_height; + + if (x1 < 0) x1 += image_width; + if (x2 < 0) x2 += image_width; + if (y1 < 0) y1 += image_height; + if (y2 < 0) y2 += image_height; + + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + } else { + x1 = qBound(0, x1, image_width - 1); + x2 = qBound(0, x2, image_width - 1); + y1 = qBound(0, y1, image_height - 1); + y2 = qBound(0, y2, image_height - 1); } - ++b; - } - } - - return buffer; -} - -static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) -{ - FetchPixelProc fetch = fetchPixelProc[data->texture.format]; - - int image_width = data->texture.width; - int image_height = data->texture.height; - - const qreal cx = x + 0.5; - const qreal cy = y + 0.5; - - const uint *end = buffer + length; - uint *b = buffer; - if (data->fast_matrix) { - // The increment pr x in the scanline - int fdx = (int)(data->m11 * fixed_scale); - int fdy = (int)(data->m12 * fixed_scale); - - int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale); - int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale); - - fx -= half_point; - fy -= half_point; - while (b < end) { - int x1 = (fx >> 16); - int x2 = x1 + 1; - int y1 = (fy >> 16); - int y2 = y1 + 1; - - int distx = ((fx - (x1 << 16)) >> 8); - int disty = ((fy - (y1 << 16)) >> 8); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 %= image_width; - x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; - if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); @@ -1018,20 +866,27 @@ static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, cons int idistx = 256 - distx; int idisty = 256 - disty; - x1 %= image_width; - x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; - if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); + if (blendType == BlendTransformedBilinearTiled) { + x1 %= image_width; + x2 %= image_width; + y1 %= image_height; + y2 %= image_height; + + if (x1 < 0) x1 += image_width; + if (x2 < 0) x2 += image_width; + if (y1 < 0) y1 += image_height; + if (y2 < 0) y2 += image_height; + + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + } else { + x1 = qBound(0, x1, image_width - 1); + x2 = qBound(0, x2, image_width - 1); + y1 = qBound(0, y1, image_height - 1); + y2 = qBound(0, y2, image_height - 1); + } const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); @@ -1135,75 +990,75 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { // Transformed { 0, // Invalid - fetchTransformed, // Mono - fetchTransformed, // MonoLsb - fetchTransformed, // Indexed8 - fetchTransformed, // RGB32 - fetchTransformed, // ARGB32 - fetchTransformed, // ARGB32_Premultiplied - fetchTransformed, // RGB16 - fetchTransformed, // ARGB8565_Premultiplied - fetchTransformed, // RGB666 - fetchTransformed, // ARGB6666_Premultiplied - fetchTransformed, // RGB555 - fetchTransformed, // ARGB8555_Premultiplied - fetchTransformed, // RGB888 - fetchTransformed, // RGB444 - fetchTransformed, // ARGB4444_Premultiplied + fetchTransformed, // Mono + fetchTransformed, // MonoLsb + fetchTransformed, // Indexed8 + fetchTransformed, // RGB32 + fetchTransformed, // ARGB32 + fetchTransformed, // ARGB32_Premultiplied + fetchTransformed, // RGB16 + fetchTransformed, // ARGB8565_Premultiplied + fetchTransformed, // RGB666 + fetchTransformed, // ARGB6666_Premultiplied + fetchTransformed, // RGB555 + fetchTransformed, // ARGB8555_Premultiplied + fetchTransformed, // RGB888 + fetchTransformed, // RGB444 + fetchTransformed, // ARGB4444_Premultiplied }, { 0, // TransformedTiled - fetchTransformedTiled, // Mono - fetchTransformedTiled, // MonoLsb - fetchTransformedTiled, // Indexed8 - fetchTransformedTiled, // RGB32 - fetchTransformedTiled, // ARGB32 - fetchTransformedTiled, // ARGB32_Premultiplied - fetchTransformedTiled, // RGB16 - fetchTransformedTiled, // ARGB8565_Premultiplied - fetchTransformedTiled, // RGB666 - fetchTransformedTiled, // ARGB6666_Premultiplied - fetchTransformedTiled, // RGB555 - fetchTransformedTiled, // ARGB8555_Premultiplied - fetchTransformedTiled, // RGB888 - fetchTransformedTiled, // RGB444 - fetchTransformedTiled, // ARGB4444_Premultiplied + fetchTransformed, // Mono + fetchTransformed, // MonoLsb + fetchTransformed, // Indexed8 + fetchTransformed, // RGB32 + fetchTransformed, // ARGB32 + fetchTransformed, // ARGB32_Premultiplied + fetchTransformed, // RGB16 + fetchTransformed, // ARGB8565_Premultiplied + fetchTransformed, // RGB666 + fetchTransformed, // ARGB6666_Premultiplied + fetchTransformed, // RGB555 + fetchTransformed, // ARGB8555_Premultiplied + fetchTransformed, // RGB888 + fetchTransformed, // RGB444 + fetchTransformed, // ARGB4444_Premultiplied }, { 0, // Bilinear - fetchTransformedBilinear, // Mono - fetchTransformedBilinear, // MonoLsb - fetchTransformedBilinear, // Indexed8 - fetchTransformedBilinear, // RGB32 - fetchTransformedBilinear, // ARGB32 - fetchTransformedBilinear, // ARGB32_Premultiplied - fetchTransformedBilinear, // RGB16 - fetchTransformedBilinear, // ARGB8565_Premultiplied - fetchTransformedBilinear, // RGB666 - fetchTransformedBilinear, // ARGB6666_Premultiplied - fetchTransformedBilinear, // RGB555 - fetchTransformedBilinear, // ARGB8555_Premultiplied - fetchTransformedBilinear, // RGB888 - fetchTransformedBilinear, // RGB444 - fetchTransformedBilinear // ARGB4444_Premultiplied + fetchTransformedBilinear, // Mono + fetchTransformedBilinear, // MonoLsb + fetchTransformedBilinear, // Indexed8 + fetchTransformedBilinear, // RGB32 + fetchTransformedBilinear, // ARGB32 + fetchTransformedBilinear, // ARGB32_Premultiplied + fetchTransformedBilinear, // RGB16 + fetchTransformedBilinear, // ARGB8565_Premultiplied + fetchTransformedBilinear, // RGB666 + fetchTransformedBilinear, // ARGB6666_Premultiplied + fetchTransformedBilinear, // RGB555 + fetchTransformedBilinear, // ARGB8555_Premultiplied + fetchTransformedBilinear, // RGB888 + fetchTransformedBilinear, // RGB444 + fetchTransformedBilinear // ARGB4444_Premultiplied }, { 0, // BilinearTiled - fetchTransformedBilinearTiled, // Mono - fetchTransformedBilinearTiled, // MonoLsb - fetchTransformedBilinearTiled, // Indexed8 - fetchTransformedBilinearTiled, // RGB32 - fetchTransformedBilinearTiled, // ARGB32 - fetchTransformedBilinearTiled, // ARGB32_Premultiplied - fetchTransformedBilinearTiled, // RGB16 - fetchTransformedBilinearTiled, // ARGB8565_Premultiplied - fetchTransformedBilinearTiled, // RGB666 - fetchTransformedBilinearTiled, // ARGB6666_Premultiplied - fetchTransformedBilinearTiled, // RGB555 - fetchTransformedBilinearTiled, // ARGB8555_Premultiplied - fetchTransformedBilinearTiled, // RGB888 - fetchTransformedBilinearTiled, // RGB444 - fetchTransformedBilinearTiled // ARGB4444_Premultiplied + fetchTransformedBilinear, // Mono + fetchTransformedBilinear, // MonoLsb + fetchTransformedBilinear, // Indexed8 + fetchTransformedBilinear, // RGB32 + fetchTransformedBilinear, // ARGB32 + fetchTransformedBilinear, // ARGB32_Premultiplied + fetchTransformedBilinear, // RGB16 + fetchTransformedBilinear, // ARGB8565_Premultiplied + fetchTransformedBilinear, // RGB666 + fetchTransformedBilinear, // ARGB6666_Premultiplied + fetchTransformedBilinear, // RGB555 + fetchTransformedBilinear, // ARGB8555_Premultiplied + fetchTransformedBilinear, // RGB888 + fetchTransformedBilinear, // RGB444 + fetchTransformedBilinear // ARGB4444_Premultiplied }, }; -- cgit v0.12