| Index: base/gfx/bitmap_platform_device_mac.cc
|
| ===================================================================
|
| --- base/gfx/bitmap_platform_device_mac.cc (revision 5678)
|
| +++ base/gfx/bitmap_platform_device_mac.cc (working copy)
|
| @@ -1,289 +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 <time.h>
|
| -
|
| -#include "SkMatrix.h"
|
| -#include "SkRegion.h"
|
| -#include "SkUtils.h"
|
| -
|
| -#include "base/gfx/bitmap_platform_device_mac.h"
|
| -#include "base/gfx/skia_utils_mac.h"
|
| -#include "base/logging.h"
|
| -
|
| -namespace gfx {
|
| -
|
| -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;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -class BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData
|
| - : public base::RefCounted<BitmapPlatformDeviceMacData> {
|
| - public:
|
| - explicit BitmapPlatformDeviceMacData(CGContextRef bitmap);
|
| -
|
| - // Create/destroy CoreGraphics context for our bitmap data.
|
| - CGContextRef GetBitmapContext() {
|
| - LoadConfig();
|
| - return bitmap_context_;
|
| - }
|
| -
|
| - void ReleaseBitmapContext() {
|
| - DCHECK(bitmap_context_);
|
| - CGContextRelease(bitmap_context_);
|
| - bitmap_context_ = NULL;
|
| - }
|
| -
|
| - // Sets the transform and clip operations. This will not update the CGContext,
|
| - // 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);
|
| -
|
| - // Loads the current transform and clip into the DC. Can be called even when
|
| - // |bitmap_context_| is NULL (will be a NOP).
|
| - void LoadConfig();
|
| -
|
| - // Lazily-created graphics context used to draw into the bitmap.
|
| - CGContextRef bitmap_context_;
|
| -
|
| - // True when there is a transform or clip that has not been set to the
|
| - // CGContext. The CGContext 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 CGContext: we need to keep track of this
|
| - // separately so it can be updated even if the CGContext isn't created yet.
|
| - SkMatrix transform_;
|
| -
|
| - // The current clipping
|
| - SkRegion clip_region_;
|
| -
|
| - private:
|
| - friend class base::RefCounted<BitmapPlatformDeviceMacData>;
|
| - ~BitmapPlatformDeviceMacData() {
|
| - if (bitmap_context_)
|
| - CGContextRelease(bitmap_context_);
|
| - }
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDeviceMacData);
|
| -};
|
| -
|
| -BitmapPlatformDeviceMac::\
|
| - BitmapPlatformDeviceMacData::BitmapPlatformDeviceMacData(
|
| - CGContextRef bitmap)
|
| - : bitmap_context_(bitmap),
|
| - config_dirty_(true) { // Want to load the config next time.
|
| - DCHECK(bitmap_context_);
|
| - // Initialize the clip region to the entire bitmap.
|
| -
|
| - SkIRect rect;
|
| - rect.set(0, 0,
|
| - CGBitmapContextGetWidth(bitmap_context_),
|
| - CGBitmapContextGetHeight(bitmap_context_));
|
| - clip_region_ = SkRegion(rect);
|
| - transform_.reset();
|
| - CGContextRetain(bitmap_context_);
|
| -}
|
| -
|
| -void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::SetMatrixClip(
|
| - const SkMatrix& transform,
|
| - const SkRegion& region) {
|
| - transform_ = transform;
|
| - clip_region_ = region;
|
| - config_dirty_ = true;
|
| -}
|
| -
|
| -void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::LoadConfig() {
|
| - if (!config_dirty_ || !bitmap_context_)
|
| - return; // Nothing to do.
|
| - config_dirty_ = false;
|
| -
|
| - // Transform.
|
| - SkMatrix t(transform_);
|
| - LoadTransformToCGContext(bitmap_context_, t);
|
| - t.setTranslateX(-t.getTranslateX());
|
| - t.setTranslateY(-t.getTranslateY());
|
| - LoadClippingRegionToCGContext(bitmap_context_, 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.
|
| -BitmapPlatformDeviceMac* BitmapPlatformDeviceMac::Create(CGContextRef context,
|
| - int width,
|
| - int height,
|
| - bool is_opaque) {
|
| - void* data = malloc(height * width * 4);
|
| - if (!data) return NULL;
|
| -
|
| - SkBitmap bitmap;
|
| - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
|
| - bitmap.setPixels(data);
|
| -
|
| - // Note: The Windows implementation clears the Bitmap later on.
|
| - // This bears mentioning since removal of this line makes the
|
| - // unit tests only fail periodically (or when MallocPreScribble is set).
|
| - bitmap.eraseARGB(0, 0, 0, 0);
|
| -
|
| - 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
|
| - }
|
| -
|
| - CGColorSpaceRef color_space =
|
| - CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
| - // allocate a bitmap context with 4 components per pixel (RGBA):
|
| - CGContextRef bitmap_context =
|
| - CGBitmapContextCreate(data, width, height, 8, width*4,
|
| - color_space, kCGImageAlphaPremultipliedLast);
|
| -
|
| - // Change the coordinate system to match WebCore's
|
| - CGContextTranslateCTM(bitmap_context, 0, height);
|
| - CGContextScaleCTM(bitmap_context, 1.0, -1.0);
|
| - CGColorSpaceRelease(color_space);
|
| -
|
| - // The device object will take ownership of the graphics context.
|
| - return new BitmapPlatformDeviceMac(
|
| - new BitmapPlatformDeviceMacData(bitmap_context), bitmap);
|
| -}
|
| -
|
| -// The device will own the bitmap, which corresponds to also owning the pixel
|
| -// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
|
| -BitmapPlatformDeviceMac::BitmapPlatformDeviceMac(
|
| - BitmapPlatformDeviceMacData* data, const SkBitmap& bitmap)
|
| - : PlatformDeviceMac(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).
|
| -BitmapPlatformDeviceMac::BitmapPlatformDeviceMac(
|
| - const BitmapPlatformDeviceMac& other)
|
| - : PlatformDeviceMac(
|
| - const_cast<BitmapPlatformDeviceMac&>(other).accessBitmap(true)),
|
| - data_(other.data_) {
|
| -}
|
| -
|
| -BitmapPlatformDeviceMac::~BitmapPlatformDeviceMac() {
|
| -}
|
| -
|
| -BitmapPlatformDeviceMac& BitmapPlatformDeviceMac::operator=(
|
| - const BitmapPlatformDeviceMac& other) {
|
| - data_ = other.data_;
|
| - return *this;
|
| -}
|
| -
|
| -CGContextRef BitmapPlatformDeviceMac::GetBitmapContext() {
|
| - return data_->GetBitmapContext();
|
| -}
|
| -
|
| -void BitmapPlatformDeviceMac::setMatrixClip(const SkMatrix& transform,
|
| - const SkRegion& region) {
|
| - data_->SetMatrixClip(transform, region);
|
| -}
|
| -
|
| -void BitmapPlatformDeviceMac::DrawToContext(CGContextRef context, int x, int y,
|
| - const CGRect* src_rect) {
|
| - bool created_dc = false;
|
| - if (!data_->bitmap_context_) {
|
| - created_dc = true;
|
| - GetBitmapContext();
|
| - }
|
| -
|
| - // this should not make a copy of the bits, since we're not doing
|
| - // anything to trigger copy on write
|
| - CGImageRef image = CGBitmapContextCreateImage(data_->bitmap_context_);
|
| - CGRect bounds;
|
| - if (src_rect) {
|
| - bounds = *src_rect;
|
| - bounds.origin.x = x;
|
| - bounds.origin.y = y;
|
| - CGImageRef sub_image = CGImageCreateWithImageInRect(image, *src_rect);
|
| - CGContextDrawImage(context, bounds, sub_image);
|
| - CGImageRelease(sub_image);
|
| - } else {
|
| - bounds.origin.x = 0;
|
| - bounds.origin.y = 0;
|
| - bounds.size.width = width();
|
| - bounds.size.height = height();
|
| - CGContextDrawImage(context, bounds, image);
|
| - }
|
| - CGImageRelease(image);
|
| -
|
| - if (created_dc)
|
| - data_->ReleaseBitmapContext();
|
| -}
|
| -
|
| -// Returns the color value at the specified location.
|
| -SkColor BitmapPlatformDeviceMac::getColorAt(int x, int y) {
|
| - const SkBitmap& bitmap = accessBitmap(true);
|
| - SkAutoLockPixels lock(bitmap);
|
| - uint32_t* data = bitmap.getAddr32(0, 0);
|
| - return static_cast<SkColor>(data[x + y * width()]);
|
| -}
|
| -
|
| -void BitmapPlatformDeviceMac::onAccessBitmap(SkBitmap*) {
|
| - // Not needed in CoreGraphics
|
| -}
|
| -
|
| -void BitmapPlatformDeviceMac::processPixels(int x, int y,
|
| - int width, int height,
|
| - adjustAlpha adjustor) {
|
| - const SkBitmap& bitmap = accessBitmap(true);
|
| - SkMatrix& matrix = data_->transform_;
|
| - int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x;
|
| - int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y;
|
| -
|
| - SkAutoLockPixels lock(bitmap);
|
| - if (Constrain(bitmap.width(), &bitmap_start_x, &width) &&
|
| - Constrain(bitmap.height(), &bitmap_start_y, &height)) {
|
| - uint32_t* data = bitmap.getAddr32(0, 0);
|
| - size_t row_words = bitmap.rowBytes() / 4;
|
| - for (int i = 0; i < height; i++) {
|
| - size_t offset = (i + bitmap_start_y) * row_words + bitmap_start_x;
|
| - for (int j = 0; j < width; j++) {
|
| - adjustor(data + offset + j);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -} // namespace gfx
|
| -
|
|
|