| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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/platform_device_win.h" | 5 #include "skia/ext/platform_device_win.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | |
| 8 #include "skia/ext/skia_utils_win.h" | 7 #include "skia/ext/skia_utils_win.h" |
| 9 #include "SkMatrix.h" | 8 #include "SkMatrix.h" |
| 10 #include "SkPath.h" | 9 #include "SkPath.h" |
| 11 #include "SkRegion.h" | 10 #include "SkRegion.h" |
| 12 #include "SkUtils.h" | 11 #include "SkUtils.h" |
| 13 | 12 |
| 14 namespace skia { | 13 namespace skia { |
| 15 | 14 |
| 16 PlatformDeviceWin::PlatformDeviceWin(const SkBitmap& bitmap) | 15 PlatformDeviceWin::PlatformDeviceWin(const SkBitmap& bitmap) |
| 17 : SkDevice(bitmap) { | 16 : SkDevice(bitmap) { |
| 18 } | 17 } |
| 19 | 18 |
| 20 // static | 19 // static |
| 21 void PlatformDeviceWin::InitializeDC(HDC context) { | 20 void PlatformDeviceWin::InitializeDC(HDC context) { |
| 22 // Enables world transformation. | 21 // Enables world transformation. |
| 23 // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the | 22 // If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the |
| 24 // counterclockwise direction in logical space. This is equivalent to the | 23 // counterclockwise direction in logical space. This is equivalent to the |
| 25 // statement that, in the GM_ADVANCED graphics mode, both arc control points | 24 // statement that, in the GM_ADVANCED graphics mode, both arc control points |
| 26 // and arcs themselves fully respect the device context's world-to-device | 25 // and arcs themselves fully respect the device context's world-to-device |
| 27 // transformation. | 26 // transformation. |
| 28 BOOL res = SetGraphicsMode(context, GM_ADVANCED); | 27 BOOL res = SetGraphicsMode(context, GM_ADVANCED); |
| 29 DCHECK_NE(res, 0); | 28 SkASSERT(res != 0); |
| 30 | 29 |
| 31 // Enables dithering. | 30 // Enables dithering. |
| 32 res = SetStretchBltMode(context, HALFTONE); | 31 res = SetStretchBltMode(context, HALFTONE); |
| 33 DCHECK_NE(res, 0); | 32 SkASSERT(res != 0); |
| 34 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called | 33 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called |
| 35 // right after. | 34 // right after. |
| 36 res = SetBrushOrgEx(context, 0, 0, NULL); | 35 res = SetBrushOrgEx(context, 0, 0, NULL); |
| 37 DCHECK_NE(res, 0); | 36 SkASSERT(res != 0); |
| 38 | 37 |
| 39 // Sets up default orientation. | 38 // Sets up default orientation. |
| 40 res = SetArcDirection(context, AD_CLOCKWISE); | 39 res = SetArcDirection(context, AD_CLOCKWISE); |
| 41 DCHECK_NE(res, 0); | 40 SkASSERT(res != 0); |
| 42 | 41 |
| 43 // Sets up default colors. | 42 // Sets up default colors. |
| 44 res = SetBkColor(context, RGB(255, 255, 255)); | 43 res = SetBkColor(context, RGB(255, 255, 255)); |
| 45 DCHECK_NE(res, CLR_INVALID); | 44 SkASSERT(res != CLR_INVALID); |
| 46 res = SetTextColor(context, RGB(0, 0, 0)); | 45 res = SetTextColor(context, RGB(0, 0, 0)); |
| 47 DCHECK_NE(res, CLR_INVALID); | 46 SkASSERT(res != CLR_INVALID); |
| 48 res = SetDCBrushColor(context, RGB(255, 255, 255)); | 47 res = SetDCBrushColor(context, RGB(255, 255, 255)); |
| 49 DCHECK_NE(res, CLR_INVALID); | 48 SkASSERT(res != CLR_INVALID); |
| 50 res = SetDCPenColor(context, RGB(0, 0, 0)); | 49 res = SetDCPenColor(context, RGB(0, 0, 0)); |
| 51 DCHECK_NE(res, CLR_INVALID); | 50 SkASSERT(res != CLR_INVALID); |
| 52 | 51 |
| 53 // Sets up default transparency. | 52 // Sets up default transparency. |
| 54 res = SetBkMode(context, OPAQUE); | 53 res = SetBkMode(context, OPAQUE); |
| 55 DCHECK_NE(res, 0); | 54 SkASSERT(res != 0); |
| 56 res = SetROP2(context, R2_COPYPEN); | 55 res = SetROP2(context, R2_COPYPEN); |
| 57 DCHECK_NE(res, 0); | 56 SkASSERT(res != 0); |
| 58 } | 57 } |
| 59 | 58 |
| 60 // static | 59 // static |
| 61 void PlatformDeviceWin::LoadPathToDC(HDC context, const SkPath& path) { | 60 void PlatformDeviceWin::LoadPathToDC(HDC context, const SkPath& path) { |
| 62 switch (path.getFillType()) { | 61 switch (path.getFillType()) { |
| 63 case SkPath::kWinding_FillType: { | 62 case SkPath::kWinding_FillType: { |
| 64 int res = SetPolyFillMode(context, WINDING); | 63 int res = SetPolyFillMode(context, WINDING); |
| 65 DCHECK(res != 0); | 64 SkASSERT(res != 0); |
| 66 break; | 65 break; |
| 67 } | 66 } |
| 68 case SkPath::kEvenOdd_FillType: { | 67 case SkPath::kEvenOdd_FillType: { |
| 69 int res = SetPolyFillMode(context, ALTERNATE); | 68 int res = SetPolyFillMode(context, ALTERNATE); |
| 70 DCHECK(res != 0); | 69 SkASSERT(res != 0); |
| 71 break; | 70 break; |
| 72 } | 71 } |
| 73 default: { | 72 default: { |
| 74 NOTREACHED(); | 73 SkASSERT(false); |
| 75 break; | 74 break; |
| 76 } | 75 } |
| 77 } | 76 } |
| 78 BOOL res = BeginPath(context); | 77 BOOL res = BeginPath(context); |
| 79 DCHECK(res != 0); | 78 SkASSERT(res != 0); |
| 80 | 79 |
| 81 CubicPaths paths; | 80 CubicPaths paths; |
| 82 if (!SkPathToCubicPaths(&paths, path)) | 81 if (!SkPathToCubicPaths(&paths, path)) |
| 83 return; | 82 return; |
| 84 | 83 |
| 85 std::vector<POINT> points; | 84 std::vector<POINT> points; |
| 86 for (CubicPaths::const_iterator path(paths.begin()); path != paths.end(); | 85 for (CubicPaths::const_iterator path(paths.begin()); path != paths.end(); |
| 87 ++path) { | 86 ++path) { |
| 88 if (!path->size()) | 87 if (!path->size()) |
| 89 continue; | 88 continue; |
| 90 // DCHECK_EQ(points.size() % 4, 0); | |
| 91 points.resize(0); | 89 points.resize(0); |
| 92 points.reserve(path->size() * 3 / 4 + 1); | 90 points.reserve(path->size() * 3 / 4 + 1); |
| 93 points.push_back(SkPointToPOINT(path->front().p[0])); | 91 points.push_back(SkPointToPOINT(path->front().p[0])); |
| 94 for (CubicPath::const_iterator point(path->begin()); point != path->end(); | 92 for (CubicPath::const_iterator point(path->begin()); point != path->end(); |
| 95 ++point) { | 93 ++point) { |
| 96 // Never add point->p[0] | 94 // Never add point->p[0] |
| 97 points.push_back(SkPointToPOINT(point->p[1])); | 95 points.push_back(SkPointToPOINT(point->p[1])); |
| 98 points.push_back(SkPointToPOINT(point->p[2])); | 96 points.push_back(SkPointToPOINT(point->p[2])); |
| 99 points.push_back(SkPointToPOINT(point->p[3])); | 97 points.push_back(SkPointToPOINT(point->p[3])); |
| 100 } | 98 } |
| 101 DCHECK_EQ((points.size() - 1) % 3, 0); | 99 SkASSERT((points.size() - 1) % 3 == 0); |
| 102 // This is slightly inefficient since all straight line and quadratic lines | 100 // This is slightly inefficient since all straight line and quadratic lines |
| 103 // are "upgraded" to a cubic line. | 101 // are "upgraded" to a cubic line. |
| 104 // TODO(maruel): http://b/1147346 We should use | 102 // TODO(maruel): http://b/1147346 We should use |
| 105 // PolyDraw/PolyBezier/Polyline whenever possible. | 103 // PolyDraw/PolyBezier/Polyline whenever possible. |
| 106 res = PolyBezier(context, &points.front(), | 104 res = PolyBezier(context, &points.front(), |
| 107 static_cast<DWORD>(points.size())); | 105 static_cast<DWORD>(points.size())); |
| 108 DCHECK_NE(res, 0); | 106 SkASSERT(res != 0); |
| 109 if (res == 0) | 107 if (res == 0) |
| 110 break; | 108 break; |
| 111 } | 109 } |
| 112 if (res == 0) { | 110 if (res == 0) { |
| 113 // Make sure the path is discarded. | 111 // Make sure the path is discarded. |
| 114 AbortPath(context); | 112 AbortPath(context); |
| 115 } else { | 113 } else { |
| 116 res = EndPath(context); | 114 res = EndPath(context); |
| 117 DCHECK(res != 0); | 115 SkASSERT(res != 0); |
| 118 } | 116 } |
| 119 } | 117 } |
| 120 | 118 |
| 121 // static | 119 // static |
| 122 void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) { | 120 void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) { |
| 123 XFORM xf; | 121 XFORM xf; |
| 124 xf.eM11 = matrix[SkMatrix::kMScaleX]; | 122 xf.eM11 = matrix[SkMatrix::kMScaleX]; |
| 125 xf.eM21 = matrix[SkMatrix::kMSkewX]; | 123 xf.eM21 = matrix[SkMatrix::kMSkewX]; |
| 126 xf.eDx = matrix[SkMatrix::kMTransX]; | 124 xf.eDx = matrix[SkMatrix::kMTransX]; |
| 127 xf.eM12 = matrix[SkMatrix::kMSkewY]; | 125 xf.eM12 = matrix[SkMatrix::kMSkewY]; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 current_path = &paths->back(); | 174 current_path = &paths->back(); |
| 177 continue; | 175 continue; |
| 178 } | 176 } |
| 179 case SkPath::kDone_Verb: // iter.next returns 0 points | 177 case SkPath::kDone_Verb: // iter.next returns 0 points |
| 180 default: { | 178 default: { |
| 181 current_path = NULL; | 179 current_path = NULL; |
| 182 // Will return false. | 180 // Will return false. |
| 183 break; | 181 break; |
| 184 } | 182 } |
| 185 } | 183 } |
| 186 DCHECK(current_path); | 184 SkASSERT(current_path); |
| 187 if (!current_path) { | 185 if (!current_path) { |
| 188 paths->clear(); | 186 paths->clear(); |
| 189 return false; | 187 return false; |
| 190 } | 188 } |
| 191 current_path->push_back(points_to_add); | 189 current_path->push_back(points_to_add); |
| 192 } | 190 } |
| 193 return true; | 191 return true; |
| 194 } | 192 } |
| 195 | 193 |
| 196 // static | 194 // static |
| (...skipping 16 matching lines...) Expand all Loading... |
| 213 // It is complex. | 211 // It is complex. |
| 214 SkPath path; | 212 SkPath path; |
| 215 region.getBoundaryPath(&path); | 213 region.getBoundaryPath(&path); |
| 216 // Clip. Note that windows clipping regions are not affected by the | 214 // Clip. Note that windows clipping regions are not affected by the |
| 217 // transform so apply it manually. | 215 // transform so apply it manually. |
| 218 path.transform(transformation); | 216 path.transform(transformation); |
| 219 LoadPathToDC(context, path); | 217 LoadPathToDC(context, path); |
| 220 hrgn = PathToRegion(context); | 218 hrgn = PathToRegion(context); |
| 221 } | 219 } |
| 222 int result = SelectClipRgn(context, hrgn); | 220 int result = SelectClipRgn(context, hrgn); |
| 223 DCHECK_NE(result, ERROR); | 221 SkASSERT(result != ERROR); |
| 224 result = DeleteObject(hrgn); | 222 result = DeleteObject(hrgn); |
| 225 DCHECK_NE(result, 0); | 223 SkASSERT(result != 0); |
| 226 } | 224 } |
| 227 | 225 |
| 228 } // namespace skia | 226 } // namespace skia |
| 229 | 227 |
| OLD | NEW |