Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Side by Side Diff: base/gfx/platform_device_win.cc

Issue 11244: Move PlatformCanvas and PlatformDevice from base/gfx to webkit/port. I left h... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/gfx/platform_device_win.h ('k') | base/gfx/vector_canvas.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "base/gfx/platform_device_win.h"
6
7 #include "base/logging.h"
8 #include "base/gfx/skia_utils.h"
9 #include "SkMatrix.h"
10 #include "SkPath.h"
11 #include "SkRegion.h"
12 #include "SkUtils.h"
13
14 namespace gfx {
15
16 PlatformDeviceWin::PlatformDeviceWin(const SkBitmap& bitmap)
17 : SkDevice(bitmap) {
18 }
19
20 // static
21 void PlatformDeviceWin::InitializeDC(HDC context) {
22 // Enables world transformation.
23 // 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
25 // 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
27 // transformation.
28 BOOL res = SetGraphicsMode(context, GM_ADVANCED);
29 DCHECK_NE(res, 0);
30
31 // Enables dithering.
32 res = SetStretchBltMode(context, HALFTONE);
33 DCHECK_NE(res, 0);
34 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called
35 // right after.
36 res = SetBrushOrgEx(context, 0, 0, NULL);
37 DCHECK_NE(res, 0);
38
39 // Sets up default orientation.
40 res = SetArcDirection(context, AD_CLOCKWISE);
41 DCHECK_NE(res, 0);
42
43 // Sets up default colors.
44 res = SetBkColor(context, RGB(255, 255, 255));
45 DCHECK_NE(res, CLR_INVALID);
46 res = SetTextColor(context, RGB(0, 0, 0));
47 DCHECK_NE(res, CLR_INVALID);
48 res = SetDCBrushColor(context, RGB(255, 255, 255));
49 DCHECK_NE(res, CLR_INVALID);
50 res = SetDCPenColor(context, RGB(0, 0, 0));
51 DCHECK_NE(res, CLR_INVALID);
52
53 // Sets up default transparency.
54 res = SetBkMode(context, OPAQUE);
55 DCHECK_NE(res, 0);
56 res = SetROP2(context, R2_COPYPEN);
57 DCHECK_NE(res, 0);
58 }
59
60 // static
61 void PlatformDeviceWin::LoadPathToDC(HDC context, const SkPath& path) {
62 switch (path.getFillType()) {
63 case SkPath::kWinding_FillType: {
64 int res = SetPolyFillMode(context, WINDING);
65 DCHECK(res != 0);
66 break;
67 }
68 case SkPath::kEvenOdd_FillType: {
69 int res = SetPolyFillMode(context, ALTERNATE);
70 DCHECK(res != 0);
71 break;
72 }
73 default: {
74 NOTREACHED();
75 break;
76 }
77 }
78 BOOL res = BeginPath(context);
79 DCHECK(res != 0);
80
81 CubicPaths paths;
82 if (!SkPathToCubicPaths(&paths, path))
83 return;
84
85 std::vector<POINT> points;
86 for (CubicPaths::const_iterator path(paths.begin()); path != paths.end();
87 ++path) {
88 if (!path->size())
89 continue;
90 // DCHECK_EQ(points.size() % 4, 0);
91 points.resize(0);
92 points.reserve(path->size() * 3 / 4 + 1);
93 points.push_back(SkPointToPOINT(path->front().p[0]));
94 for (CubicPath::const_iterator point(path->begin()); point != path->end();
95 ++point) {
96 // Never add point->p[0]
97 points.push_back(SkPointToPOINT(point->p[1]));
98 points.push_back(SkPointToPOINT(point->p[2]));
99 points.push_back(SkPointToPOINT(point->p[3]));
100 }
101 DCHECK_EQ((points.size() - 1) % 3, 0);
102 // This is slightly inefficient since all straight line and quadratic lines
103 // are "upgraded" to a cubic line.
104 // TODO(maruel): http://b/1147346 We should use
105 // PolyDraw/PolyBezier/Polyline whenever possible.
106 res = PolyBezier(context, &points.front(),
107 static_cast<DWORD>(points.size()));
108 DCHECK_NE(res, 0);
109 if (res == 0)
110 break;
111 }
112 if (res == 0) {
113 // Make sure the path is discarded.
114 AbortPath(context);
115 } else {
116 res = EndPath(context);
117 DCHECK(res != 0);
118 }
119 }
120
121 // static
122 void PlatformDeviceWin::LoadTransformToDC(HDC dc, const SkMatrix& matrix) {
123 XFORM xf;
124 xf.eM11 = matrix[SkMatrix::kMScaleX];
125 xf.eM21 = matrix[SkMatrix::kMSkewX];
126 xf.eDx = matrix[SkMatrix::kMTransX];
127 xf.eM12 = matrix[SkMatrix::kMSkewY];
128 xf.eM22 = matrix[SkMatrix::kMScaleY];
129 xf.eDy = matrix[SkMatrix::kMTransY];
130 SetWorldTransform(dc, &xf);
131 }
132
133 // static
134 bool PlatformDeviceWin::SkPathToCubicPaths(CubicPaths* paths,
135 const SkPath& skpath) {
136 paths->clear();
137 CubicPath* current_path = NULL;
138 SkPoint current_points[4];
139 CubicPoints points_to_add;
140 SkPath::Iter iter(skpath, false);
141 for (SkPath::Verb verb = iter.next(current_points);
142 verb != SkPath::kDone_Verb;
143 verb = iter.next(current_points)) {
144 switch (verb) {
145 case SkPath::kMove_Verb: { // iter.next returns 1 point
146 // Ignores it since the point is copied in the next operation. See
147 // SkPath::Iter::next() for reference.
148 paths->push_back(CubicPath());
149 current_path = &paths->back();
150 // Skip point addition.
151 continue;
152 }
153 case SkPath::kLine_Verb: { // iter.next returns 2 points
154 points_to_add.p[0] = current_points[0];
155 points_to_add.p[1] = current_points[0];
156 points_to_add.p[2] = current_points[1];
157 points_to_add.p[3] = current_points[1];
158 break;
159 }
160 case SkPath::kQuad_Verb: { // iter.next returns 3 points
161 points_to_add.p[0] = current_points[0];
162 points_to_add.p[1] = current_points[1];
163 points_to_add.p[2] = current_points[2];
164 points_to_add.p[3] = current_points[2];
165 break;
166 }
167 case SkPath::kCubic_Verb: { // iter.next returns 4 points
168 points_to_add.p[0] = current_points[0];
169 points_to_add.p[1] = current_points[1];
170 points_to_add.p[2] = current_points[2];
171 points_to_add.p[3] = current_points[3];
172 break;
173 }
174 case SkPath::kClose_Verb: { // iter.next returns 1 point (the last point)
175 paths->push_back(CubicPath());
176 current_path = &paths->back();
177 continue;
178 }
179 case SkPath::kDone_Verb: // iter.next returns 0 points
180 default: {
181 current_path = NULL;
182 // Will return false.
183 break;
184 }
185 }
186 DCHECK(current_path);
187 if (!current_path) {
188 paths->clear();
189 return false;
190 }
191 current_path->push_back(points_to_add);
192 }
193 return true;
194 }
195
196 // static
197 void PlatformDeviceWin::LoadClippingRegionToDC(HDC context,
198 const SkRegion& region,
199 const SkMatrix& transformation) {
200 HRGN hrgn;
201 if (region.isEmpty()) {
202 // region can be empty, in which case everything will be clipped.
203 hrgn = CreateRectRgn(0, 0, 0, 0);
204 } else if (region.isRect()) {
205 // Do the transformation.
206 SkRect rect;
207 rect.set(region.getBounds());
208 transformation.mapRect(&rect);
209 SkIRect irect;
210 rect.round(&irect);
211 hrgn = CreateRectRgnIndirect(&SkIRectToRECT(irect));
212 } else {
213 // It is complex.
214 SkPath path;
215 region.getBoundaryPath(&path);
216 // Clip. Note that windows clipping regions are not affected by the
217 // transform so apply it manually.
218 path.transform(transformation);
219 LoadPathToDC(context, path);
220 hrgn = PathToRegion(context);
221 }
222 int result = SelectClipRgn(context, hrgn);
223 DCHECK_NE(result, ERROR);
224 result = DeleteObject(hrgn);
225 DCHECK_NE(result, 0);
226 }
227
228 } // namespace gfx
229
OLDNEW
« no previous file with comments | « base/gfx/platform_device_win.h ('k') | base/gfx/vector_canvas.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698