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

Side by Side Diff: content/test/layout_tests/runner/WebTestThemeControlWin.cpp

Issue 110533009: Import TestRunner library into chromium. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updates Created 7 years 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
OLDNEW
(Empty)
1 // Copyright 2013 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 /*
6 * Copyright (C) 2010 Google Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 * * Neither the name of Google Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 // This file implements a simple generic version of the WebThemeEngine,
36 // which is used to draw all the native controls on a web page. We use this
37 // file when running in layout test mode in order to remove any
38 // platform-specific rendering differences due to themes, colors, etc.
39 //
40
41 #include "content/test/layout_tests/runner/WebTestThemeControlWin.h"
42
43 #include "content/test/layout_tests/runner/TestCommon.h"
44 #include "skia/ext/skia_utils_win.h"
45 #include "third_party/skia/include/core/SkCanvas.h"
46 #include "third_party/skia/include/core/SkPaint.h"
47 #include "third_party/skia/include/core/SkPath.h"
48
49 #include <algorithm>
50
51 using namespace blink;
52 using namespace std;
53
54 namespace WebTestRunner {
55
56 namespace {
57
58 const SkColor edgeColor = SK_ColorBLACK;
59 const SkColor readOnlyColor = SkColorSetRGB(0xe9, 0xc2, 0xa6);
60 const SkColor fgColor = SK_ColorBLACK;
61
62 // These are indexed by WebTestThemeControlWin::State, *not* WebThemeEngine::Sta te.
63 const SkColor bgColors[] = {
64 SK_ColorBLACK, // Unknown (not used)
65 SkColorSetRGB(0xc9, 0xc9, 0xc9), // Disabled
66 SkColorSetRGB(0xf3, 0xe0, 0xd0), // Readonly
67 SkColorSetRGB(0x89, 0xc4, 0xff), // Normal
68 SkColorSetRGB(0x43, 0xf9, 0xff), // Hot
69 SkColorSetRGB(0x20, 0xf6, 0xcc), // Hover
70 SkColorSetRGB(0x00, 0xf3, 0xac), // Focused
71 SkColorSetRGB(0xa9, 0xff, 0x12), // Pressed
72 SkColorSetRGB(0xcc, 0xcc, 0xcc) // Indeterminate (not used)
73 };
74
75 SkIRect validate(const SkIRect& rect, WebTestThemeControlWin::Type ctype)
76 {
77 switch (ctype) {
78 case WebTestThemeControlWin::UncheckedBoxType:
79 case WebTestThemeControlWin::CheckedBoxType:
80 case WebTestThemeControlWin::UncheckedRadioType:
81 case WebTestThemeControlWin::CheckedRadioType: {
82 SkIRect retval = rect;
83
84 // The maximum width and height is 13.
85 // Center the square in the passed rectangle.
86 const int maxControlSize = 13;
87 int controlSize = std::min(rect.width(), rect.height());
88 controlSize = std::min(controlSize, maxControlSize);
89
90 retval.fLeft = rect.fLeft + (rect.width() / 2) - (controlSize / 2);
91 retval.fRight = retval.fLeft + controlSize - 1;
92 retval.fTop = rect.fTop + (rect.height() / 2) - (controlSize / 2);
93 retval.fBottom = retval.fTop + controlSize - 1;
94
95 return retval;
96 }
97
98 default:
99 return rect;
100 }
101 }
102
103 }
104
105 WebTestThemeControlWin::WebTestThemeControlWin(SkCanvas* canvas, const SkIRect& irect, Type ctype, State cstate)
106 : m_canvas(canvas)
107 , m_irect(validate(irect, ctype))
108 , m_type(ctype)
109 , m_state(cstate)
110 , m_left(m_irect.fLeft)
111 , m_right(m_irect.fRight)
112 , m_top(m_irect.fTop)
113 , m_bottom(m_irect.fBottom)
114 , m_height(m_irect.height())
115 , m_width(m_irect.width())
116 , m_edgeColor(edgeColor)
117 , m_bgColor(bgColors[cstate])
118 , m_fgColor(fgColor)
119 {
120 }
121
122 WebTestThemeControlWin::~WebTestThemeControlWin()
123 {
124 }
125
126 void WebTestThemeControlWin::box(const SkIRect& rect, SkColor fillColor)
127 {
128 SkPaint paint;
129
130 paint.setStyle(SkPaint::kFill_Style);
131 paint.setColor(fillColor);
132 m_canvas->drawIRect(rect, paint);
133
134 paint.setColor(m_edgeColor);
135 paint.setStyle(SkPaint::kStroke_Style);
136 m_canvas->drawIRect(rect, paint);
137 }
138
139 void WebTestThemeControlWin::line(int x0, int y0, int x1, int y1, SkColor color)
140 {
141 SkPaint paint;
142 paint.setColor(color);
143 m_canvas->drawLine(SkIntToScalar(x0), SkIntToScalar(y0), SkIntToScalar(x1), SkIntToScalar(y1), paint);
144 }
145
146 void WebTestThemeControlWin::triangle(int x0, int y0, int x1, int y1, int x2, in t y2, SkColor color)
147 {
148 SkPath path;
149 SkPaint paint;
150
151 paint.setColor(color);
152 paint.setStyle(SkPaint::kFill_Style);
153 path.incReserve(4);
154 path.moveTo(SkIntToScalar(x0), SkIntToScalar(y0));
155 path.lineTo(SkIntToScalar(x1), SkIntToScalar(y1));
156 path.lineTo(SkIntToScalar(x2), SkIntToScalar(y2));
157 path.close();
158 m_canvas->drawPath(path, paint);
159
160 paint.setColor(m_edgeColor);
161 paint.setStyle(SkPaint::kStroke_Style);
162 m_canvas->drawPath(path, paint);
163 }
164
165 void WebTestThemeControlWin::roundRect(SkColor color)
166 {
167 SkRect rect;
168 SkScalar radius = SkIntToScalar(5);
169 SkPaint paint;
170
171 rect.set(m_irect);
172 paint.setColor(color);
173 paint.setStyle(SkPaint::kFill_Style);
174 m_canvas->drawRoundRect(rect, radius, radius, paint);
175
176 paint.setColor(m_edgeColor);
177 paint.setStyle(SkPaint::kStroke_Style);
178 m_canvas->drawRoundRect(rect, radius, radius, paint);
179 }
180
181 void WebTestThemeControlWin::oval(SkColor color)
182 {
183 SkRect rect;
184 SkPaint paint;
185
186 rect.set(m_irect);
187 paint.setColor(color);
188 paint.setStyle(SkPaint::kFill_Style);
189 m_canvas->drawOval(rect, paint);
190
191 paint.setColor(m_edgeColor);
192 paint.setStyle(SkPaint::kStroke_Style);
193 m_canvas->drawOval(rect, paint);
194 }
195
196 void WebTestThemeControlWin::circle(SkScalar radius, SkColor color)
197 {
198 SkScalar cy = SkIntToScalar(m_top + m_height / 2);
199 SkScalar cx = SkIntToScalar(m_left + m_width / 2);
200 SkPaint paint;
201
202 paint.setColor(color);
203 paint.setStyle(SkPaint::kFill_Style);
204 m_canvas->drawCircle(cx, cy, radius, paint);
205
206 paint.setColor(m_edgeColor);
207 paint.setStyle(SkPaint::kStroke_Style);
208 m_canvas->drawCircle(cx, cy, radius, paint);
209 }
210
211 void WebTestThemeControlWin::nestedBoxes(int indentLeft, int indentTop, int inde ntRight, int indentBottom, SkColor outerColor, SkColor innerColor)
212 {
213 SkIRect lirect;
214 box(m_irect, outerColor);
215 lirect.set(m_irect.fLeft + indentLeft, m_irect.fTop + indentTop, m_irect.fRi ght - indentRight, m_irect.fBottom - indentBottom);
216 box(lirect, innerColor);
217 }
218
219 void WebTestThemeControlWin::markState()
220 {
221 // The horizontal lines in a read only control are spaced by this amount.
222 const int readOnlyLineOffset = 5;
223
224 // The length of a triangle side for the corner marks.
225 const int triangleSize = 5;
226
227 switch (m_state) {
228 case UnknownState:
229 case DisabledState:
230 case NormalState:
231 case IndeterminateState:
232 // Don't visually mark these states (color is enough).
233 break;
234 case ReadOnlyState:
235 // Drawing lines across the control.
236 for (int i = m_top + readOnlyLineOffset; i < m_bottom; i += readOnlyLine Offset)
237 line(m_left + 1, i, m_right - 1, i, readOnlyColor);
238 break;
239
240 case HotState:
241 // Draw a triangle in the upper left corner of the control.
242 triangle(m_left, m_top, m_left + triangleSize, m_top, m_left, m_top + tr iangleSize, m_edgeColor);
243 break;
244
245 case HoverState:
246 // Draw a triangle in the upper right corner of the control.
247 triangle(m_right, m_top, m_right, m_top + triangleSize, m_right - triang leSize, m_top, m_edgeColor);
248 break;
249
250 case FocusedState:
251 // Draw a triangle in the bottom right corner of the control.
252 triangle(m_right, m_bottom, m_right - triangleSize, m_bottom, m_right, m _bottom - triangleSize, m_edgeColor);
253 break;
254
255 case PressedState:
256 // Draw a triangle in the bottom left corner of the control.
257 triangle(m_left, m_bottom, m_left, m_bottom - triangleSize, m_left + tri angleSize, m_bottom, m_edgeColor);
258 break;
259
260 default:
261 BLINK_ASSERT_NOT_REACHED();
262 break;
263 }
264 }
265
266 void WebTestThemeControlWin::draw()
267 {
268 int halfWidth = m_width / 2;
269 int halfHeight = m_height / 2;
270 int quarterWidth = m_width / 4;
271 int quarterHeight = m_height / 4;
272
273 // Indent amounts for the check in a checkbox or radio button.
274 const int checkIndent = 3;
275
276 // Indent amounts for short and long sides of the scrollbar notches.
277 const int notchLongOffset = 1;
278 const int notchShortOffset = 4;
279 const int noOffset = 0;
280
281 // Indent amounts for the short and long sides of a scroll thumb box.
282 const int thumbLongIndent = 0;
283 const int thumbShortIndent = 2;
284
285 // Indents for the crosshatch on a scroll grip.
286 const int gripLongIndent = 3;
287 const int gripShortIndent = 5;
288
289 // Indents for the the slider track.
290 const int sliderIndent = 2;
291
292 switch (m_type) {
293 case UnknownType:
294 BLINK_ASSERT_NOT_REACHED();
295 break;
296
297 case TextFieldType:
298 // We render this by hand outside of this function.
299 BLINK_ASSERT_NOT_REACHED();
300 break;
301
302 case PushButtonType:
303 // push buttons render as a rounded rectangle
304 roundRect(m_bgColor);
305 break;
306
307 case UncheckedBoxType:
308 // Unchecked boxes are simply plain boxes.
309 box(m_irect, m_bgColor);
310 break;
311
312 case CheckedBoxType:
313 nestedBoxes(checkIndent, checkIndent, checkIndent, checkIndent, m_bgColo r, m_fgColor);
314 break;
315
316 case IndeterminateCheckboxType:
317 // Indeterminate checkbox is a box containing '-'.
318 nestedBoxes(checkIndent, halfHeight, checkIndent, halfHeight, m_bgColor, m_fgColor);
319 break;
320
321 case UncheckedRadioType:
322 circle(SkIntToScalar(halfHeight), m_bgColor);
323 break;
324
325 case CheckedRadioType:
326 circle(SkIntToScalar(halfHeight), m_bgColor);
327 circle(SkIntToScalar(halfHeight - checkIndent), m_fgColor);
328 break;
329
330 case HorizontalScrollTrackBackType: {
331 // Draw a box with a notch at the left.
332 int longOffset = halfHeight - notchLongOffset;
333 int shortOffset = m_width - notchShortOffset;
334 nestedBoxes(noOffset, longOffset, shortOffset, longOffset, m_bgColor, m_ edgeColor);
335 break;
336 }
337
338 case HorizontalScrollTrackForwardType: {
339 // Draw a box with a notch at the right.
340 int longOffset = halfHeight - notchLongOffset;
341 int shortOffset = m_width - notchShortOffset;
342 nestedBoxes(shortOffset, longOffset, noOffset, longOffset, m_bgColor, m_ fgColor);
343 break;
344 }
345
346 case VerticalScrollTrackBackType: {
347 // Draw a box with a notch at the top.
348 int longOffset = halfWidth - notchLongOffset;
349 int shortOffset = m_height - notchShortOffset;
350 nestedBoxes(longOffset, noOffset, longOffset, shortOffset, m_bgColor, m_ fgColor);
351 break;
352 }
353
354 case VerticalScrollTrackForwardType: {
355 // Draw a box with a notch at the bottom.
356 int longOffset = halfWidth - notchLongOffset;
357 int shortOffset = m_height - notchShortOffset;
358 nestedBoxes(longOffset, shortOffset, longOffset, noOffset, m_bgColor, m_ fgColor);
359 break;
360 }
361
362 case HorizontalScrollThumbType:
363 // Draw a narrower box on top of the outside box.
364 nestedBoxes(thumbLongIndent, thumbShortIndent, thumbLongIndent, thumbSho rtIndent, m_bgColor, m_bgColor);
365 break;
366
367 case VerticalScrollThumbType:
368 // Draw a shorter box on top of the outside box.
369 nestedBoxes(thumbShortIndent, thumbLongIndent, thumbShortIndent, thumbLo ngIndent, m_bgColor, m_bgColor);
370 break;
371
372 case HorizontalSliderThumbType:
373 case VerticalSliderThumbType:
374 // Slider thumbs are ovals.
375 oval(m_bgColor);
376 break;
377
378 case HorizontalScrollGripType: {
379 // Draw a horizontal crosshatch for the grip.
380 int longOffset = halfWidth - gripLongIndent;
381 line(m_left + gripLongIndent, m_top + halfHeight, m_right - gripLongInde nt, m_top + halfHeight, m_fgColor);
382 line(m_left + longOffset, m_top + gripShortIndent, m_left + longOffset, m_bottom - gripShortIndent, m_fgColor);
383 line(m_right - longOffset, m_top + gripShortIndent, m_right - longOffset , m_bottom - gripShortIndent, m_fgColor);
384 break;
385 }
386
387 case VerticalScrollGripType: {
388 // Draw a vertical crosshatch for the grip.
389 int longOffset = halfHeight - gripLongIndent;
390 line(m_left + halfWidth, m_top + gripLongIndent, m_left + halfWidth, m_b ottom - gripLongIndent, m_fgColor);
391 line(m_left + gripShortIndent, m_top + longOffset, m_right - gripShortIn dent, m_top + longOffset, m_fgColor);
392 line(m_left + gripShortIndent, m_bottom - longOffset, m_right - gripShor tIndent, m_bottom - longOffset, m_fgColor);
393 break;
394 }
395
396 case LeftArrowType:
397 // Draw a left arrow inside a box.
398 box(m_irect, m_bgColor);
399 triangle(m_right - quarterWidth, m_top + quarterHeight, m_right - quarte rWidth, m_bottom - quarterHeight, m_left + quarterWidth, m_top + halfHeight, m_f gColor);
400 break;
401
402 case RightArrowType:
403 // Draw a left arrow inside a box.
404 box(m_irect, m_bgColor);
405 triangle(m_left + quarterWidth, m_top + quarterHeight, m_right - quarter Width, m_top + halfHeight, m_left + quarterWidth, m_bottom - quarterHeight, m_fg Color);
406 break;
407
408 case UpArrowType:
409 // Draw an up arrow inside a box.
410 box(m_irect, m_bgColor);
411 triangle(m_left + quarterWidth, m_bottom - quarterHeight, m_left + halfW idth, m_top + quarterHeight, m_right - quarterWidth, m_bottom - quarterHeight, m _fgColor);
412 break;
413
414 case DownArrowType:
415 // Draw a down arrow inside a box.
416 box(m_irect, m_bgColor);
417 triangle(m_left + quarterWidth, m_top + quarterHeight, m_right - quarter Width, m_top + quarterHeight, m_left + halfWidth, m_bottom - quarterHeight, m_fg Color);
418 break;
419
420 case HorizontalSliderTrackType: {
421 // Draw a narrow rect for the track plus box hatches on the ends.
422 SkIRect lirect;
423 lirect = m_irect;
424 lirect.inset(noOffset, halfHeight - sliderIndent);
425 box(lirect, m_bgColor);
426 line(m_left, m_top, m_left, m_bottom, m_edgeColor);
427 line(m_right, m_top, m_right, m_bottom, m_edgeColor);
428 break;
429 }
430
431 case VerticalSliderTrackType: {
432 // Draw a narrow rect for the track plus box hatches on the ends.
433 SkIRect lirect;
434 lirect = m_irect;
435 lirect.inset(halfWidth - sliderIndent, noOffset);
436 box(lirect, m_bgColor);
437 line(m_left, m_top, m_right, m_top, m_edgeColor);
438 line(m_left, m_bottom, m_right, m_bottom, m_edgeColor);
439 break;
440 }
441
442 case DropDownButtonType:
443 // Draw a box with a big down arrow on top.
444 box(m_irect, m_bgColor);
445 triangle(m_left + quarterWidth, m_top, m_right - quarterWidth, m_top, m_ left + halfWidth, m_bottom, m_fgColor);
446 break;
447
448 default:
449 BLINK_ASSERT_NOT_REACHED();
450 break;
451 }
452
453 markState();
454 }
455
456 // Because rendering a text field is dependent on input
457 // parameters the other controls don't have, we render it directly
458 // rather than trying to overcomplicate draw() further.
459 void WebTestThemeControlWin::drawTextField(bool drawEdges, bool fillContentArea, SkColor color)
460 {
461 SkPaint paint;
462
463 if (fillContentArea) {
464 paint.setColor(color);
465 paint.setStyle(SkPaint::kFill_Style);
466 m_canvas->drawIRect(m_irect, paint);
467 }
468 if (drawEdges) {
469 paint.setColor(m_edgeColor);
470 paint.setStyle(SkPaint::kStroke_Style);
471 m_canvas->drawIRect(m_irect, paint);
472 }
473
474 markState();
475 }
476
477 void WebTestThemeControlWin::drawProgressBar(const SkIRect& fillRect)
478 {
479 SkPaint paint;
480
481 paint.setColor(m_bgColor);
482 paint.setStyle(SkPaint::kFill_Style);
483 m_canvas->drawIRect(m_irect, paint);
484
485 // Emulate clipping
486 SkIRect tofill;
487 tofill.intersect(m_irect, fillRect);
488 paint.setColor(m_fgColor);
489 paint.setStyle(SkPaint::kFill_Style);
490 m_canvas->drawIRect(tofill, paint);
491
492 markState();
493 }
494
495 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698