diff options
Diffstat (limited to 'skia/ext')
-rwxr-xr-x | skia/ext/bitmap_platform_device_mac.h | 1 | ||||
-rw-r--r-- | skia/ext/bitmap_platform_device_win.cc | 134 | ||||
-rw-r--r-- | skia/ext/bitmap_platform_device_win.h | 16 | ||||
-rw-r--r-- | skia/ext/platform_canvas_unittest.cc | 6 | ||||
-rwxr-xr-x | skia/ext/platform_device_mac.cc | 9 | ||||
-rwxr-xr-x | skia/ext/platform_device_mac.h | 9 | ||||
-rw-r--r-- | skia/ext/platform_device_win.h | 20 |
7 files changed, 23 insertions, 172 deletions
diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h index 2e31eb2..7116a1b 100755 --- a/skia/ext/bitmap_platform_device_mac.h +++ b/skia/ext/bitmap_platform_device_mac.h @@ -61,7 +61,6 @@ class BitmapPlatformDeviceMac : public PlatformDeviceMac { virtual void DrawToContext(CGContextRef context, int x, int y, const CGRect* src_rect); virtual bool IsVectorial() { return false; } - virtual void fixupAlphaBeforeCompositing() { }; // Returns the color value at the specified location. This does not // consider any transforms that may be set on the device. diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index 1b5c2eb..5702b55 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc @@ -11,33 +11,6 @@ namespace skia { -// When Windows draws text, is sets the fourth byte (which Skia uses for alpha) -// to zero. This means that if we try compositing with text that Windows has -// drawn, we get invalid color values (if the alpha is 0, the other channels -// should be 0 since Skia uses premultiplied colors) and strange results. -// -// HTML rendering only requires one bit of transparency. When you ask for a -// semitransparent div, the div itself is drawn in another layer as completely -// opaque, and then composited onto the lower layer with a transfer function. -// The only place an alpha channel is needed is to track what has been drawn -// and what has not been drawn. -// -// Therefore, when we allocate a new device, we fill it with this special -// color. Because Skia uses premultiplied colors, any color where the alpha -// channel is smaller than any component is impossible, so we know that no -// legitimate drawing will produce this color. We use 1 as the alpha value -// because 0 is produced when Windows draws text (even though it should be -// opaque). -// -// When a layer is done and we want to render it to a lower layer, we use -// fixupAlphaBeforeCompositing. This replaces all 0 alpha channels with -// opaque (to fix the text problem), and replaces this magic color value -// with transparency. The result is something that can be correctly -// composited. However, once this has been done, no more can be drawn to -// the layer because fixing the alphas *again* will result in incorrect -// values. -static const uint32_t kMagicTransparencyColor = 0x01FFFEFD; - namespace { // Constrains position and size to fit within available_size. If |size| is -1, @@ -67,36 +40,6 @@ bool Constrain(int available_size, int* position, int *size) { return true; } -// If the pixel value is 0, it gets set to kMagicTransparencyColor. -void PrepareAlphaForGDI(uint32_t* pixel) { - if (*pixel == 0) { - *pixel = kMagicTransparencyColor; - } -} - -// If the pixel value is kMagicTransparencyColor, it gets set to 0. Otherwise -// if the alpha is 0, the alpha is set to 255. -void PostProcessAlphaForGDI(uint32_t* pixel) { - if (*pixel == kMagicTransparencyColor) { - *pixel = 0; - } else if ((*pixel & 0xFF000000) == 0) { - *pixel |= 0xFF000000; - } -} - -// Sets the opacity of the specified value to 0xFF. -void MakeOpaqueAlphaAdjuster(uint32_t* pixel) { - *pixel |= 0xFF000000; -} - -// See the declaration of kMagicTransparencyColor at the top of the file. -void FixupAlphaBeforeCompositing(uint32_t* pixel) { - if (*pixel == kMagicTransparencyColor) - *pixel = 0; - else - *pixel |= 0xFF000000; -} - } // namespace class BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData : public SkRefCnt { @@ -280,10 +223,7 @@ BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create( bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green #endif } else { - // A transparent layer is requested: fill with our magic "transparent" - // color, see the declaration of kMagicTransparencyColor above - sk_memset32(static_cast<uint32_t*>(data), kMagicTransparencyColor, - width * height); + bitmap.eraseARGB(0, 0, 0, 0); } // The device object will take ownership of the HBITMAP. The initial refcount @@ -387,56 +327,14 @@ void BitmapPlatformDeviceWin::drawToHDC(HDC dc, int x, int y, data_->ReleaseBitmapDC(); } -void BitmapPlatformDeviceWin::prepareForGDI(int x, int y, int width, - int height) { - processPixels<PrepareAlphaForGDI>(x, y, width, height); -} - -void BitmapPlatformDeviceWin::postProcessGDI(int x, int y, int width, - int height) { - processPixels<PostProcessAlphaForGDI>(x, y, width, height); -} - void BitmapPlatformDeviceWin::makeOpaque(int x, int y, int width, int height) { - processPixels<MakeOpaqueAlphaAdjuster>(x, y, width, height); -} - -void BitmapPlatformDeviceWin::fixupAlphaBeforeCompositing() { - const SkBitmap& bitmap = accessBitmap(true); - SkAutoLockPixels lock(bitmap); - uint32_t* data = bitmap.getAddr32(0, 0); - - size_t words = bitmap.rowBytes() / sizeof(uint32_t) * bitmap.height(); - for (size_t i = 0; i < words; i++) { - if (data[i] == kMagicTransparencyColor) - data[i] = 0; - else - data[i] |= 0xFF000000; - } -} - -// Returns the color value at the specified location. -SkColor BitmapPlatformDeviceWin::getColorAt(int x, int y) { - const SkBitmap& bitmap = accessBitmap(false); - SkAutoLockPixels lock(bitmap); - uint32_t* data = bitmap.getAddr32(0, 0); - return static_cast<SkColor>(data[x + y * width()]); -} - -void BitmapPlatformDeviceWin::onAccessBitmap(SkBitmap* bitmap) { - // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI - // operation has occurred on our DC. - if (data_->IsBitmapDCCreated()) - GdiFlush(); -} - -template<BitmapPlatformDeviceWin::adjustAlpha adjustor> -void BitmapPlatformDeviceWin::processPixels(int x, - int y, - int width, - int height) { const SkBitmap& bitmap = accessBitmap(true); SkASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); + + // FIXME(brettw): This is kind of lame, we shouldn't be dealing with + // transforms at this level. Probably there should be a PlatformCanvas + // function that does the transform (using the actual transform not just the + // translation) and calls us with the transformed rect. const SkMatrix& matrix = data_->transform(); int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; @@ -450,13 +348,27 @@ void BitmapPlatformDeviceWin::processPixels(int x, uint32_t* data = bitmap.getAddr32(0, 0) + (bitmap_start_y * row_words) + bitmap_start_x; for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - adjustor(data + j); - } + for (int j = 0; j < width; j++) + data[j] |= (0xFF << SK_A32_SHIFT); data += row_words; } } } +// Returns the color value at the specified location. +SkColor BitmapPlatformDeviceWin::getColorAt(int x, int y) { + const SkBitmap& bitmap = accessBitmap(false); + SkAutoLockPixels lock(bitmap); + uint32_t* data = bitmap.getAddr32(0, 0); + return static_cast<SkColor>(data[x + y * width()]); +} + +void BitmapPlatformDeviceWin::onAccessBitmap(SkBitmap* bitmap) { + // FIXME(brettw) OPTIMIZATION: We should only flush if we know a GDI + // operation has occurred on our DC. + if (data_->IsBitmapDCCreated()) + GdiFlush(); +} + } // namespace skia diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h index f6e456d..428441d 100644 --- a/skia/ext/bitmap_platform_device_win.h +++ b/skia/ext/bitmap_platform_device_win.h @@ -61,10 +61,7 @@ class BitmapPlatformDeviceWin : public PlatformDeviceWin { virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region); virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect); - virtual void prepareForGDI(int x, int y, int width, int height); - virtual void postProcessGDI(int x, int y, int width, int height); virtual void makeOpaque(int x, int y, int width, int height); - virtual void fixupAlphaBeforeCompositing(); virtual bool IsVectorial() { return false; } // Returns the color value at the specified location. This does not @@ -78,10 +75,6 @@ class BitmapPlatformDeviceWin : public PlatformDeviceWin { virtual void onAccessBitmap(SkBitmap* bitmap); private: - // Function pointer used by the processPixels method for setting the alpha - // value of a particular pixel. - typedef void (*adjustAlpha)(uint32_t* pixel); - // Reference counted data that can be shared between multiple devices. This // allows copy constructors and operator= for devices to work properly. The // bitmaps used by the base device class are already refcounted and copyable. @@ -91,15 +84,6 @@ class BitmapPlatformDeviceWin : public PlatformDeviceWin { BitmapPlatformDeviceWin(BitmapPlatformDeviceWinData* data, const SkBitmap& bitmap); - // Loops through each of the pixels in the specified range, invoking - // adjustor for the alpha value of each pixel. If |width| or |height| are -1, - // the available width/height is used. - template<adjustAlpha adjustor> - void processPixels(int x, - int y, - int width, - int height); - // Data associated with this device, guaranteed non-null. We hold a reference // to this object. BitmapPlatformDeviceWinData* data_; diff --git a/skia/ext/platform_canvas_unittest.cc b/skia/ext/platform_canvas_unittest.cc index e1f1eee..426591b 100644 --- a/skia/ext/platform_canvas_unittest.cc +++ b/skia/ext/platform_canvas_unittest.cc @@ -116,9 +116,6 @@ class LayerSaver { } ~LayerSaver() { -#if defined(OS_WIN) - canvas_.getTopPlatformDevice().fixupAlphaBeforeCompositing(); -#endif canvas_.restore(); } @@ -177,9 +174,6 @@ TEST(PlatformCanvas, ClipRegion) { // with a black rectangle. // Note: Don't use LayerSaver, since internally it sets a clip region. DrawNativeRect(canvas, 0, 0, 16, 16); -#if defined(OS_WIN) - canvas.getTopPlatformDevice().fixupAlphaBeforeCompositing(); -#endif EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorBLACK)); // Test that intersecting disjoint clip rectangles sets an empty clip region diff --git a/skia/ext/platform_device_mac.cc b/skia/ext/platform_device_mac.cc index 6722105..0b09b9e 100755 --- a/skia/ext/platform_device_mac.cc +++ b/skia/ext/platform_device_mac.cc @@ -33,21 +33,12 @@ bool constrain(int available_size, int* position, int *size) { return false; } -// Sets the opacity of the specified value to 0xFF. -void makeOpaqueAlphaAdjuster(uint32_t* pixel) { - *pixel |= 0xFF000000; -} - } // namespace PlatformDeviceMac::PlatformDeviceMac(const SkBitmap& bitmap) : SkDevice(bitmap) { } -void PlatformDeviceMac::makeOpaque(int x, int y, int width, int height) { - processPixels(x, y, width, height, makeOpaqueAlphaAdjuster); -} - // Set up the CGContextRef for peaceful coexistence with Skia void PlatformDeviceMac::InitializeCGContext(CGContextRef context) { // CG defaults to the same settings as Skia diff --git a/skia/ext/platform_device_mac.h b/skia/ext/platform_device_mac.h index dbfed5c..b2136af 100755 --- a/skia/ext/platform_device_mac.h +++ b/skia/ext/platform_device_mac.h @@ -35,18 +35,9 @@ class PlatformDeviceMac : public SkDevice { virtual void DrawToContext(CGContextRef context, int x, int y, const CGRect* src_rect) = 0; - // Sets the opacity of each pixel in the specified region to be opaque. - void makeOpaque(int x, int y, int width, int height); - // Returns if the preferred rendering engine is vectorial or bitmap based. virtual bool IsVectorial() = 0; - // On platforms where the native rendering API does not support rendering - // into bitmaps with a premultiplied alpha channel, this call is responsible - // for doing any fixup necessary. It is not used on the Mac, since - // CoreGraphics can handle premultiplied alpha just fine. - virtual void fixupAlphaBeforeCompositing() = 0; - // Initializes the default settings and colors in a device context. static void InitializeCGContext(CGContextRef context); diff --git a/skia/ext/platform_device_win.h b/skia/ext/platform_device_win.h index 506bd6a..75319bb 100644 --- a/skia/ext/platform_device_win.h +++ b/skia/ext/platform_device_win.h @@ -36,29 +36,9 @@ class PlatformDeviceWin : public SkDevice { // source device will be copied. virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect) = 0; - // Invoke before using GDI functions. See description in platform_device.cc - // for specifics. - // NOTE: x,y,width and height are relative to the current transform. - virtual void prepareForGDI(int x, int y, int width, int height) { } - - // Invoke after using GDI functions. See description in platform_device.cc - // for specifics. - // NOTE: x,y,width and height are relative to the current transform. - virtual void postProcessGDI(int x, int y, int width, int height) { } - // Sets the opacity of each pixel in the specified region to be opaque. virtual void makeOpaque(int x, int y, int width, int height) { } - // Call this function to fix the alpha channels before compositing this layer - // onto another. Internally, the device uses a special alpha method to work - // around problems with Windows. This call will put the values into what - // Skia expects, so it can be composited onto other layers. - // - // After this call, no more drawing can be done because the - // alpha channels will be "correct", which, if this function is called again - // will make them wrong. See the implementation for more discussion. - virtual void fixupAlphaBeforeCompositing() { } - // Returns if the preferred rendering engine is vectorial or bitmap based. virtual bool IsVectorial() = 0; |