| Index: skia/ext/bitmap_platform_device_linux.cc
|
| diff --git a/skia/ext/bitmap_platform_device_linux.cc b/skia/ext/bitmap_platform_device_linux.cc
|
| index 1b061b00d823288edaf7db25fe72a264c799731e..a74ec830561efed9f7b90c89951af485817683d8 100644
|
| --- a/skia/ext/bitmap_platform_device_linux.cc
|
| +++ b/skia/ext/bitmap_platform_device_linux.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2009 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.
|
|
|
| @@ -8,6 +8,33 @@
|
|
|
| namespace skia {
|
|
|
| +namespace {
|
| +
|
| +void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
|
| + cairo_matrix_t cairo_matrix;
|
| + cairo_matrix_init(&cairo_matrix,
|
| + SkScalarToFloat(matrix.getScaleX()),
|
| + SkScalarToFloat(matrix.getSkewY()),
|
| + SkScalarToFloat(matrix.getSkewX()),
|
| + SkScalarToFloat(matrix.getScaleY()),
|
| + SkScalarToFloat(matrix.getTranslateX()),
|
| + SkScalarToFloat(matrix.getTranslateY()));
|
| + cairo_set_matrix(context, &cairo_matrix);
|
| +}
|
| +
|
| +void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
|
| + cairo_reset_clip(context);
|
| +
|
| + // TODO(brettw) support non-rect clips.
|
| + SkIRect bounding = clip.getBounds();
|
| + cairo_rectangle(context, bounding.fLeft, bounding.fTop,
|
| + bounding.fRight - bounding.fLeft,
|
| + bounding.fBottom - bounding.fTop);
|
| + cairo_clip(context);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| // -----------------------------------------------------------------------------
|
| // These objects are reference counted and own a Cairo surface. The surface is
|
| // the backing store for a Skia bitmap and we reference count it so that we can
|
| @@ -17,18 +44,39 @@ namespace skia {
|
| class BitmapPlatformDevice::BitmapPlatformDeviceData
|
| : public base::RefCounted<BitmapPlatformDeviceData> {
|
| public:
|
| - explicit BitmapPlatformDeviceData(cairo_surface_t* surface)
|
| - : surface_(surface) { }
|
| + explicit BitmapPlatformDeviceData(cairo_surface_t* surface);
|
|
|
| - cairo_surface_t* surface() const { return surface_; }
|
| + cairo_t* GetContext();
|
| + cairo_surface_t* GetSurface();
|
| +
|
| + // Sets the transform and clip operations. This will not update the Cairo
|
| + // surface, 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);
|
|
|
| protected:
|
| + friend class base::RefCounted<BitmapPlatformDeviceData>;
|
| +
|
| + ~BitmapPlatformDeviceData();
|
| +
|
| + void LoadConfig();
|
| +
|
| + // The Cairo surface inside this DC.
|
| + cairo_t* context_;
|
| cairo_surface_t *const surface_;
|
|
|
| - friend class base::RefCounted<BitmapPlatformDeviceData>;
|
| - ~BitmapPlatformDeviceData() {
|
| - cairo_surface_destroy(surface_);
|
| - }
|
| + // True when there is a transform or clip that has not been set to the
|
| + // surface. The surface 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_;
|
|
|
| // Disallow copy & assign.
|
| BitmapPlatformDeviceData(const BitmapPlatformDeviceData&);
|
| @@ -36,6 +84,52 @@ class BitmapPlatformDevice::BitmapPlatformDeviceData
|
| const BitmapPlatformDeviceData&);
|
| };
|
|
|
| +BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
|
| + cairo_surface_t* surface)
|
| + : surface_(surface),
|
| + config_dirty_(true) { // Want to load the config next time.
|
| + context_ = cairo_create(surface);
|
| +}
|
| +
|
| +BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
|
| + cairo_destroy(context_);
|
| + cairo_surface_destroy(surface_);
|
| +}
|
| +
|
| +cairo_t* BitmapPlatformDevice::BitmapPlatformDeviceData::GetContext() {
|
| + LoadConfig();
|
| + return context_;
|
| +}
|
| +
|
| +void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
|
| + const SkMatrix& transform,
|
| + const SkRegion& region) {
|
| + transform_ = transform;
|
| + clip_region_ = region;
|
| + config_dirty_ = true;
|
| +}
|
| +
|
| +cairo_surface_t*
|
| +BitmapPlatformDevice::BitmapPlatformDeviceData::GetSurface() {
|
| + // TODO(brettw) this function should be removed.
|
| + LoadConfig();
|
| + return surface_;
|
| +}
|
| +
|
| +void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
|
| + if (!config_dirty_ || !context_)
|
| + return; // Nothing to do.
|
| + config_dirty_ = false;
|
| +
|
| + // Load the identity matrix since this is what our clip is relative to.
|
| + cairo_matrix_t cairo_matrix;
|
| + cairo_matrix_init_identity(&cairo_matrix);
|
| + cairo_set_matrix(context_, &cairo_matrix);
|
| +
|
| + LoadClipToContext(context_, clip_region_);
|
| + LoadMatrixToContext(context_, transform_);
|
| +}
|
| +
|
| // 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
|
| @@ -98,8 +192,13 @@ BitmapPlatformDevice::BitmapPlatformDevice(
|
| BitmapPlatformDevice::~BitmapPlatformDevice() {
|
| }
|
|
|
| -cairo_surface_t* BitmapPlatformDevice::surface() const {
|
| - return data_->surface();
|
| +cairo_t* BitmapPlatformDevice::beginPlatformPaint() {
|
| + return data_->GetContext();
|
| +}
|
| +
|
| +void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
|
| + const SkRegion& region) {
|
| + data_->SetMatrixClip(transform, region);
|
| }
|
|
|
| BitmapPlatformDevice& BitmapPlatformDevice::operator=(
|
|
|