OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "skia/ext/bitmap_platform_device_mac.h" | 5 #include "skia/ext/bitmap_platform_device_mac.h" |
6 | 6 |
7 #import <ApplicationServices/ApplicationServices.h> | 7 #import <ApplicationServices/ApplicationServices.h> |
8 #include <time.h> | 8 #include <time.h> |
9 | 9 |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
(...skipping 53 matching lines...) Loading... |
64 } | 64 } |
65 | 65 |
66 void BitmapPlatformDevice::SetMatrixClip( | 66 void BitmapPlatformDevice::SetMatrixClip( |
67 const SkMatrix& transform, | 67 const SkMatrix& transform, |
68 const SkRegion& region) { | 68 const SkRegion& region) { |
69 transform_ = transform; | 69 transform_ = transform; |
70 clip_region_ = region; | 70 clip_region_ = region; |
71 config_dirty_ = true; | 71 config_dirty_ = true; |
72 } | 72 } |
73 | 73 |
| 74 // Loads the specified Skia transform into the device context |
| 75 static void LoadTransformToCGContext(CGContextRef context, |
| 76 const SkMatrix& matrix) { |
| 77 // CoreGraphics can concatenate transforms, but not reset the current one. |
| 78 // So in order to get the required behavior here, we need to first make |
| 79 // the current transformation matrix identity and only then load the new one. |
| 80 |
| 81 // Reset matrix to identity. |
| 82 CGAffineTransform orig_cg_matrix = CGContextGetCTM(context); |
| 83 CGAffineTransform orig_cg_matrix_inv = |
| 84 CGAffineTransformInvert(orig_cg_matrix); |
| 85 CGContextConcatCTM(context, orig_cg_matrix_inv); |
| 86 |
| 87 // assert that we have indeed returned to the identity Matrix. |
| 88 SkASSERT(CGAffineTransformIsIdentity(CGContextGetCTM(context))); |
| 89 |
| 90 // Convert xform to CG-land. |
| 91 // Our coordinate system is flipped to match WebKit's so we need to modify |
| 92 // the xform to match that. |
| 93 SkMatrix transformed_matrix = matrix; |
| 94 SkScalar sy = -matrix.getScaleY(); |
| 95 transformed_matrix.setScaleY(sy); |
| 96 size_t height = CGBitmapContextGetHeight(context); |
| 97 SkScalar ty = -matrix.getTranslateY(); // y axis is flipped. |
| 98 transformed_matrix.setTranslateY(ty + (SkScalar)height); |
| 99 |
| 100 CGAffineTransform cg_matrix = |
| 101 gfx::SkMatrixToCGAffineTransform(transformed_matrix); |
| 102 |
| 103 // Load final transform into context. |
| 104 CGContextConcatCTM(context, cg_matrix); |
| 105 } |
| 106 |
| 107 // Loads a SkRegion into the CG context. |
| 108 static void LoadClippingRegionToCGContext(CGContextRef context, |
| 109 const SkRegion& region, |
| 110 const SkMatrix& transformation) { |
| 111 if (region.isEmpty()) { |
| 112 // region can be empty, in which case everything will be clipped. |
| 113 SkRect rect; |
| 114 rect.setEmpty(); |
| 115 CGContextClipToRect(context, gfx::SkRectToCGRect(rect)); |
| 116 } else if (region.isRect()) { |
| 117 // CoreGraphics applies the current transform to clip rects, which is |
| 118 // unwanted. Inverse-transform the rect before sending it to CG. This only |
| 119 // works for translations and scaling, but not for rotations (but the |
| 120 // viewport is never rotated anyway). |
| 121 SkMatrix t; |
| 122 bool did_invert = transformation.invert(&t); |
| 123 if (!did_invert) |
| 124 t.reset(); |
| 125 // Do the transformation. |
| 126 SkRect rect; |
| 127 rect.set(region.getBounds()); |
| 128 t.mapRect(&rect); |
| 129 SkIRect irect; |
| 130 rect.round(&irect); |
| 131 CGContextClipToRect(context, gfx::SkIRectToCGRect(irect)); |
| 132 } else { |
| 133 // It is complex. |
| 134 SkPath path; |
| 135 region.getBoundaryPath(&path); |
| 136 // Clip. Note that windows clipping regions are not affected by the |
| 137 // transform so apply it manually. |
| 138 path.transform(transformation); |
| 139 // TODO(playmobil): Implement. |
| 140 SkASSERT(false); |
| 141 // LoadPathToDC(context, path); |
| 142 // hrgn = PathToRegion(context); |
| 143 } |
| 144 } |
| 145 |
74 void BitmapPlatformDevice::LoadConfig() { | 146 void BitmapPlatformDevice::LoadConfig() { |
75 if (!config_dirty_ || !bitmap_context_) | 147 if (!config_dirty_ || !bitmap_context_) |
76 return; // Nothing to do. | 148 return; // Nothing to do. |
77 config_dirty_ = false; | 149 config_dirty_ = false; |
78 | 150 |
79 // We must restore and then save the state of the graphics context since the | 151 // We must restore and then save the state of the graphics context since the |
80 // calls to Load the clipping region to the context are strictly cummulative, | 152 // calls to Load the clipping region to the context are strictly cummulative, |
81 // i.e., you can't replace a clip rect, other than with a save/restore. | 153 // i.e., you can't replace a clip rect, other than with a save/restore. |
82 // But this implies that no other changes to the state are done elsewhere. | 154 // But this implies that no other changes to the state are done elsewhere. |
83 // If we ever get to need to change this, then we must replace the clip rect | 155 // If we ever get to need to change this, then we must replace the clip rect |
(...skipping 157 matching lines...) Loading... |
241 | 313 |
242 if (!is_opaque) | 314 if (!is_opaque) |
243 bitmap_.eraseColor(0); | 315 bitmap_.eraseColor(0); |
244 | 316 |
245 surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), | 317 surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), |
246 bitmap_.height()); | 318 bitmap_.height()); |
247 return true; | 319 return true; |
248 } | 320 } |
249 | 321 |
250 } // namespace skia | 322 } // namespace skia |
OLD | NEW |