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 |