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...) Expand 10 before | Expand all | Expand 10 after 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 | |
146 void BitmapPlatformDevice::LoadConfig() { | 74 void BitmapPlatformDevice::LoadConfig() { |
147 if (!config_dirty_ || !bitmap_context_) | 75 if (!config_dirty_ || !bitmap_context_) |
148 return; // Nothing to do. | 76 return; // Nothing to do. |
149 config_dirty_ = false; | 77 config_dirty_ = false; |
150 | 78 |
151 // We must restore and then save the state of the graphics context since the | 79 // We must restore and then save the state of the graphics context since the |
152 // calls to Load the clipping region to the context are strictly cummulative, | 80 // calls to Load the clipping region to the context are strictly cummulative, |
153 // i.e., you can't replace a clip rect, other than with a save/restore. | 81 // i.e., you can't replace a clip rect, other than with a save/restore. |
154 // But this implies that no other changes to the state are done elsewhere. | 82 // But this implies that no other changes to the state are done elsewhere. |
155 // If we ever get to need to change this, then we must replace the clip rect | 83 // If we ever get to need to change this, then we must replace the clip rect |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 241 |
314 if (!is_opaque) | 242 if (!is_opaque) |
315 bitmap_.eraseColor(0); | 243 bitmap_.eraseColor(0); |
316 | 244 |
317 surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), | 245 surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), |
318 bitmap_.height()); | 246 bitmap_.height()); |
319 return true; | 247 return true; |
320 } | 248 } |
321 | 249 |
322 } // namespace skia | 250 } // namespace skia |
OLD | NEW |