Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1310)

Unified Diff: webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceWin.cpp

Issue 11568: Move skia extensions from the port to skia/ext. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceWin.cpp
===================================================================
--- webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceWin.cpp (revision 5845)
+++ webkit/port/platform/graphics/skia/public/BitmapPlatformDeviceWin.cpp (working copy)
@@ -1,446 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "BitmapPlatformDeviceWin.h"
-
-#include "base/gfx/gdi_util.h"
-#include "base/logging.h"
-#include "SkMatrix.h"
-#include "SkRegion.h"
-#include "SkUtils.h"
-
-namespace gfx {
-
-// 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,
-// all the available_size is used. Returns false if the position is out of
-// available_size.
-bool Constrain(int available_size, int* position, int *size) {
- if (*size < -2)
- return false;
-
- if (*position < 0) {
- if (*size != -1)
- *size += *position;
- *position = 0;
- }
- if (*size == 0 || *position >= available_size)
- return false;
-
- if (*size > 0) {
- int overflow = (*position + *size) - available_size;
- if (overflow > 0) {
- *size -= overflow;
- }
- } else {
- // Fill up available size.
- *size = available_size - *position;
- }
- 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 base::RefCounted<BitmapPlatformDeviceWinData> {
- public:
- explicit BitmapPlatformDeviceWinData(HBITMAP hbitmap);
-
- // Create/destroy hdc_, which is the memory DC for our bitmap data.
- HDC GetBitmapDC();
- void ReleaseBitmapDC();
- bool IsBitmapDCCreated() const;
-
- // Sets the transform and clip operations. This will not update the DC,
- // but will mark the config as dirty. The next call of LoadConfig will
- // pick up these changes.
- void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
-
- const SkMatrix& transform() const {
- return transform_;
- }
-
- protected:
- // Loads the current transform and clip into the DC. Can be called even when
- // the DC is NULL (will be a NOP).
- void LoadConfig();
-
- // Windows bitmap corresponding to our surface.
- HBITMAP hbitmap_;
-
- // Lazily-created DC used to draw into the bitmap, see getBitmapDC.
- HDC hdc_;
-
- // True when there is a transform or clip that has not been set to the DC.
- // The DC is retrieved for every text operation, and the transform and clip
- // do not change as much. We can save time by not loading the clip and
- // transform for every one.
- bool config_dirty_;
-
- // Translation assigned to the DC: we need to keep track of this separately
- // so it can be updated even if the DC isn't created yet.
- SkMatrix transform_;
-
- // The current clipping
- SkRegion clip_region_;
-
- private:
- friend class base::RefCounted<BitmapPlatformDeviceWinData>;
- ~BitmapPlatformDeviceWinData();
-
- DISALLOW_EVIL_CONSTRUCTORS(BitmapPlatformDeviceWinData);
-};
-
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::BitmapPlatformDeviceWinData(
- HBITMAP hbitmap)
- : hbitmap_(hbitmap),
- hdc_(NULL),
- config_dirty_(true) { // Want to load the config next time.
- // Initialize the clip region to the entire bitmap.
- BITMAP bitmap_data;
- if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) {
- SkIRect rect;
- rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
- clip_region_ = SkRegion(rect);
- }
-
- transform_.reset();
-}
-
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::~BitmapPlatformDeviceWinData() {
- if (hdc_)
- ReleaseBitmapDC();
-
- // this will free the bitmap data as well as the bitmap handle
- DeleteObject(hbitmap_);
-}
-
-HDC BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::GetBitmapDC() {
- if (!hdc_) {
- hdc_ = CreateCompatibleDC(NULL);
- InitializeDC(hdc_);
- HGDIOBJ old_bitmap = SelectObject(hdc_, hbitmap_);
- // When the memory DC is created, its display surface is exactly one
- // monochrome pixel wide and one monochrome pixel high. Since we select our
- // own bitmap, we must delete the previous one.
- DeleteObject(old_bitmap);
- }
-
- LoadConfig();
- return hdc_;
-}
-
-void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::ReleaseBitmapDC() {
- DCHECK(hdc_);
- DeleteDC(hdc_);
- hdc_ = NULL;
-}
-
-bool BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::IsBitmapDCCreated()
- const {
- return hdc_ != NULL;
-}
-
-
-void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::SetMatrixClip(
- const SkMatrix& transform,
- const SkRegion& region) {
- transform_ = transform;
- clip_region_ = region;
- config_dirty_ = true;
-}
-
-void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::LoadConfig() {
- if (!config_dirty_ || !hdc_)
- return; // Nothing to do.
- config_dirty_ = false;
-
- // Transform.
- SkMatrix t(transform_);
- LoadTransformToDC(hdc_, t);
- // We don't use transform_ for the clipping region since the translation is
- // already applied to offset_x_ and offset_y_.
- t.reset();
- LoadClippingRegionToDC(hdc_, clip_region_, t);
-}
-
-// We use this static factory function instead of the regular constructor so
-// that we can create the pixel data before calling the constructor. This is
-// required so that we can call the base class' constructor with the pixel
-// data.
-BitmapPlatformDeviceWin* BitmapPlatformDeviceWin::create(HDC screen_dc,
- int width,
- int height,
- bool is_opaque,
- HANDLE shared_section) {
- SkBitmap bitmap;
-
- // CreateDIBSection appears to get unhappy if we create an empty bitmap, so
- // just create a minimal bitmap
- if ((width == 0) || (height == 0)) {
- width = 1;
- height = 1;
- }
-
- BITMAPINFOHEADER hdr = {0};
- CreateBitmapHeader(width, height, &hdr);
-
- void* data = NULL;
- HBITMAP hbitmap = CreateDIBSection(screen_dc,
- reinterpret_cast<BITMAPINFO*>(&hdr), 0,
- &data,
- shared_section, 0);
-
- // If we run out of GDI objects or some other error occurs, we won't get a
- // bitmap here. This will cause us to crash later because the data pointer is
- // NULL. To make sure that we can assign blame for those crashes to this code,
- // we deliberately crash here, even in release mode.
- if (!hbitmap) {
- DWORD error = GetLastError();
- LOG(ERROR) << "CreateDIBSection Failed. Error: " << error << "\n";
- return NULL;
- }
-
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
- bitmap.setPixels(data);
- bitmap.setIsOpaque(is_opaque);
-
- if (is_opaque) {
-#ifndef NDEBUG
- // To aid in finding bugs, we set the background color to something
- // obviously wrong so it will be noticable when it is not cleared
- 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);
- }
-
- // The device object will take ownership of the HBITMAP.
- return new BitmapPlatformDeviceWin(new BitmapPlatformDeviceWinData(hbitmap),
- bitmap);
-}
-
-// The device will own the HBITMAP, which corresponds to also owning the pixel
-// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWin(
- BitmapPlatformDeviceWinData* data,
- const SkBitmap& bitmap) : PlatformDeviceWin(bitmap), data_(data) {
-}
-
-// The copy constructor just adds another reference to the underlying data.
-// We use a const cast since the default Skia definitions don't define the
-// proper constedness that we expect (accessBitmap should really be const).
-BitmapPlatformDeviceWin::BitmapPlatformDeviceWin(
- const BitmapPlatformDeviceWin& other)
- : PlatformDeviceWin(
- const_cast<BitmapPlatformDeviceWin&>(other).accessBitmap(true)),
- data_(other.data_) {
-}
-
-BitmapPlatformDeviceWin::~BitmapPlatformDeviceWin() {
-}
-
-BitmapPlatformDeviceWin& BitmapPlatformDeviceWin::operator=(
- const BitmapPlatformDeviceWin& other) {
- data_ = other.data_;
- return *this;
-}
-
-HDC BitmapPlatformDeviceWin::getBitmapDC() {
- return data_->GetBitmapDC();
-}
-
-void BitmapPlatformDeviceWin::setMatrixClip(const SkMatrix& transform,
- const SkRegion& region) {
- data_->SetMatrixClip(transform, region);
-}
-
-void BitmapPlatformDeviceWin::drawToHDC(HDC dc, int x, int y,
- const RECT* src_rect) {
- bool created_dc = !data_->IsBitmapDCCreated();
- HDC source_dc = getBitmapDC();
-
- RECT temp_rect;
- if (!src_rect) {
- temp_rect.left = 0;
- temp_rect.right = width();
- temp_rect.top = 0;
- temp_rect.bottom = height();
- src_rect = &temp_rect;
- }
-
- int copy_width = src_rect->right - src_rect->left;
- int copy_height = src_rect->bottom - src_rect->top;
-
- // We need to reset the translation for our bitmap or (0,0) won't be in the
- // upper left anymore
- SkMatrix identity;
- identity.reset();
-
- LoadTransformToDC(source_dc, identity);
- if (isOpaque()) {
- BitBlt(dc,
- x,
- y,
- copy_width,
- copy_height,
- source_dc,
- src_rect->left,
- src_rect->top,
- SRCCOPY);
- } else {
- DCHECK(copy_width != 0 && copy_height != 0);
- BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
- GdiAlphaBlend(dc,
- x,
- y,
- copy_width,
- copy_height,
- source_dc,
- src_rect->left,
- src_rect->top,
- copy_width,
- copy_height,
- blend_function);
- }
- LoadTransformToDC(source_dc, data_->transform());
-
- if (created_dc)
- 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);
- DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
- const SkMatrix& matrix = data_->transform();
- int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x;
- int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y;
-
- if (Constrain(bitmap.width(), &bitmap_start_x, &width) &&
- Constrain(bitmap.height(), &bitmap_start_y, &height)) {
- SkAutoLockPixels lock(bitmap);
- DCHECK_EQ(bitmap.rowBytes() % sizeof(uint32_t), 0u);
- size_t row_words = bitmap.rowBytes() / sizeof(uint32_t);
- // Set data to the first pixel to be modified.
- 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);
- }
- data += row_words;
- }
- }
-}
-
-} // namespace gfx
-

Powered by Google App Engine
This is Rietveld 408576698