summaryrefslogtreecommitdiffstats
path: root/base/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'base/gfx')
-rwxr-xr-xbase/gfx/bitmap_platform_device_mac.cc62
-rwxr-xr-xbase/gfx/bitmap_platform_device_mac.h7
-rwxr-xr-xbase/gfx/platform_canvas_mac.cc73
-rwxr-xr-xbase/gfx/platform_canvas_mac.h19
-rwxr-xr-xbase/gfx/platform_device_mac.cc67
-rwxr-xr-xbase/gfx/platform_device_mac.h12
6 files changed, 102 insertions, 138 deletions
diff --git a/base/gfx/bitmap_platform_device_mac.cc b/base/gfx/bitmap_platform_device_mac.cc
index 0bae190..40b58cf 100755
--- a/base/gfx/bitmap_platform_device_mac.cc
+++ b/base/gfx/bitmap_platform_device_mac.cc
@@ -52,6 +52,7 @@ class BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData
// Create/destroy CoreGraphics context for our bitmap data.
CGContextRef GetBitmapContext() {
+ LoadConfig();
return bitmap_context_;
}
@@ -64,8 +65,7 @@ class BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData
// 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 SetTransform(const SkMatrix& t);
- void SetClipRegion(const SkRegion& region);
+ 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).
@@ -109,19 +109,15 @@ BitmapPlatformDeviceMac::\
rect.set(0, 0,
CGBitmapContextGetWidth(bitmap_context_),
CGBitmapContextGetHeight(bitmap_context_));
- SkRegion region(rect);
- SetClipRegion(region);
+ clip_region_ = SkRegion(rect);
+ transform_.reset();
CGContextRetain(bitmap_context_);
}
-void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::SetTransform(
- const SkMatrix& t) {
- transform_ = t;
- config_dirty_ = true;
-}
-
-void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::SetClipRegion(
+void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::SetMatrixClip(
+ const SkMatrix& transform,
const SkRegion& region) {
+ transform_ = transform;
clip_region_ = region;
config_dirty_ = true;
}
@@ -134,11 +130,10 @@ void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::LoadConfig() {
// Transform.
SkMatrix t(transform_);
LoadTransformToCGContext(bitmap_context_, t);
-
- // TODO(brettw) we should support more than just rect clipping here.
- SkIRect rect = clip_region_.getBounds();
-
- CGContextClipToRect(bitmap_context_, SkIRectToCGRect(rect));
+
+ t.setTranslateX(-t.getTranslateX());
+ t.setTranslateY(-t.getTranslateY());
+ LoadClippingRegionToCGContext(bitmap_context_, clip_region_, t);
}
@@ -150,6 +145,8 @@ BitmapPlatformDeviceMac* BitmapPlatformDeviceMac::Create(CGContextRef context,
int width,
int height,
bool is_opaque) {
+ // TODO(playmobil): remove debug code.
+ //printf("BitmapPlatformDeviceMac::Create(%d,%d)\n", width, height);
// each pixel is 4 bytes (RGBA):
void* data = malloc(height * width * 4);
if (!data) return NULL;
@@ -214,12 +211,9 @@ CGContextRef BitmapPlatformDeviceMac::GetBitmapContext() {
return data_->GetBitmapContext();
}
-void BitmapPlatformDeviceMac::SetTransform(const SkMatrix& matrix) {
- data_->SetTransform(matrix);
-}
-
-void BitmapPlatformDeviceMac::SetClipRegion(const SkRegion& region) {
- data_->SetClipRegion(region);
+void BitmapPlatformDeviceMac::setMatrixClip(const SkMatrix& transform,
+ const SkRegion& region) {
+ data_->SetMatrixClip(transform, region);
}
void BitmapPlatformDeviceMac::DrawToContext(CGContextRef context, int x, int y,
@@ -253,6 +247,18 @@ void BitmapPlatformDeviceMac::DrawToContext(CGContextRef context, int x, int y,
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,
@@ -276,17 +282,5 @@ void BitmapPlatformDeviceMac::processPixels(int x, int y,
}
}
-// 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
-}
-
} // namespace gfx
diff --git a/base/gfx/bitmap_platform_device_mac.h b/base/gfx/bitmap_platform_device_mac.h
index fdbe2e4..a008444 100755
--- a/base/gfx/bitmap_platform_device_mac.h
+++ b/base/gfx/bitmap_platform_device_mac.h
@@ -56,10 +56,7 @@ class BitmapPlatformDeviceMac : public PlatformDeviceMac {
BitmapPlatformDeviceMac& operator=(const BitmapPlatformDeviceMac& other);
virtual CGContextRef GetBitmapContext();
- virtual void SetTransform(const SkMatrix& matrix);
-
- // This currently only supports extremely simple clip rects.
- virtual void SetClipRegion(const SkRegion& region);
+ virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region);
virtual void DrawToContext(CGContextRef context, int x, int y,
const CGRect* src_rect);
@@ -68,7 +65,7 @@ class BitmapPlatformDeviceMac : public PlatformDeviceMac {
// Returns the color value at the specified location. This does not
// consider any transforms that may be set on the device.
- SkColor GetColorAt(int x, int y);
+ SkColor getColorAt(int x, int y);
protected:
// Reference counted data that can be shared between multiple devices. This
diff --git a/base/gfx/platform_canvas_mac.cc b/base/gfx/platform_canvas_mac.cc
index ef06e0e..102655c 100755
--- a/base/gfx/platform_canvas_mac.cc
+++ b/base/gfx/platform_canvas_mac.cc
@@ -52,81 +52,10 @@ PlatformDeviceMac& PlatformCanvasMac::getTopPlatformDevice() const {
return *static_cast<PlatformDeviceMac*>(iter.device());
}
-// Clipping -------------------------------------------------------------------
-
-bool PlatformCanvasMac::clipRect(const SkRect& rect, SkRegion::Op op) {
- bool ret = SkCanvas::clipRect(rect, op);
- getTopPlatformDevice().SetClipRegion(getTotalClip());
- return ret;
-}
-
-bool PlatformCanvasMac::clipPath(const SkPath& path, SkRegion::Op op) {
- bool ret = SkCanvas::clipPath(path, op);
- getTopPlatformDevice().SetClipRegion(getTotalClip());
- return ret;
-}
-
-bool PlatformCanvasMac::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
- bool ret = SkCanvas::clipRegion(deviceRgn, op);
- getTopPlatformDevice().SetClipRegion(getTotalClip());
- return ret;
-}
-
-// Transforming ---------------------------------------------------------------
-
-bool PlatformCanvasMac::translate(SkScalar dx, SkScalar dy) {
- if (!SkCanvas::translate(dx, dy))
- return false;
- getTopPlatformDevice().SetTransform(getTotalMatrix());
- return true;
-}
-
-bool PlatformCanvasMac::scale(SkScalar sx, SkScalar sy) {
- if (!SkCanvas::scale(sx, sy))
- return false;
- getTopPlatformDevice().SetTransform(getTotalMatrix());
- return true;
-}
-
-int PlatformCanvasMac::saveLayer(const SkRect* bounds,
- const SkPaint* paint,
- SaveFlags flags) {
- int result = SkCanvas::saveLayer(bounds, paint, flags);
-
- // saveLayer will have created a new device which, depending on the clip
- // rect, may be smaller than the original layer. Therefore, it will have a
- // transform applied, and we need to sync CG with that transform.
- SkCanvas::LayerIter iter(this, false);
- PlatformDeviceMac& new_device =
- *static_cast<PlatformDeviceMac*>(iter.device());
-
- // There man not actually be a new layer if the layer is empty.
- if (!iter.done()) {
- new_device.SetTransform(getTotalMatrix());
- new_device.SetClipRegion(getTotalClip());
- }
- return result;
-}
-
-int PlatformCanvasMac::save(SkCanvas::SaveFlags flags) {
- int ret = SkCanvas::save(flags);
- PlatformDeviceMac& device = getTopPlatformDevice();
- device.SetTransform(getTotalMatrix());
- device.SetClipRegion(getTotalClip());
- return ret;
-}
-
-void PlatformCanvasMac::restore() {
- SkCanvas::restore();
- PlatformDeviceMac& device = getTopPlatformDevice();
- device.SetTransform(getTotalMatrix());
- device.SetClipRegion(getTotalClip());
-}
-
SkDevice* PlatformCanvasMac::createDevice(SkBitmap::Config config,
int width,
int height,
- bool is_opaque) {
+ bool is_opaque, bool isForLayer) {
DCHECK(config == SkBitmap::kARGB_8888_Config);
return createPlatformDevice(width, height, is_opaque, NULL);
}
diff --git a/base/gfx/platform_canvas_mac.h b/base/gfx/platform_canvas_mac.h
index 3cf2d5a..562b1a0 100755
--- a/base/gfx/platform_canvas_mac.h
+++ b/base/gfx/platform_canvas_mac.h
@@ -30,15 +30,6 @@ class PlatformCanvasMac : public SkCanvas {
// For two-part init, call if you use the no-argument constructor above
void initialize(int width, int height, bool is_opaque, CGContextRef context);
- // Keep the platform clipping in sync with the skia clipping. Note that
- // platform clipping may only clip to the bounds of the clipping region, if
- // it is complex.
- virtual bool clipRect(const SkRect& rect,
- SkRegion::Op op = SkRegion::kIntersect_Op);
- virtual bool clipPath(const SkPath& path,
- SkRegion::Op op = SkRegion::kIntersect_Op);
- virtual bool clipRegion(const SkRegion& deviceRgn,
- SkRegion::Op op = SkRegion::kIntersect_Op);
// These calls should surround calls to platform drawing routines. The CG
// context returned by beginPlatformPaint is the one that can be used to
@@ -48,14 +39,6 @@ class PlatformCanvasMac : public SkCanvas {
virtual CGContextRef beginPlatformPaint();
virtual void endPlatformPaint();
- // overridden to keep the platform graphics context in sync with the canvas
- virtual bool translate(SkScalar dx, SkScalar dy);
- virtual bool scale(SkScalar sx, SkScalar sy);
- virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
- SaveFlags flags = kARGB_ClipLayer_SaveFlag);
- virtual int save(SkCanvas::SaveFlags flags = SkCanvas::kMatrixClip_SaveFlag);
- virtual void restore();
-
// Returns the platform device pointer of the topmost rect with a non-empty
// clip. In practice, this is usually either the top layer or nothing, since
// we usually set the clip to new layers when we make them.
@@ -80,7 +63,7 @@ class PlatformCanvasMac : public SkCanvas {
// the device is always our own so we know that we can use GDI operations
// on it. Simply calls into createPlatformDevice().
virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
- bool is_opaque);
+ bool is_opaque, bool isForLayer);
// Creates a device store for use by the canvas. By default, it creates a
// BitmapPlatformDevice object. Can be overridden to change the object type.
diff --git a/base/gfx/platform_device_mac.cc b/base/gfx/platform_device_mac.cc
index 9185dae..ab0b188 100755
--- a/base/gfx/platform_device_mac.cc
+++ b/base/gfx/platform_device_mac.cc
@@ -97,10 +97,73 @@ void PlatformDeviceMac::LoadPathToCGContext(CGContextRef context,
// static
void PlatformDeviceMac::LoadTransformToCGContext(CGContextRef context,
const SkMatrix& matrix) {
- // TOOD: CoreGraphics can concatenate transforms, but not reset the current
- // ont. Either find a workaround or remove this function if it turns out
+ // TODO: CoreGraphics can concatenate transforms, but not reset the current
+ // one. Either find a workaround or remove this function if it turns out
// to be unneeded on the Mac.
+ // For now, just load the translation.
+
+ // First reset the Transforms.
+ // TODO(playmobil): no need to call CGContextTranslateCTM() twice
+ // just add up the numbers and call through.
+ CGAffineTransform orig_transform = CGContextGetCTM(context);
+ CGContextTranslateCTM(context,
+ -orig_transform.tx,
+ orig_transform.ty); // y axis is flipped.
+
+ // TODO(playmobil): remove debug code.
+ // CGAffineTransform temp_transform = CGContextGetCTM(context);
+
+ // Now set the new transform.
+ int tx = matrix.getTranslateX();
+ int ty = -matrix.getTranslateY();
+ int height = CGBitmapContextGetHeight(context);
+ CGContextTranslateCTM(context,
+ tx,
+ -(ty+height));
+ CGAffineTransform new_transform = CGContextGetCTM(context);
+// TODO(playmobil): remove debug code.
+// printf("tx_matrix (%lf,%lf)->(%lf,%lf)->(%lf,%lf) (%d, %d) height=%d\n", orig_transform.tx,
+// orig_transform.ty,
+// foo_transform.tx,
+// foo_transform.ty,
+// new_transform.tx,
+// new_transform.ty, tx, ty, height);
}
+// static
+void PlatformDeviceMac::LoadClippingRegionToCGContext(
+ CGContextRef context,
+ const SkRegion& region,
+ const SkMatrix& transformation) {
+ if (region.isEmpty()) {
+ // region can be empty, in which case everything will be clipped.
+ SkRect rect;
+ rect.setEmpty();
+ CGContextClipToRect(context, SkRectToCGRect(rect));
+ } else if (region.isRect()) {
+ // Do the transformation.
+ SkRect rect;
+ rect.set(region.getBounds());
+ transformation.mapRect(&rect);
+ SkIRect irect;
+ rect.round(&irect);
+// TODO(playmobil): remove debug code.
+// printf("Clipping to (%d,%d) (%d,%d)\n", irect.fLeft, irect.fTop,
+// irect.fRight, irect.fBottom);
+ CGContextClipToRect(context, SkIRectToCGRect(irect));
+ } else {
+ // It is complex.
+ SkPath path;
+ region.getBoundaryPath(&path);
+ // Clip. Note that windows clipping regions are not affected by the
+ // transform so apply it manually.
+ path.transform(transformation);
+ // TODO(playmobil): Implement.
+ NOTREACHED();
+ // LoadPathToDC(context, path);
+ // hrgn = PathToRegion(context);
+ }
+}
+
} // namespace gfx
diff --git a/base/gfx/platform_device_mac.h b/base/gfx/platform_device_mac.h
index 590cd24..79a14be 100755
--- a/base/gfx/platform_device_mac.h
+++ b/base/gfx/platform_device_mac.h
@@ -27,13 +27,6 @@ class PlatformDeviceMac : public SkDevice {
// should exist only during one pass of rendering.
virtual CGContextRef GetBitmapContext() = 0;
- // Translate the device's coordinate system by the given amount; this will
- // override any previous calls to this function.
- virtual void SetTransform(const SkMatrix& matrix) = 0;
-
- // Sets the clipping region, overriding any previous calls.
- virtual void SetClipRegion(const SkRegion& region) = 0;
-
// Draws to the given graphics context. If the bitmap context doesn't exist,
// this will temporarily create it. However, if you have created the bitmap
// context, it will be more efficient if you don't free it until after this
@@ -61,6 +54,11 @@ class PlatformDeviceMac : public SkDevice {
// clipping or as a stroke.
static void LoadPathToCGContext(CGContextRef context, const SkPath& path);
+ // Loads a SkRegion into the CG context.
+ static void LoadClippingRegionToCGContext(CGContextRef context,
+ const SkRegion& region,
+ const SkMatrix& transformation);
+
protected:
// Forwards |bitmap| to SkDevice's constructor.
PlatformDeviceMac(const SkBitmap& bitmap);