diff options
author | Matthew Hoops | 2011-12-12 15:25:28 -0500 |
---|---|---|
committer | Matthew Hoops | 2011-12-12 15:25:28 -0500 |
commit | 00279659b22cbd5db739d5351e83a9fc2a2ae408 (patch) | |
tree | 497f06f46820043cbdf1725652b8f0073223e24a /graphics | |
parent | d932df79bed5aac97e17c0920a5e75cb5ce733ee (diff) | |
parent | d1628feb761acc9f4607f64de3eb620fea53bcc9 (diff) | |
download | scummvm-rg350-00279659b22cbd5db739d5351e83a9fc2a2ae408.tar.gz scummvm-rg350-00279659b22cbd5db739d5351e83a9fc2a2ae408.tar.bz2 scummvm-rg350-00279659b22cbd5db739d5351e83a9fc2a2ae408.zip |
Merge remote branch 'upstream/master' into pegasus
Conflicts:
video/qt_decoder.cpp
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/VectorRenderer.cpp | 28 | ||||
-rw-r--r-- | graphics/VectorRenderer.h | 3 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.cpp | 543 | ||||
-rw-r--r-- | graphics/VectorRendererSpec.h | 8 | ||||
-rw-r--r-- | graphics/pict.cpp | 2 | ||||
-rw-r--r-- | graphics/png.cpp | 4 | ||||
-rw-r--r-- | graphics/png.h | 13 | ||||
-rw-r--r-- | graphics/scaler/scale2x.h | 4 | ||||
-rw-r--r-- | graphics/scaler/scale3x.h | 4 | ||||
-rw-r--r-- | graphics/scaler/scalebit.h | 4 | ||||
-rw-r--r-- | graphics/surface.cpp | 8 | ||||
-rw-r--r-- | graphics/yuv_to_rgb.h | 2 |
12 files changed, 413 insertions, 210 deletions
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index 4dbcd9845f..30ef9eeeeb 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -78,27 +78,29 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect & switch (step.xAlign) { case Graphics::DrawStep::kVectorAlignManual: - if (step.x >= 0) in_x = area.left + step.x; - else in_x = area.left + area.width() + step.x; // value relative to the opposite corner. + if (step.x >= 0) + in_x = area.left + step.x + step.padding.left; + else + in_x = area.left + area.width() + step.x + step.padding.left; // value relative to the opposite corner. break; case Graphics::DrawStep::kVectorAlignCenter: - in_x = area.left + (area.width() / 2) - (in_w / 2); + in_x = area.left + (area.width() / 2) - (in_w / 2) + ((step.padding.left + step.padding.right ) / 2); break; case Graphics::DrawStep::kVectorAlignLeft: - in_x = area.left; + in_x = area.left + step.padding.left; break; case Graphics::DrawStep::kVectorAlignRight: - in_x = area.left + area.width() - in_w; + in_x = area.left + area.width() - in_w - step.padding.right; break; default: error("Vertical alignment in horizontal data"); } } else { - in_x = area.left; + in_x = area.left + step.padding.left; in_w = area.width(); } @@ -107,27 +109,29 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect & switch (step.yAlign) { case Graphics::DrawStep::kVectorAlignManual: - if (step.y >= 0) in_y = area.top + step.y; - else in_y = area.top + area.height() + step.y; // relative + if (step.y >= 0) + in_y = area.top + step.y + step.padding.top; + else + in_y = area.top + area.height() + step.y + step.padding.top; // relative break; case Graphics::DrawStep::kVectorAlignCenter: - in_y = area.top + (area.height() / 2) - (in_h / 2); + in_y = area.top + (area.height() / 2) - (in_h / 2) + ((step.padding.top + step.padding.bottom ) / 2) ; break; case Graphics::DrawStep::kVectorAlignTop: - in_y = area.top; + in_y = area.top + step.padding.top; break; case Graphics::DrawStep::kVectorAlignBottom: - in_y = area.top + area.height() - in_h; + in_y = area.top + area.height() - in_h - step.padding.bottom; break; default: error("Horizontal alignment in vertical data"); } } else { - in_y = area.top; + in_y = area.top + step.padding.top; in_h = area.height(); } diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index ec8a8f7245..e98f4aa761 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -55,6 +55,8 @@ struct DrawStep { bool autoWidth, autoHeight; int16 x, y, w, h; /**< width, height and position, if not measured automatically. negative values mean counting from the opposite direction */ + + Common::Rect padding; enum VectorAlignment { kVectorAlignManual, @@ -491,7 +493,6 @@ protected: uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */ int _gradientFactor; /**< Multiplication factor of the active gradient */ - int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */ }; } // End of namespace Graphics diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index a2cb693b78..588e17b6cb 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -77,7 +77,7 @@ inline frac_t fp_sqroot(uint32 x) { HELPER MACROS for Bresenham's circle drawing algorithm Note the proper spelling on this header. */ -#define __BE_ALGORITHM() { \ +#define BE_ALGORITHM() { \ if (f >= 0) { \ y--; \ ddF_y += 2; \ @@ -89,7 +89,7 @@ inline frac_t fp_sqroot(uint32 x) { f += ddF_x + 1; \ } -#define __BE_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py) { \ +#define BE_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py) { \ *(ptr1 + (y) - (px)) = color; \ *(ptr1 + (x) - (py)) = color; \ *(ptr2 - (x) - (py)) = color; \ @@ -100,7 +100,7 @@ inline frac_t fp_sqroot(uint32 x) { *(ptr4 + (y) + (px)) = color; \ } -#define __BE_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) { \ +#define BE_DRAWCIRCLE_XCOLOR(ptr1,ptr2,ptr3,ptr4,x,y,px,py) { \ *(ptr1 + (y) - (px)) = color1; \ *(ptr1 + (x) - (py)) = color2; \ *(ptr2 - (x) - (py)) = color2; \ @@ -111,13 +111,13 @@ inline frac_t fp_sqroot(uint32 x) { *(ptr4 + (y) + (px)) = color3; \ } -#define __BE_RESET() { \ +#define BE_RESET() { \ f = 1 - r; \ ddF_x = 0; ddF_y = -2 * r; \ x = 0; y = r; px = 0; py = pitch * r; \ } -#define __TRIANGLE_MAINX() \ +#define TRIANGLE_MAINX() \ if (error_term >= 0) { \ ptr_right += pitch; \ ptr_left += pitch; \ @@ -128,7 +128,7 @@ inline frac_t fp_sqroot(uint32 x) { ptr_right++; \ ptr_left--; -#define __TRIANGLE_MAINY() \ +#define TRIANGLE_MAINY() \ if (error_term >= 0) { \ ptr_right++; \ ptr_left--; \ @@ -140,7 +140,7 @@ inline frac_t fp_sqroot(uint32 x) { ptr_left += pitch; /** HELPER MACROS for WU's circle drawing algorithm **/ -#define __WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) { \ +#define WU_DRAWCIRCLE(ptr1,ptr2,ptr3,ptr4,x,y,px,py,a) { \ this->blendPixelPtr(ptr1 + (y) - (px), color, a); \ this->blendPixelPtr(ptr1 + (x) - (py), color, a); \ this->blendPixelPtr(ptr2 - (x) - (py), color, a); \ @@ -152,7 +152,7 @@ inline frac_t fp_sqroot(uint32 x) { } // optimized Wu's algorithm -#define __WU_ALGORITHM() { \ +#define WU_ALGORITHM() { \ oldT = T; \ T = fp_sqroot(rsq - y*y) ^ 0xFFFF; \ py += pitch; \ @@ -169,7 +169,7 @@ namespace Graphics { /** * Fills several pixels in a row with a given color. * - * This is a replacement function for Common::set_to, using an unrolled + * This is a replacement function for Common::fill, using an unrolled * loop to maximize performance on most architectures. * This function may (and should) be overloaded in any child renderers * for portable platforms with platform-specific assembly code. @@ -224,17 +224,6 @@ VectorRenderer *createRenderer(int mode) { } template<typename PixelType> -void VectorRendererSpec<PixelType>:: -setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) { - _gradientEnd = _format.RGBToColor(r2, g2, b2); - _gradientStart = _format.RGBToColor(r1, g1, b1); - - Base::_gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask); - Base::_gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask); - Base::_gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask); -} - -template<typename PixelType> VectorRendererSpec<PixelType>:: VectorRendererSpec(PixelFormat format) : _format(format), @@ -246,6 +235,93 @@ VectorRendererSpec(PixelFormat format) : _bitmapAlphaColor = _format.RGBToColor(255, 0, 255); } +/**************************** + * Gradient-related methods * + ****************************/ + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: +setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) { + _gradientEnd = _format.RGBToColor(r2, g2, b2); + _gradientStart = _format.RGBToColor(r1, g1, b1); + + _gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask); + _gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask); + _gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask); +} + +template<typename PixelType> +inline PixelType VectorRendererSpec<PixelType>:: +calcGradient(uint32 pos, uint32 max) { + PixelType output = 0; + pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max; + + output |= ((_gradientStart & _redMask) + ((_gradientBytes[0] * pos) >> 12)) & _redMask; + output |= ((_gradientStart & _greenMask) + ((_gradientBytes[1] * pos) >> 12)) & _greenMask; + output |= ((_gradientStart & _blueMask) + ((_gradientBytes[2] * pos) >> 12)) & _blueMask; + output |= _alphaMask; + + return output; +} + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: +precalcGradient(int h) { + PixelType prevcolor = 0, color; + + _gradCache.resize(0); + _gradIndexes.resize(0); + + for (int i = 0; i < h + 2; i++) { + color = calcGradient(i, h); + if (color != prevcolor || i == 0 || i > h - 1) { + prevcolor = color; + _gradCache.push_back(color); + _gradIndexes.push_back(i); + } + } +} + +template<typename PixelType> +void VectorRendererSpec<PixelType>:: +gradientFill(PixelType *ptr, int width, int x, int y) { + bool ox = ((y & 1) == 1); + int stripSize; + int curGrad = 0; + + while (_gradIndexes[curGrad + 1] <= y) + curGrad++; + + stripSize = _gradIndexes[curGrad + 1] - _gradIndexes[curGrad]; + + int grad = (((y - _gradIndexes[curGrad]) % stripSize) << 2) / stripSize; + + // Dithering: + // +--+ +--+ +--+ +--+ + // | | | | | *| | *| + // | | | *| |* | |**| + // +--+ +--+ +--+ +--+ + // 0 1 2 3 + if (grad == 0 || + _gradCache[curGrad] == _gradCache[curGrad + 1] || // no color change + stripSize < 2) { // the stip is small + colorFill<PixelType>(ptr, ptr + width, _gradCache[curGrad]); + } else if (grad == 3 && ox) { + colorFill<PixelType>(ptr, ptr + width, _gradCache[curGrad + 1]); + } else { + for (int j = x; j < x + width; j++, ptr++) { + bool oy = ((j & 1) == 1); + + if ((ox && oy) || + ((grad == 2 || grad == 3) && ox && !oy) || + (grad == 3 && oy)) + *ptr = _gradCache[curGrad + 1]; + else + *ptr = _gradCache[curGrad]; + } + } +} + template<typename PixelType> void VectorRendererSpec<PixelType>:: fillSurface() { @@ -259,9 +335,11 @@ fillSurface() { } else if (Base::_fillMode == kFillForeground) { colorFill<PixelType>((PixelType *)ptr, (PixelType *)(ptr + pitch * h), _fgColor); } else if (Base::_fillMode == kFillGradient) { - int i = h; - while (i--) { - colorFill<PixelType>((PixelType *)ptr, (PixelType *)(ptr + pitch), calcGradient(h - i, h)); + precalcGradient(h); + + for (int i = 0; i < h; i++) { + gradientFill((PixelType *)ptr, _activeSurface->w, 0, i); + ptr += pitch; } } @@ -413,20 +491,6 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { (((int)(idst & _alphaMask) * alpha) >> 8)))); } -template<typename PixelType> -inline PixelType VectorRendererSpec<PixelType>:: -calcGradient(uint32 pos, uint32 max) { - PixelType output = 0; - pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max; - - output |= ((_gradientStart & _redMask) + ((Base::_gradientBytes[0] * pos) >> 12)) & _redMask; - output |= ((_gradientStart & _greenMask) + ((Base::_gradientBytes[1] * pos) >> 12)) & _greenMask; - output |= ((_gradientStart & _blueMask) + ((Base::_gradientBytes[2] * pos) >> 12)) & _blueMask; - output |= _alphaMask; - - return output; -} - /******************************************************************** ******************************************************************** * Primitive shapes drawing - Public API calls - VectorRendererSpec * @@ -693,25 +757,49 @@ drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { if (Base::_dynamicData != 0) orient = (TriangleOrientation)Base::_dynamicData; - int newW = w / 2; - if (newW % 2) newW++; + if (w == h) { + int newW = w; - switch (orient) { + switch (orient) { case kTriangleUp: case kTriangleDown: - drawTriangleFast(x + (newW / 2), y + (h / 2) - (newW / 2), newW, (orient == kTriangleDown), color, Base::_fillMode); + //drawTriangleFast(x, y, newW, (orient == kTriangleDown), color, Base::_fillMode); + drawTriangleVertAlg(x, y, newW, newW, (orient == kTriangleDown), color, Base::_fillMode); break; case kTriangleLeft: case kTriangleRight: case kTriangleAuto: break; - } + } + + if (Base::_strokeWidth > 0) + if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) { + //drawTriangleFast(x, y, newW, (orient == kTriangleDown), _fgColor, kFillDisabled); + drawTriangleVertAlg(x, y, newW, newW, (orient == kTriangleDown), color, Base::_fillMode); + } + } else { + int newW = w; + int newH = h; + + switch (orient) { + case kTriangleUp: + case kTriangleDown: + drawTriangleVertAlg(x, y, newW, newH, (orient == kTriangleDown), color, Base::_fillMode); + break; + + case kTriangleLeft: + case kTriangleRight: + case kTriangleAuto: + break; + } - if (Base::_strokeWidth > 0) - if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) { - drawTriangleFast(x + (newW / 2), y + (h / 2) - (newW / 2), newW, (orient == kTriangleDown), _fgColor, kFillDisabled); + if (Base::_strokeWidth > 0) { + if (Base::_fillMode == kFillBackground || Base::_fillMode == kFillGradient) { + drawTriangleVertAlg(x, y, newW, newH, (orient == kTriangleDown), _fgColor, kFillDisabled); + } } + } } @@ -746,11 +834,11 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); sp += pitch; - __BE_RESET(); + BE_RESET(); r--; while (x++ < y) { - __BE_ALGORITHM(); + BE_ALGORITHM(); *(ptr_tr + (y) - (px)) = color; *(ptr_tr + (x) - (py)) = color; *(ptr_tl - (x) - (py)) = color; @@ -790,13 +878,13 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer: } } } else { - __BE_RESET(); + BE_RESET(); PixelType color1, color2; color1 = color2 = color; while (x++ < y) { - __BE_ALGORITHM(); + BE_ALGORITHM(); if (fill_m == kFillGradient) { color1 = calcGradient(real_radius - x, long_h); @@ -1005,130 +1093,249 @@ drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color) { } /** VERTICAL TRIANGLE DRAWING ALGORITHM **/ +/** + FIXED POINT ARITHMETIC +**/ + +#define FIXED_POINT 1 + +#if FIXED_POINT +#define ipart(x) ((x) & ~0xFF) +// This is not really correct since gradient is not percentage, but [0..255] +#define rfpart(x) ((0x100 - ((x) & 0xFF)) * 100 >> 8) +//#define rfpart(x) (0x100 - ((x) & 0xFF)) +#else +#define ipart(x) ((int)x) +#define round(x) (ipart(x + 0.5)) +#define fpart(x) (x - ipart(x)) +#define rfpart(x) (int)((1 - fpart(x)) * 100) +#endif + template<typename PixelType> void VectorRendererSpec<PixelType>:: drawTriangleVertAlg(int x1, int y1, int w, int h, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) { - int dx = w >> 1, dy = h, gradient_h = 0; int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; - PixelType *ptr_right = 0, *ptr_left = 0; - - if (inverted) { - ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1); - ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + w, y1); - } else { - ptr_right = ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + dx, y1); + int gradient_h = 0; + if (!inverted) { + pitch = -pitch; + y1 += h; } + + PixelType *ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1); + PixelType *floor = ptr_right - 1; + PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + w, y1); + + int x2 = x1 + w / 2; + int y2 = y1 + h; + +#if FIXED_POINT + int dx = (x2 - x1) << 8; + int dy = (y2 - y1) << 8; + + if (abs(dx) > abs(dy)) { +#else + double dx = (double)x2 - (double)x1; + double dy = (double)y2 - (double)y1; - if (dx > dy) { - int ddy = dy * 2; - int dysub = ddy - (dx * 2); - int error_term = ddy - dx; + if (fabs(dx) > fabs(dy)) { +#endif + while (floor++ != ptr_left) + blendPixelPtr(floor, color, 50); + +#if FIXED_POINT + int gradient = (dy << 8) / dx; + int intery = (y1 << 8) + gradient; +#else + double gradient = dy / dx; + double intery = y1 + gradient; +#endif - switch (fill_m) { - case kFillDisabled: - while (dx--) { - __TRIANGLE_MAINX(); - *ptr_right = color; - *ptr_left = color; + for (int x = x1 + 1; x < x2; x++) { +#if FIXED_POINT + if (intery + gradient > ipart(intery) + 0x100) { +#else + if (intery + gradient > ipart(intery) + 1) { +#endif + ptr_right++; + ptr_left--; } - colorFill<PixelType>(ptr_left, ptr_right, color); - break; - case kFillForeground: - case kFillBackground: - while (dx--) { - __TRIANGLE_MAINX(); - if (inverted) colorFill<PixelType>(ptr_right, ptr_left, color); - else colorFill<PixelType>(ptr_left, ptr_right, color); + ptr_left += pitch; + ptr_right += pitch; + + intery += gradient; + + switch (fill_m) { + case kFillDisabled: + *ptr_left = *ptr_right = color; + break; + case kFillForeground: + case kFillBackground: + colorFill<PixelType>(ptr_right + 1, ptr_left, color); + blendPixelPtr(ptr_right, color, rfpart(intery)); + blendPixelPtr(ptr_left, color, rfpart(intery)); + break; + case kFillGradient: + colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h)); + blendPixelPtr(ptr_right, color, rfpart(intery)); + blendPixelPtr(ptr_left, color, rfpart(intery)); + break; } - break; + } + + return; + } + +#if FIXED_POINT + if (abs(dx) < abs(dy)) { +#else + if (fabs(dx) < fabs(dy)) { +#endif + ptr_left--; + while (floor++ != ptr_left) + blendPixelPtr(floor, color, 50); + +#if FIXED_POINT + int gradient = (dx << 8) / (dy + 0x100); + int interx = (x1 << 8) + gradient; +#else + double gradient = dx / (dy+1); + double interx = x1 + gradient; +#endif - case kFillGradient: - while (dx--) { - __TRIANGLE_MAINX(); - if (inverted) colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h)); - else colorFill<PixelType>(ptr_left, ptr_right, calcGradient(gradient_h++, h)); + for (int y = y1 + 1; y < y2; y++) { +#if FIXED_POINT + if (interx + gradient > ipart(interx) + 0x100) { +#else + if (interx + gradient > ipart(interx) + 1) { +#endif + ptr_right++; + ptr_left--; + } + + ptr_left += pitch; + ptr_right += pitch; + + interx += gradient; + + switch (fill_m) { + case kFillDisabled: + *ptr_left = *ptr_right = color; + break; + case kFillForeground: + case kFillBackground: + colorFill<PixelType>(ptr_right + 1, ptr_left, color); + blendPixelPtr(ptr_right, color, rfpart(interx)); + blendPixelPtr(ptr_left, color, rfpart(interx)); + break; + case kFillGradient: + colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h)); + blendPixelPtr(ptr_right, color, rfpart(interx)); + blendPixelPtr(ptr_left, color, rfpart(interx)); + break; } - break; } - } else { - int ddx = dx * 2; - int dxsub = ddx - (dy * 2); - int error_term = ddx - dy; + + return; + } + + ptr_left--; + + while (floor++ != ptr_left) + blendPixelPtr(floor, color, 50); + +#if FIXED_POINT + int gradient = (dx / dy) << 8; + int interx = (x1 << 8) + gradient; +#else + double gradient = dx / dy; + double interx = x1 + gradient; +#endif + + for (int y = y1 + 1; y < y2; y++) { + ptr_right++; + ptr_left--; + + ptr_left += pitch; + ptr_right += pitch; + interx += gradient; + switch (fill_m) { case kFillDisabled: - while (dy--) { - __TRIANGLE_MAINY(); - *ptr_right = color; - *ptr_left = color; - } - colorFill<PixelType>(ptr_left, ptr_right, color); + *ptr_left = *ptr_right = color; break; - case kFillForeground: case kFillBackground: - while (dy--) { - __TRIANGLE_MAINY(); - if (inverted) colorFill<PixelType>(ptr_right, ptr_left, color); - else colorFill<PixelType>(ptr_left, ptr_right, color); - } + colorFill<PixelType>(ptr_right + 1, ptr_left, color); + blendPixelPtr(ptr_right, color, rfpart(interx)); + blendPixelPtr(ptr_left, color, rfpart(interx)); break; case kFillGradient: - while (dy--) { - __TRIANGLE_MAINY(); - if (inverted) colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h)); - else colorFill<PixelType>(ptr_left, ptr_right, calcGradient(gradient_h++, h)); - } + colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, h)); + blendPixelPtr(ptr_right, color, rfpart(interx)); + blendPixelPtr(ptr_left, color, rfpart(interx)); break; } } + } - /** VERTICAL TRIANGLE DRAWING - FAST VERSION FOR SQUARED TRIANGLES */ template<typename PixelType> void VectorRendererSpec<PixelType>:: drawTriangleFast(int x1, int y1, int size, bool inverted, PixelType color, VectorRenderer::FillMode fill_m) { int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; - int hstep = 0, dy = size; - bool grad = (fill_m == kFillGradient); - - PixelType *ptr_right = 0, *ptr_left = 0; - - if (x1 + size > Base::_activeSurface->w || x1 < 0 || - y1 + size > Base::_activeSurface->h || y1 < 0) - return; - - if (inverted) { - ptr_left = (PixelType *)_activeSurface->getBasePtr(x1, y1); - ptr_right = (PixelType *)_activeSurface->getBasePtr(x1 + size, y1); - } else { - ptr_left = (PixelType *)_activeSurface->getBasePtr(x1, y1 + size); - ptr_right = (PixelType *)_activeSurface->getBasePtr(x1 + size, y1 + size); + + if (!inverted) { pitch = -pitch; + y1 += size; } - - if (fill_m == kFillDisabled) { - while (ptr_left < ptr_right) { - *ptr_left = color; - *ptr_right = color; - ptr_left += pitch; - ptr_right += pitch; - if (hstep++ % 2) { - ptr_left++; - ptr_right--; - } + + int gradient_h = 0; + PixelType *ptr_right = (PixelType *)_activeSurface->getBasePtr(x1, y1); + PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x1 + size, y1); + int x2 = x1 + size / 2; + int y2 = y1 + size; + int deltaX = abs(x2 - x1); + int deltaY = abs(y2 - y1); + int signX = x1 < x2 ? 1 : -1; + int signY = y1 < y2 ? 1 : -1; + int error = deltaX - deltaY; + + colorFill<PixelType>(ptr_right, ptr_left, color); + + while (1) { + switch (fill_m) { + case kFillDisabled: + *ptr_left = *ptr_right = color; + break; + case kFillForeground: + case kFillBackground: + colorFill<PixelType>(ptr_right, ptr_left, color); + break; + case kFillGradient: + colorFill<PixelType>(ptr_right, ptr_left, calcGradient(gradient_h++, size)); + break; } - } else { - while (ptr_left < ptr_right) { - colorFill<PixelType>(ptr_left, ptr_right, grad ? calcGradient(dy--, size) : color); - ptr_left += pitch; + + if (x1 == x2 && y1 == y2) + break; + + int error2 = error * 2; + + if (error2 > -deltaY) { + error -= deltaY; + x1 += signX; + ptr_right += signX; + ptr_left += -signX; + } + + if (error2 < deltaX) { + error += deltaX; + y1 += signY; ptr_right += pitch; - if (hstep++ % 2) { - ptr_left++; - ptr_right--; - } + ptr_left += pitch; } } } @@ -1158,16 +1365,16 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color); sp += pitch; - __BE_RESET(); + BE_RESET(); r--; while (x++ < y) { - __BE_ALGORITHM(); - __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); + BE_ALGORITHM(); + BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); if (Base::_strokeWidth > 1) { - __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py); - __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py); + BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py); + BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py); } } } @@ -1179,12 +1386,12 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto ptr_fill += pitch; } } else { - __BE_RESET(); + BE_RESET(); PixelType color1, color2, color3, color4; if (fill_m == kFillGradient) { while (x++ < y) { - __BE_ALGORITHM(); + BE_ALGORITHM(); color1 = calcGradient(real_radius - x, long_h); color2 = calcGradient(real_radius - y, long_h); @@ -1197,11 +1404,11 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color4); colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color3); - __BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); + BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); } } else { while (x++ < y) { - __BE_ALGORITHM(); + BE_ALGORITHM(); colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color); colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color); @@ -1210,7 +1417,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color); // do not remove - messes up the drawing at lower resolutions - __BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); + BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py); } } @@ -1235,7 +1442,7 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f if (fill_m == kFillDisabled) { while (sw++ < Base::_strokeWidth) { - __BE_RESET(); + BE_RESET(); r--; *(ptr + y) = color; @@ -1244,21 +1451,21 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f *(ptr - py) = color; while (x++ < y) { - __BE_ALGORITHM(); - __BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py); + BE_ALGORITHM(); + BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py); if (Base::_strokeWidth > 1) { - __BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x - 1, y, px, py); - __BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px - pitch, py); + BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x - 1, y, px, py); + BE_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px - pitch, py); } } } } else { colorFill<PixelType>(ptr - r, ptr + r, color); - __BE_RESET(); + BE_RESET(); while (x++ < y) { - __BE_ALGORITHM(); + BE_ALGORITHM(); colorFill<PixelType>(ptr - x + py, ptr + x + py, color); colorFill<PixelType>(ptr - x - py, ptr + x - py, color); colorFill<PixelType>(ptr - y + px, ptr + y + px, color); @@ -1330,7 +1537,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) { int short_h = h - (2 * r) + 1; - __BE_RESET(); + BE_RESET(); // HACK: As we are drawing circles exploting 8-axis symmetry, // there are 4 pixels on each circle which are drawn twice. @@ -1339,7 +1546,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) { uint32 hb = 0; while (x++ < y) { - __BE_ALGORITHM(); + BE_ALGORITHM(); if (((1 << x) & hb) == 0) { blendFill(ptr_tr - px - r, ptr_tr + y - px, 0, alpha); @@ -1392,7 +1599,7 @@ drawRoundedSquareFakeBevel(int x1, int y1, int r, int w, int h, int amount) { py = 0; while (x > y++) { - __WU_ALGORITHM(); + WU_ALGORITHM(); blendPixelPtr(ptr_tr + (y) - (px - pitch), color, a2); blendPixelPtr(ptr_tr + (x - 1) - (py), color, a2); @@ -1514,13 +1721,13 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto py = 0; while (x > y++) { - __WU_ALGORITHM(); + WU_ALGORITHM(); if (sw != 1 && sw != Base::_strokeWidth) a2 = a1 = 255; - __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - pitch), py, a2); - __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); + WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - pitch), py, a2); + WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); } } @@ -1538,7 +1745,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto py = 0; while (x > 1 + y++) { - __WU_ALGORITHM(); + WU_ALGORITHM(); colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color); colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color); @@ -1546,7 +1753,7 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color); colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color); - __WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); + WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1); } ptr_fill += pitch * r; @@ -1585,13 +1792,13 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f *(ptr - px) = (PixelType)color; while (x > y++) { - __WU_ALGORITHM(); + WU_ALGORITHM(); if (sw != 1 && sw != Base::_strokeWidth) a2 = a1 = 255; - __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, (x - 1), y, (px - pitch), py, a2); - __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); + WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, (x - 1), y, (px - pitch), py, a2); + WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); } } } else { @@ -1603,14 +1810,14 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f py = 0; while (x > y++) { - __WU_ALGORITHM(); + WU_ALGORITHM(); colorFill<PixelType>(ptr - x + py, ptr + x + py, color); colorFill<PixelType>(ptr - x - py, ptr + x - py, color); colorFill<PixelType>(ptr - y + px, ptr + y + px, color); colorFill<PixelType>(ptr - y - px, ptr + y - px, color); - __WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); + WU_DRAWCIRCLE(ptr, ptr, ptr, ptr, x, y, px, py, a1); } } } diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h index 3ba7d88e4e..fe64f9774d 100644 --- a/graphics/VectorRendererSpec.h +++ b/graphics/VectorRendererSpec.h @@ -185,6 +185,9 @@ protected: */ inline PixelType calcGradient(uint32 pos, uint32 max); + void precalcGradient(int h); + void gradientFill(PixelType *first, int width, int x, int y); + /** * Fills several pixels in a row with a given color and the specified alpha blending. * @@ -208,6 +211,11 @@ protected: PixelType _gradientStart; /**< Start color for the fill gradient */ PixelType _gradientEnd; /**< End color for the fill gradient */ + int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */ + + Common::Array<PixelType> _gradCache; + Common::Array<int> _gradIndexes; + PixelType _bevelColor; PixelType _bitmapAlphaColor; }; diff --git a/graphics/pict.cpp b/graphics/pict.cpp index 0f4dcd463f..dcd0df8e10 100644 --- a/graphics/pict.cpp +++ b/graphics/pict.cpp @@ -467,7 +467,7 @@ void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalet stream->readUint16BE(); uint16 packType; - uint16 pixelSize; + uint16 pixelSize; // FIXME: unused // Top two bits signify PixMap vs BitMap if (rowBytes & 0xC000) { diff --git a/graphics/png.cpp b/graphics/png.cpp index 2189fd333f..cea8b575ad 100644 --- a/graphics/png.cpp +++ b/graphics/png.cpp @@ -22,8 +22,6 @@ #include "graphics/png.h" -#ifdef GRAPHICS_PNG_H - #include "graphics/pixelformat.h" #include "graphics/surface.h" @@ -487,5 +485,3 @@ void PNG::readTransparencyChunk(uint32 chunkLength) { } } // End of Graphics namespace - -#endif // GRAPHICS_PNG_H diff --git a/graphics/png.h b/graphics/png.h index 3f8ea85320..25f9c1e7bc 100644 --- a/graphics/png.h +++ b/graphics/png.h @@ -23,20 +23,11 @@ /* * PNG decoder used in engines: * - sword25 + * - ScummVM GUI * Dependencies: * - zlib */ -// Currently, only the sword25 engine uses the PNG decoder, so skip compiling -// it if sword25 is not enabled, or if zlib (a required dependency) is not -// enabled. - -#if !(defined(ENABLE_SWORD25) || defined(USE_ZLIB)) - -// Do not compile the PNG decoder code - -#else - #ifndef GRAPHICS_PNG_H #define GRAPHICS_PNG_H @@ -176,5 +167,3 @@ private: } // End of Graphics namespace #endif // GRAPHICS_PNG_H - -#endif // Engine and zlib guard diff --git a/graphics/scaler/scale2x.h b/graphics/scaler/scale2x.h index b0c887d43c..917e817a0d 100644 --- a/graphics/scaler/scale2x.h +++ b/graphics/scaler/scale2x.h @@ -18,8 +18,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef __SCALE2X_H -#define __SCALE2X_H +#ifndef SCALER_SCALE2X_H +#define SCALER_SCALE2X_H #if defined(_MSC_VER) #define __restrict__ diff --git a/graphics/scaler/scale3x.h b/graphics/scaler/scale3x.h index ad5604d086..8d93914400 100644 --- a/graphics/scaler/scale3x.h +++ b/graphics/scaler/scale3x.h @@ -18,8 +18,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef __SCALE3X_H -#define __SCALE3X_H +#ifndef SCALER_SCALE3X_H +#define SCALER_SCALE3X_H #if defined(_MSC_VER) #define __restrict__ diff --git a/graphics/scaler/scalebit.h b/graphics/scaler/scalebit.h index 6e4a30caf0..75f9dae455 100644 --- a/graphics/scaler/scalebit.h +++ b/graphics/scaler/scalebit.h @@ -33,8 +33,8 @@ * - derivative works of the program are allowed. */ -#ifndef __SCALEBIT_H -#define __SCALEBIT_H +#ifndef SCALER_SCALEBIT_H +#define SCALER_SCALEBIT_H int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height); void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height); diff --git a/graphics/surface.cpp b/graphics/surface.cpp index c1c676ed0b..d5e2692338 100644 --- a/graphics/surface.cpp +++ b/graphics/surface.cpp @@ -106,10 +106,10 @@ void Surface::hLine(int x, int y, int x2, uint32 color) { memset(ptr, (byte)color, x2 - x + 1); } else if (format.bytesPerPixel == 2) { uint16 *ptr = (uint16 *)getBasePtr(x, y); - Common::set_to(ptr, ptr + (x2 - x + 1), (uint16)color); + Common::fill(ptr, ptr + (x2 - x + 1), (uint16)color); } else if (format.bytesPerPixel == 4) { uint32 *ptr = (uint32 *)getBasePtr(x, y); - Common::set_to(ptr, ptr + (x2 - x + 1), color); + Common::fill(ptr, ptr + (x2 - x + 1), color); } else { error("Surface::hLine: bytesPerPixel must be 1, 2, or 4"); } @@ -183,13 +183,13 @@ void Surface::fillRect(Common::Rect r, uint32 color) { if (format.bytesPerPixel == 2) { uint16 *ptr = (uint16 *)getBasePtr(r.left, r.top); while (height--) { - Common::set_to(ptr, ptr + width, (uint16)color); + Common::fill(ptr, ptr + width, (uint16)color); ptr += pitch / 2; } } else { uint32 *ptr = (uint32 *)getBasePtr(r.left, r.top); while (height--) { - Common::set_to(ptr, ptr + width, color); + Common::fill(ptr, ptr + width, color); ptr += pitch / 4; } } diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h index 2d3b9e634e..259ba09810 100644 --- a/graphics/yuv_to_rgb.h +++ b/graphics/yuv_to_rgb.h @@ -35,8 +35,6 @@ namespace Graphics { -struct Surface; - /** * Convert a YUV420 image to an RGB surface * |