| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #include "PlatformDeviceMac.h" | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "base/gfx/skia_utils_mac.h" | |
| 11 #include "SkMatrix.h" | |
| 12 #include "SkPath.h" | |
| 13 #include "SkUtils.h" | |
| 14 | |
| 15 namespace gfx { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // Constrains position and size to fit within available_size. | |
| 20 bool constrain(int available_size, int* position, int *size) { | |
| 21 if (*position < 0) { | |
| 22 *size += *position; | |
| 23 *position = 0; | |
| 24 } | |
| 25 if (*size > 0 && *position < available_size) { | |
| 26 int overflow = (*position + *size) - available_size; | |
| 27 if (overflow > 0) { | |
| 28 *size -= overflow; | |
| 29 } | |
| 30 return true; | |
| 31 } | |
| 32 return false; | |
| 33 } | |
| 34 | |
| 35 // Sets the opacity of the specified value to 0xFF. | |
| 36 void makeOpaqueAlphaAdjuster(uint32_t* pixel) { | |
| 37 *pixel |= 0xFF000000; | |
| 38 } | |
| 39 | |
| 40 } // namespace | |
| 41 | |
| 42 PlatformDeviceMac::PlatformDeviceMac(const SkBitmap& bitmap) | |
| 43 : SkDevice(bitmap) { | |
| 44 } | |
| 45 | |
| 46 void PlatformDeviceMac::makeOpaque(int x, int y, int width, int height) { | |
| 47 processPixels(x, y, width, height, makeOpaqueAlphaAdjuster); | |
| 48 } | |
| 49 | |
| 50 // Set up the CGContextRef for peaceful coexistence with Skia | |
| 51 void PlatformDeviceMac::InitializeCGContext(CGContextRef context) { | |
| 52 // CG defaults to the same settings as Skia | |
| 53 } | |
| 54 | |
| 55 // static | |
| 56 void PlatformDeviceMac::LoadPathToCGContext(CGContextRef context, | |
| 57 const SkPath& path) { | |
| 58 // instead of a persistent attribute of the context, CG specifies the fill | |
| 59 // type per call, so we just have to load up the geometry. | |
| 60 CGContextBeginPath(context); | |
| 61 | |
| 62 SkPoint points[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} }; | |
| 63 SkPath::Iter iter(path, false); | |
| 64 for (SkPath::Verb verb = iter.next(points); verb != SkPath::kDone_Verb; | |
| 65 verb = iter.next(points)) { | |
| 66 switch (verb) { | |
| 67 case SkPath::kMove_Verb: { // iter.next returns 1 point | |
| 68 CGContextMoveToPoint(context, points[0].fX, points[0].fY); | |
| 69 break; | |
| 70 } | |
| 71 case SkPath::kLine_Verb: { // iter.next returns 2 points | |
| 72 CGContextAddLineToPoint(context, points[1].fX, points[1].fY); | |
| 73 break; | |
| 74 } | |
| 75 case SkPath::kQuad_Verb: { // iter.next returns 3 points | |
| 76 CGContextAddQuadCurveToPoint(context, points[1].fX, points[1].fY, | |
| 77 points[2].fX, points[2].fY); | |
| 78 break; | |
| 79 } | |
| 80 case SkPath::kCubic_Verb: { // iter.next returns 4 points | |
| 81 CGContextAddCurveToPoint(context, points[1].fX, points[1].fY, | |
| 82 points[2].fX, points[2].fY, | |
| 83 points[3].fX, points[3].fY); | |
| 84 break; | |
| 85 } | |
| 86 case SkPath::kClose_Verb: { // iter.next returns 1 point (the last point) | |
| 87 break; | |
| 88 } | |
| 89 case SkPath::kDone_Verb: // iter.next returns 0 points | |
| 90 default: { | |
| 91 NOTREACHED(); | |
| 92 break; | |
| 93 } | |
| 94 } | |
| 95 } | |
| 96 CGContextClosePath(context); | |
| 97 } | |
| 98 | |
| 99 // static | |
| 100 void PlatformDeviceMac::LoadTransformToCGContext(CGContextRef context, | |
| 101 const SkMatrix& matrix) { | |
| 102 // CoreGraphics can concatenate transforms, but not reset the current one. | |
| 103 // So in order to get the required behavior here, we need to first make | |
| 104 // the current transformation matrix identity and only then load the new one. | |
| 105 | |
| 106 // Reset matrix to identity. | |
| 107 CGAffineTransform orig_cg_matrix = CGContextGetCTM(context); | |
| 108 CGAffineTransform orig_cg_matrix_inv = CGAffineTransformInvert(orig_cg_matrix)
; | |
| 109 CGContextConcatCTM(context, orig_cg_matrix_inv); | |
| 110 | |
| 111 // assert that we have indeed returned to the identity Matrix. | |
| 112 DCHECK(CGAffineTransformIsIdentity(CGContextGetCTM(context))); | |
| 113 | |
| 114 // Convert xform to CG-land. | |
| 115 // Our coordinate system is flipped to match WebKit's so we need to modify | |
| 116 // the xform to match that. | |
| 117 SkMatrix transformed_matrix = matrix; | |
| 118 SkScalar sy = matrix.getScaleY() * (SkScalar)-1; | |
| 119 transformed_matrix.setScaleY(sy); | |
| 120 size_t height = CGBitmapContextGetHeight(context); | |
| 121 SkScalar ty = -matrix.getTranslateY(); // y axis is flipped. | |
| 122 transformed_matrix.setTranslateY(ty + (SkScalar)height); | |
| 123 | |
| 124 CGAffineTransform cg_matrix = SkMatrixToCGAffineTransform(transformed_matrix); | |
| 125 | |
| 126 // Load final transform into context. | |
| 127 CGContextConcatCTM(context, cg_matrix); | |
| 128 } | |
| 129 | |
| 130 // static | |
| 131 void PlatformDeviceMac::LoadClippingRegionToCGContext( | |
| 132 CGContextRef context, | |
| 133 const SkRegion& region, | |
| 134 const SkMatrix& transformation) { | |
| 135 if (region.isEmpty()) { | |
| 136 // region can be empty, in which case everything will be clipped. | |
| 137 SkRect rect; | |
| 138 rect.setEmpty(); | |
| 139 CGContextClipToRect(context, SkRectToCGRect(rect)); | |
| 140 } else if (region.isRect()) { | |
| 141 // Do the transformation. | |
| 142 SkRect rect; | |
| 143 rect.set(region.getBounds()); | |
| 144 transformation.mapRect(&rect); | |
| 145 SkIRect irect; | |
| 146 rect.round(&irect); | |
| 147 CGContextClipToRect(context, SkIRectToCGRect(irect)); | |
| 148 } else { | |
| 149 // It is complex. | |
| 150 SkPath path; | |
| 151 region.getBoundaryPath(&path); | |
| 152 // Clip. Note that windows clipping regions are not affected by the | |
| 153 // transform so apply it manually. | |
| 154 path.transform(transformation); | |
| 155 // TODO(playmobil): Implement. | |
| 156 NOTREACHED(); | |
| 157 // LoadPathToDC(context, path); | |
| 158 // hrgn = PathToRegion(context); | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 } // namespace gfx | |
| 163 | |
| OLD | NEW |