summaryrefslogtreecommitdiffstats
path: root/skia/ext
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-27 22:15:19 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-27 22:15:19 +0000
commit54910b7969906431a43c7a17bd1ee580f8eeb9fa (patch)
treefd12d10eb9b2a8d48311e82e585d113d56a730b1 /skia/ext
parentd5fbc00d5d55132f03f229f3dba001fc62ee6795 (diff)
downloadchromium_src-54910b7969906431a43c7a17bd1ee580f8eeb9fa.zip
chromium_src-54910b7969906431a43c7a17bd1ee580f8eeb9fa.tar.gz
chromium_src-54910b7969906431a43c7a17bd1ee580f8eeb9fa.tar.bz2
Pull WebKit deps to get transparency fixes, and rebaseline affected layout tests.
Add a helper class to manage Windows' transparency issues. It will create layers and manage transforms in such a way that most effects can be achieved with fonts and form controls on Windows while looking nice. This removes the magic transparency color and associated infrastructure since it is no longer needed. This fixes semitransparent ClearType antialiasing and pngs with alpha channels with opacity applied. BUG=559,2791,3229,6372 Review URL: http://codereview.chromium.org/21201 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10637 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/ext')
-rwxr-xr-xskia/ext/bitmap_platform_device_mac.h1
-rw-r--r--skia/ext/bitmap_platform_device_win.cc134
-rw-r--r--skia/ext/bitmap_platform_device_win.h16
-rw-r--r--skia/ext/platform_canvas_unittest.cc6
-rwxr-xr-xskia/ext/platform_device_mac.cc9
-rwxr-xr-xskia/ext/platform_device_mac.h9
-rw-r--r--skia/ext/platform_device_win.h20
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;