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

Side by Side Diff: third_party/WebKit/Source/core/paint/ObjectPainter.cpp

Issue 2404583002: Fix integer overflow in ObjectPainter and divide by zero in Color. (Closed)
Patch Set: Fix two typos converting to saturated. Created 4 years, 2 months 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/platform/graphics/Color.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "core/paint/ObjectPainter.h" 5 #include "core/paint/ObjectPainter.h"
6 6
7 #include "core/layout/LayoutBlock.h" 7 #include "core/layout/LayoutBlock.h"
8 #include "core/layout/LayoutInline.h" 8 #include "core/layout/LayoutInline.h"
9 #include "core/layout/LayoutObject.h" 9 #include "core/layout/LayoutObject.h"
10 #include "core/layout/LayoutTheme.h" 10 #include "core/layout/LayoutTheme.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 // - needs a positive adjacent joint width (required by drawLineForBoxSide). 53 // - needs a positive adjacent joint width (required by drawLineForBoxSide).
54 // A counterclockwise joint: 54 // A counterclockwise joint:
55 // - needs to increase the edge length to include the joint; 55 // - needs to increase the edge length to include the joint;
56 // - needs a negative adjacent joint width (required by drawLineForBoxSide). 56 // - needs a negative adjacent joint width (required by drawLineForBoxSide).
57 switch (edge1.side) { 57 switch (edge1.side) {
58 case BSTop: 58 case BSTop:
59 switch (edge2.side) { 59 switch (edge2.side) {
60 case BSRight: // Clockwise 60 case BSRight: // Clockwise
61 return outlineWidth; 61 return outlineWidth;
62 case BSLeft: // Counterclockwise 62 case BSLeft: // Counterclockwise
63 edge1.x2 += outlineWidth; 63 edge1.x2 = saturatedAddition(edge1.x2, outlineWidth);
64 edge2.y2 += outlineWidth; 64 edge2.y2 = saturatedAddition(edge2.y2, outlineWidth);
65 return -outlineWidth; 65 return -outlineWidth;
66 default: // Same side or no joint. 66 default: // Same side or no joint.
67 return 0; 67 return 0;
68 } 68 }
69 case BSRight: 69 case BSRight:
70 switch (edge2.side) { 70 switch (edge2.side) {
71 case BSBottom: // Clockwise 71 case BSBottom: // Clockwise
72 return outlineWidth; 72 return outlineWidth;
73 case BSTop: // Counterclockwise 73 case BSTop: // Counterclockwise
74 edge1.y2 += outlineWidth; 74 edge1.y2 = saturatedAddition(edge1.y2, outlineWidth);
75 edge2.x1 -= outlineWidth; 75 edge2.x1 = saturatedSubtraction(edge2.x1, outlineWidth);
76 return -outlineWidth; 76 return -outlineWidth;
77 default: // Same side or no joint. 77 default: // Same side or no joint.
78 return 0; 78 return 0;
79 } 79 }
80 case BSBottom: 80 case BSBottom:
81 switch (edge2.side) { 81 switch (edge2.side) {
82 case BSLeft: // Clockwise 82 case BSLeft: // Clockwise
83 return outlineWidth; 83 return outlineWidth;
84 case BSRight: // Counterclockwise 84 case BSRight: // Counterclockwise
85 edge1.x1 -= outlineWidth; 85 edge1.x1 = saturatedSubtraction(edge1.x1, outlineWidth);
86 edge2.y1 -= outlineWidth; 86 edge2.y1 = saturatedSubtraction(edge2.y1, outlineWidth);
87 return -outlineWidth; 87 return -outlineWidth;
88 default: // Same side or no joint. 88 default: // Same side or no joint.
89 return 0; 89 return 0;
90 } 90 }
91 case BSLeft: 91 case BSLeft:
92 switch (edge2.side) { 92 switch (edge2.side) {
93 case BSTop: // Clockwise 93 case BSTop: // Clockwise
94 return outlineWidth; 94 return outlineWidth;
95 case BSBottom: // Counterclockwise 95 case BSBottom: // Counterclockwise
96 edge1.y1 -= outlineWidth; 96 edge1.y1 = saturatedSubtraction(edge1.y1, outlineWidth);
97 edge2.x2 += outlineWidth; 97 edge2.x2 = saturatedAddition(edge2.x2, outlineWidth);
98 return -outlineWidth; 98 return -outlineWidth;
99 default: // Same side or no joint. 99 default: // Same side or no joint.
100 return 0; 100 return 0;
101 } 101 }
102 default: 102 default:
103 ASSERT_NOT_REACHED(); 103 ASSERT_NOT_REACHED();
104 return 0; 104 return 0;
105 } 105 }
106 } 106 }
107 107
(...skipping 27 matching lines...) Expand all
135 continue; 135 continue;
136 136
137 edges.grow(++count); 137 edges.grow(++count);
138 OutlineEdgeInfo& edge = edges.last(); 138 OutlineEdgeInfo& edge = edges.last();
139 edge.x1 = SkScalarTruncToInt(points[0].x()); 139 edge.x1 = SkScalarTruncToInt(points[0].x());
140 edge.y1 = SkScalarTruncToInt(points[0].y()); 140 edge.y1 = SkScalarTruncToInt(points[0].y());
141 edge.x2 = SkScalarTruncToInt(points[1].x()); 141 edge.x2 = SkScalarTruncToInt(points[1].x());
142 edge.y2 = SkScalarTruncToInt(points[1].y()); 142 edge.y2 = SkScalarTruncToInt(points[1].y());
143 if (edge.x1 == edge.x2) { 143 if (edge.x1 == edge.x2) {
144 if (edge.y1 < edge.y2) { 144 if (edge.y1 < edge.y2) {
145 edge.x1 -= width; 145 edge.x1 = saturatedSubtraction(edge.x1, width);
146 edge.side = BSRight; 146 edge.side = BSRight;
147 } else { 147 } else {
148 std::swap(edge.y1, edge.y2); 148 std::swap(edge.y1, edge.y2);
149 edge.x2 += width; 149 edge.x2 = saturatedAddition(edge.x2, width);
150 edge.side = BSLeft; 150 edge.side = BSLeft;
151 } 151 }
152 } else { 152 } else {
153 ASSERT(edge.y1 == edge.y2); 153 ASSERT(edge.y1 == edge.y2);
154 if (edge.x1 < edge.x2) { 154 if (edge.x1 < edge.x2) {
155 edge.y2 += width; 155 edge.y2 = saturatedAddition(edge.y2, width);
156 edge.side = BSTop; 156 edge.side = BSTop;
157 } else { 157 } else {
158 std::swap(edge.x1, edge.x2); 158 std::swap(edge.x1, edge.x2);
159 edge.y1 -= width; 159 edge.y1 = saturatedSubtraction(edge.y1, width);
160 edge.side = BSBottom; 160 edge.side = BSBottom;
161 } 161 }
162 } 162 }
163 } 163 }
164 164
165 if (!count) 165 if (!count)
166 return; 166 return;
167 167
168 Color outlineColor = color; 168 Color outlineColor = color;
169 bool useTransparencyLayer = color.hasAlpha(); 169 bool useTransparencyLayer = color.hasAlpha();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 path.lineTo(quad[1]); 208 path.lineTo(quad[1]);
209 path.lineTo(quad[2]); 209 path.lineTo(quad[2]);
210 path.lineTo(quad[3]); 210 path.lineTo(quad[3]);
211 SkPaint paint(context.fillPaint()); 211 SkPaint paint(context.fillPaint());
212 paint.setAntiAlias(antialias); 212 paint.setAntiAlias(antialias);
213 paint.setColor(color.rgb()); 213 paint.setColor(color.rgb());
214 214
215 context.drawPath(path, paint); 215 context.drawPath(path, paint);
216 } 216 }
217 217
218 int thirdOfDouble(int width) {
219 return std::max((width * 2 + 1) / 3, 0);
220 }
221
218 } // namespace 222 } // namespace
219 223
220 void ObjectPainter::paintOutline(const PaintInfo& paintInfo, 224 void ObjectPainter::paintOutline(const PaintInfo& paintInfo,
221 const LayoutPoint& paintOffset) { 225 const LayoutPoint& paintOffset) {
222 ASSERT(shouldPaintSelfOutline(paintInfo.phase)); 226 ASSERT(shouldPaintSelfOutline(paintInfo.phase));
223 227
224 const ComputedStyle& styleToUse = m_layoutObject.styleRef(); 228 const ComputedStyle& styleToUse = m_layoutObject.styleRef();
225 if (!styleToUse.hasOutline() || 229 if (!styleToUse.hasOutline() ||
226 styleToUse.visibility() != EVisibility::Visible) 230 styleToUse.visibility() != EVisibility::Visible)
227 return; 231 return;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 int y2, 347 int y2,
344 BoxSide side, 348 BoxSide side,
345 Color color, 349 Color color,
346 EBorderStyle style, 350 EBorderStyle style,
347 int adjacentWidth1, 351 int adjacentWidth1,
348 int adjacentWidth2, 352 int adjacentWidth2,
349 bool antialias) { 353 bool antialias) {
350 int thickness; 354 int thickness;
351 int length; 355 int length;
352 if (side == BSTop || side == BSBottom) { 356 if (side == BSTop || side == BSBottom) {
353 thickness = y2 - y1; 357 thickness = saturatedSubtraction(y2, y1);
354 length = x2 - x1; 358 length = saturatedSubtraction(x2, x1);
355 } else { 359 } else {
356 thickness = x2 - x1; 360 thickness = saturatedSubtraction(x2, x1);
357 length = y2 - y1; 361 length = saturatedSubtraction(y2, y1);
358 } 362 }
359 363
360 // We would like this check to be an ASSERT as we don't want to draw empty 364 // We would like this check to be an ASSERT as we don't want to draw empty
361 // borders. However nothing guarantees that the following recursive calls to 365 // borders. However nothing guarantees that the following recursive calls to
362 // drawLineForBoxSide will have positive thickness and length. 366 // drawLineForBoxSide will have positive thickness and length.
363 if (length <= 0 || thickness <= 0) 367 if (length <= 0 || thickness <= 0)
364 return; 368 return;
365 369
366 if (style == BorderStyleDouble && thickness < 3) 370 if (style == BorderStyleDouble && thickness < 3)
367 style = BorderStyleSolid; 371 style = BorderStyleSolid;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 StrokeStyle oldStrokeStyle = graphicsContext.getStrokeStyle(); 422 StrokeStyle oldStrokeStyle = graphicsContext.getStrokeStyle();
419 graphicsContext.setShouldAntialias(antialias); 423 graphicsContext.setShouldAntialias(antialias);
420 graphicsContext.setStrokeColor(color); 424 graphicsContext.setStrokeColor(color);
421 graphicsContext.setStrokeThickness(thickness); 425 graphicsContext.setStrokeThickness(thickness);
422 graphicsContext.setStrokeStyle(style == BorderStyleDashed ? DashedStroke 426 graphicsContext.setStrokeStyle(style == BorderStyleDashed ? DashedStroke
423 : DottedStroke); 427 : DottedStroke);
424 428
425 switch (side) { 429 switch (side) {
426 case BSBottom: 430 case BSBottom:
427 case BSTop: { 431 case BSTop: {
428 int midY = y1 + thickness / 2; 432 int midY = saturatedAddition(y1, thickness / 2);
429 graphicsContext.drawLine(IntPoint(x1, midY), IntPoint(x2, midY)); 433 graphicsContext.drawLine(IntPoint(x1, midY), IntPoint(x2, midY));
430 break; 434 break;
431 } 435 }
432 case BSRight: 436 case BSRight:
433 case BSLeft: { 437 case BSLeft: {
434 int midX = x1 + thickness / 2; 438 int midX = saturatedAddition(x1, thickness / 2);
435 graphicsContext.drawLine(IntPoint(midX, y1), IntPoint(midX, y2)); 439 graphicsContext.drawLine(IntPoint(midX, y1), IntPoint(midX, y2));
436 break; 440 break;
437 } 441 }
438 } 442 }
439 graphicsContext.setShouldAntialias(wasAntialiased); 443 graphicsContext.setShouldAntialias(wasAntialiased);
440 graphicsContext.setStrokeStyle(oldStrokeStyle); 444 graphicsContext.setStrokeStyle(oldStrokeStyle);
441 } 445 }
442 446
443 void ObjectPainter::drawDoubleBoxSide(GraphicsContext& graphicsContext, 447 void ObjectPainter::drawDoubleBoxSide(GraphicsContext& graphicsContext,
444 int x1, 448 int x1,
445 int y1, 449 int y1,
446 int x2, 450 int x2,
447 int y2, 451 int y2,
448 int length, 452 int length,
449 BoxSide side, 453 BoxSide side,
450 Color color, 454 Color color,
451 int thickness, 455 int thickness,
452 int adjacentWidth1, 456 int adjacentWidth1,
453 int adjacentWidth2, 457 int adjacentWidth2,
454 bool antialias) { 458 bool antialias) {
455 int thirdOfThickness = (thickness + 1) / 3; 459 int thirdOfThickness = saturatedAddition(thickness, 1) / 3;
456 ASSERT(thirdOfThickness > 0); 460 ASSERT(thirdOfThickness > 0);
457 461
458 if (!adjacentWidth1 && !adjacentWidth2) { 462 if (!adjacentWidth1 && !adjacentWidth2) {
459 StrokeStyle oldStrokeStyle = graphicsContext.getStrokeStyle(); 463 StrokeStyle oldStrokeStyle = graphicsContext.getStrokeStyle();
460 graphicsContext.setStrokeStyle(NoStroke); 464 graphicsContext.setStrokeStyle(NoStroke);
461 graphicsContext.setFillColor(color); 465 graphicsContext.setFillColor(color);
462 466
463 bool wasAntialiased = graphicsContext.shouldAntialias(); 467 bool wasAntialiased = graphicsContext.shouldAntialias();
464 graphicsContext.setShouldAntialias(antialias); 468 graphicsContext.setShouldAntialias(antialias);
465 469
466 switch (side) { 470 switch (side) {
467 case BSTop: 471 case BSTop:
468 case BSBottom: 472 case BSBottom:
469 graphicsContext.drawRect(IntRect(x1, y1, length, thirdOfThickness)); 473 graphicsContext.drawRect(IntRect(x1, y1, length, thirdOfThickness));
470 graphicsContext.drawRect( 474 graphicsContext.drawRect(
471 IntRect(x1, y2 - thirdOfThickness, length, thirdOfThickness)); 475 IntRect(x1, saturatedSubtraction(y2, thirdOfThickness), length,
476 thirdOfThickness));
472 break; 477 break;
473 case BSLeft: 478 case BSLeft:
474 case BSRight: 479 case BSRight:
475 graphicsContext.drawRect(IntRect(x1, y1, thirdOfThickness, length)); 480 graphicsContext.drawRect(IntRect(x1, y1, thirdOfThickness, length));
476 graphicsContext.drawRect( 481 graphicsContext.drawRect(
477 IntRect(x2 - thirdOfThickness, y1, thirdOfThickness, length)); 482 IntRect(saturatedSubtraction(x2, thirdOfThickness), y1,
483 thirdOfThickness, length));
478 break; 484 break;
479 } 485 }
480 486
481 graphicsContext.setShouldAntialias(wasAntialiased); 487 graphicsContext.setShouldAntialias(wasAntialiased);
482 graphicsContext.setStrokeStyle(oldStrokeStyle); 488 graphicsContext.setStrokeStyle(oldStrokeStyle);
483 return; 489 return;
484 } 490 }
485 491
486 int adjacent1BigThird = 492 int adjacent1BigThird =
487 ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 3; 493 ((adjacentWidth1 > 0) ? saturatedAddition(adjacentWidth1, 1)
494 : saturatedSubtraction(adjacentWidth1, 1)) /
495 3;
488 int adjacent2BigThird = 496 int adjacent2BigThird =
489 ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 3; 497 ((adjacentWidth2 > 0) ? saturatedAddition(adjacentWidth2, 1)
498 : saturatedSubtraction(adjacentWidth2, 1)) /
499 3;
490 500
491 switch (side) { 501 switch (side) {
492 case BSTop: 502 case BSTop:
493 drawLineForBoxSide(graphicsContext,
494 x1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), y1,
495 x2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0),
496 y1 + thirdOfThickness, side, color, BorderStyleSolid,
497 adjacent1BigThird, adjacent2BigThird, antialias);
498 drawLineForBoxSide( 503 drawLineForBoxSide(
499 graphicsContext, x1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), 504 graphicsContext,
500 y2 - thirdOfThickness, x2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), 505 saturatedAddition(x1, thirdOfDouble(-adjacentWidth1)), y1,
501 y2, side, color, BorderStyleSolid, adjacent1BigThird, 506 saturatedSubtraction(x2, thirdOfDouble(-adjacentWidth2)),
502 adjacent2BigThird, antialias); 507 saturatedAddition(y1, thirdOfThickness), side, color,
508 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias);
509 drawLineForBoxSide(
510 graphicsContext, saturatedAddition(x1, thirdOfDouble(adjacentWidth1)),
511 saturatedSubtraction(y2, thirdOfThickness),
512 saturatedSubtraction(x2, thirdOfDouble(adjacentWidth2)), y2, side,
513 color, BorderStyleSolid, adjacent1BigThird, adjacent2BigThird,
514 antialias);
503 break; 515 break;
504 case BSLeft: 516 case BSLeft:
505 drawLineForBoxSide( 517 drawLineForBoxSide(
506 graphicsContext, x1, y1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), 518 graphicsContext, x1,
507 x1 + thirdOfThickness, 519 saturatedAddition(y1, thirdOfDouble(-adjacentWidth1)),
508 y2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), side, color, 520 saturatedAddition(x1, thirdOfThickness),
521 saturatedSubtraction(y2, thirdOfDouble(-adjacentWidth2)), side, color,
509 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias); 522 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias);
510 drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, 523 drawLineForBoxSide(
511 y1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), x2, 524 graphicsContext, saturatedSubtraction(x2, thirdOfThickness),
512 y2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), side, 525 saturatedAddition(y1, thirdOfDouble(adjacentWidth1)), x2,
513 color, BorderStyleSolid, adjacent1BigThird, 526 saturatedSubtraction(y2, thirdOfDouble(adjacentWidth2)), side, color,
514 adjacent2BigThird, antialias); 527 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias);
515 break; 528 break;
516 case BSBottom: 529 case BSBottom:
517 drawLineForBoxSide(graphicsContext,
518 x1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), y1,
519 x2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0),
520 y1 + thirdOfThickness, side, color, BorderStyleSolid,
521 adjacent1BigThird, adjacent2BigThird, antialias);
522 drawLineForBoxSide( 530 drawLineForBoxSide(
523 graphicsContext, x1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), 531 graphicsContext, saturatedAddition(x1, thirdOfDouble(adjacentWidth1)),
524 y2 - thirdOfThickness, 532 y1, saturatedSubtraction(x2, thirdOfDouble(adjacentWidth2)),
525 x2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), y2, side, color, 533 saturatedAddition(y1, thirdOfThickness), side, color,
526 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias); 534 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias);
535 drawLineForBoxSide(
536 graphicsContext,
537 saturatedAddition(x1, thirdOfDouble(-adjacentWidth1)),
538 saturatedSubtraction(y2, thirdOfThickness),
539 saturatedSubtraction(x2, thirdOfDouble(-adjacentWidth2)), y2, side,
540 color, BorderStyleSolid, adjacent1BigThird, adjacent2BigThird,
541 antialias);
527 break; 542 break;
528 case BSRight: 543 case BSRight:
529 drawLineForBoxSide( 544 drawLineForBoxSide(
530 graphicsContext, x1, y1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), 545 graphicsContext, x1,
531 x1 + thirdOfThickness, y2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), 546 saturatedAddition(y1, thirdOfDouble(adjacentWidth1)),
532 side, color, BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, 547 saturatedAddition(x1, thirdOfThickness),
533 antialias); 548 saturatedSubtraction(y2, thirdOfDouble(adjacentWidth2)), side, color,
534 drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, 549 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias);
535 y1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), x2, 550 drawLineForBoxSide(
536 y2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), side, 551 graphicsContext, saturatedSubtraction(x2, thirdOfThickness),
537 color, BorderStyleSolid, adjacent1BigThird, 552 saturatedAddition(y1, thirdOfDouble(-adjacentWidth1)), x2,
538 adjacent2BigThird, antialias); 553 saturatedSubtraction(y2, thirdOfDouble(-adjacentWidth2)), side, color,
554 BorderStyleSolid, adjacent1BigThird, adjacent2BigThird, antialias);
539 break; 555 break;
540 default: 556 default:
541 break; 557 break;
542 } 558 }
543 } 559 }
544 560
545 void ObjectPainter::drawRidgeOrGrooveBoxSide(GraphicsContext& graphicsContext, 561 void ObjectPainter::drawRidgeOrGrooveBoxSide(GraphicsContext& graphicsContext,
546 int x1, 562 int x1,
547 int y1, 563 int y1,
548 int x2, 564 int x2,
549 int y2, 565 int y2,
550 BoxSide side, 566 BoxSide side,
551 Color color, 567 Color color,
552 EBorderStyle style, 568 EBorderStyle style,
553 int adjacentWidth1, 569 int adjacentWidth1,
554 int adjacentWidth2, 570 int adjacentWidth2,
555 bool antialias) { 571 bool antialias) {
556 EBorderStyle s1; 572 EBorderStyle s1;
557 EBorderStyle s2; 573 EBorderStyle s2;
558 if (style == BorderStyleGroove) { 574 if (style == BorderStyleGroove) {
559 s1 = BorderStyleInset; 575 s1 = BorderStyleInset;
560 s2 = BorderStyleOutset; 576 s2 = BorderStyleOutset;
561 } else { 577 } else {
562 s1 = BorderStyleOutset; 578 s1 = BorderStyleOutset;
563 s2 = BorderStyleInset; 579 s2 = BorderStyleInset;
564 } 580 }
565 581
566 int adjacent1BigHalf = 582 int adjacent1BigHalf =
567 ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 2; 583 ((adjacentWidth1 > 0) ? saturatedAddition(adjacentWidth1, 1)
584 : saturatedSubtraction(adjacentWidth1, 1)) /
585 2;
568 int adjacent2BigHalf = 586 int adjacent2BigHalf =
569 ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 2; 587 ((adjacentWidth2 > 0) ? saturatedAddition(adjacentWidth2, 1)
588 : saturatedSubtraction(adjacentWidth2, 1)) /
589 2;
570 590
571 switch (side) { 591 switch (side) {
572 case BSTop: 592 case BSTop:
573 drawLineForBoxSide(graphicsContext, x1 + std::max(-adjacentWidth1, 0) / 2,
574 y1, x2 - std::max(-adjacentWidth2, 0) / 2,
575 (y1 + y2 + 1) / 2, side, color, s1, adjacent1BigHalf,
576 adjacent2BigHalf, antialias);
577 drawLineForBoxSide( 593 drawLineForBoxSide(
578 graphicsContext, x1 + std::max(adjacentWidth1 + 1, 0) / 2, 594 graphicsContext,
579 (y1 + y2 + 1) / 2, x2 - std::max(adjacentWidth2 + 1, 0) / 2, y2, side, 595 saturatedAddition(x1, std::max(-adjacentWidth1, 0) / 2), y1,
580 color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); 596 saturatedSubtraction(x2, std::max(-adjacentWidth2, 0) / 2),
597 saturatedAddition(y1, saturatedAddition(y2, 1)) / 2, side, color, s1,
598 adjacent1BigHalf, adjacent2BigHalf, antialias);
599 drawLineForBoxSide(
600 graphicsContext,
601 saturatedAddition(
602 x1, std::max(saturatedAddition(adjacentWidth1, 1), 0) / 2),
603 saturatedAddition(y1, saturatedAddition(y2, 1)) / 2,
604 saturatedSubtraction(
605 x2, std::max(saturatedAddition(adjacentWidth2, 1), 0) / 2),
606 y2, side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2,
607 antialias);
581 break; 608 break;
582 case BSLeft: 609 case BSLeft:
583 drawLineForBoxSide( 610 drawLineForBoxSide(
584 graphicsContext, x1, y1 + std::max(-adjacentWidth1, 0) / 2, 611 graphicsContext, x1,
585 (x1 + x2 + 1) / 2, y2 - std::max(-adjacentWidth2, 0) / 2, side, color, 612 saturatedAddition(y1, std::max(-adjacentWidth1, 0) / 2),
586 s1, adjacent1BigHalf, adjacent2BigHalf, antialias); 613 saturatedAddition(x1, saturatedAddition(x2, 1)) / 2,
587 drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, 614 saturatedSubtraction(y2, std::max(-adjacentWidth2, 0) / 2), side,
588 y1 + std::max(adjacentWidth1 + 1, 0) / 2, x2, 615 color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
589 y2 - std::max(adjacentWidth2 + 1, 0) / 2, side, color, 616 drawLineForBoxSide(
590 s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); 617 graphicsContext, saturatedAddition(x1, saturatedAddition(x2, 1)) / 2,
618 saturatedAddition(
619 y1, std::max(saturatedAddition(adjacentWidth1, 1), 0) / 2),
620 x2, saturatedSubtraction(
621 y2, std::max(saturatedAddition(adjacentWidth2, 1), 0) / 2),
622 side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
591 break; 623 break;
592 case BSBottom: 624 case BSBottom:
593 drawLineForBoxSide(graphicsContext, x1 + std::max(adjacentWidth1, 0) / 2,
594 y1, x2 - std::max(adjacentWidth2, 0) / 2,
595 (y1 + y2 + 1) / 2, side, color, s2, adjacent1BigHalf,
596 adjacent2BigHalf, antialias);
597 drawLineForBoxSide( 625 drawLineForBoxSide(
598 graphicsContext, x1 + std::max(-adjacentWidth1 + 1, 0) / 2, 626 graphicsContext,
599 (y1 + y2 + 1) / 2, x2 - std::max(-adjacentWidth2 + 1, 0) / 2, y2, 627 saturatedAddition(x1, std::max(adjacentWidth1, 0) / 2), y1,
600 side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); 628 saturatedSubtraction(x2, std::max(adjacentWidth2, 0) / 2),
629 saturatedAddition(y1, saturatedAddition(y2, 1)) / 2, side, color, s2,
630 adjacent1BigHalf, adjacent2BigHalf, antialias);
631 drawLineForBoxSide(
632 graphicsContext,
633 saturatedAddition(
634 x1, std::max(saturatedAddition(-adjacentWidth1, 1), 0) / 2),
635 saturatedAddition(y1, saturatedAddition(y2, 1)) / 2,
636 saturatedSubtraction(
637 x2, std::max(saturatedAddition(-adjacentWidth2, 1), 0) / 2),
638 y2, side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2,
639 antialias);
601 break; 640 break;
602 case BSRight: 641 case BSRight:
603 drawLineForBoxSide( 642 drawLineForBoxSide(
604 graphicsContext, x1, y1 + std::max(adjacentWidth1, 0) / 2, 643 graphicsContext, x1,
605 (x1 + x2 + 1) / 2, y2 - std::max(adjacentWidth2, 0) / 2, side, color, 644 saturatedAddition(y1, std::max(adjacentWidth1, 0) / 2),
606 s2, adjacent1BigHalf, adjacent2BigHalf, antialias); 645 saturatedAddition(x1, saturatedAddition(x2, 1)) / 2,
607 drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, 646 saturatedSubtraction(y2, std::max(adjacentWidth2, 0) / 2), side,
608 y1 + std::max(-adjacentWidth1 + 1, 0) / 2, x2, 647 color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
609 y2 - std::max(-adjacentWidth2 + 1, 0) / 2, side, color, 648 drawLineForBoxSide(
610 s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); 649 graphicsContext, saturatedAddition(x1, saturatedAddition(x2, 1)) / 2,
650 saturatedAddition(
651 y1, std::max(saturatedAddition(-adjacentWidth1, 1), 0) / 2),
652 x2, saturatedSubtraction(
653 y2, std::max(saturatedAddition(-adjacentWidth2, 1), 0) / 2),
654 side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
611 break; 655 break;
612 } 656 }
613 } 657 }
614 658
615 void ObjectPainter::drawSolidBoxSide(GraphicsContext& graphicsContext, 659 void ObjectPainter::drawSolidBoxSide(GraphicsContext& graphicsContext,
616 int x1, 660 int x1,
617 int y1, 661 int y1,
618 int x2, 662 int x2,
619 int y2, 663 int y2,
620 BoxSide side, 664 BoxSide side,
621 Color color, 665 Color color,
622 int adjacentWidth1, 666 int adjacentWidth1,
623 int adjacentWidth2, 667 int adjacentWidth2,
624 bool antialias) { 668 bool antialias) {
625 ASSERT(x2 >= x1); 669 ASSERT(x2 >= x1);
626 ASSERT(y2 >= y1); 670 ASSERT(y2 >= y1);
627 671
628 if (!adjacentWidth1 && !adjacentWidth2) { 672 if (!adjacentWidth1 && !adjacentWidth2) {
629 // Tweak antialiasing to match the behavior of fillQuad(); 673 // Tweak antialiasing to match the behavior of fillQuad();
630 // this matters for rects in transformed contexts. 674 // this matters for rects in transformed contexts.
631 bool wasAntialiased = graphicsContext.shouldAntialias(); 675 bool wasAntialiased = graphicsContext.shouldAntialias();
632 if (antialias != wasAntialiased) 676 if (antialias != wasAntialiased)
633 graphicsContext.setShouldAntialias(antialias); 677 graphicsContext.setShouldAntialias(antialias);
634 graphicsContext.fillRect(IntRect(x1, y1, x2 - x1, y2 - y1), color); 678 graphicsContext.fillRect(IntRect(x1, y1, saturatedSubtraction(x2, x1),
679 saturatedSubtraction(y2, y1)),
680 color);
635 if (antialias != wasAntialiased) 681 if (antialias != wasAntialiased)
636 graphicsContext.setShouldAntialias(wasAntialiased); 682 graphicsContext.setShouldAntialias(wasAntialiased);
637 return; 683 return;
638 } 684 }
639 685
640 FloatPoint quad[4]; 686 FloatPoint quad[4];
641 switch (side) { 687 switch (side) {
642 case BSTop: 688 case BSTop:
643 quad[0] = FloatPoint(x1 + std::max(-adjacentWidth1, 0), y1); 689 quad[0] =
644 quad[1] = FloatPoint(x1 + std::max(adjacentWidth1, 0), y2); 690 FloatPoint(saturatedAddition(x1, std::max(-adjacentWidth1, 0)), y1);
645 quad[2] = FloatPoint(x2 - std::max(adjacentWidth2, 0), y2); 691 quad[1] =
646 quad[3] = FloatPoint(x2 - std::max(-adjacentWidth2, 0), y1); 692 FloatPoint(saturatedAddition(x1, std::max(adjacentWidth1, 0)), y2);
693 quad[2] =
694 FloatPoint(saturatedSubtraction(x2, std::max(adjacentWidth2, 0)), y2);
695 quad[3] = FloatPoint(
696 saturatedSubtraction(x2, std::max(-adjacentWidth2, 0)), y1);
647 break; 697 break;
648 case BSBottom: 698 case BSBottom:
649 quad[0] = FloatPoint(x1 + std::max(adjacentWidth1, 0), y1); 699 quad[0] =
650 quad[1] = FloatPoint(x1 + std::max(-adjacentWidth1, 0), y2); 700 FloatPoint(saturatedAddition(x1, std::max(adjacentWidth1, 0)), y1);
651 quad[2] = FloatPoint(x2 - std::max(-adjacentWidth2, 0), y2); 701 quad[1] =
652 quad[3] = FloatPoint(x2 - std::max(adjacentWidth2, 0), y1); 702 FloatPoint(saturatedAddition(x1, std::max(-adjacentWidth1, 0)), y2);
703 quad[2] = FloatPoint(
704 saturatedSubtraction(x2, std::max(-adjacentWidth2, 0)), y2);
705 quad[3] =
706 FloatPoint(saturatedSubtraction(x2, std::max(adjacentWidth2, 0)), y1);
653 break; 707 break;
654 case BSLeft: 708 case BSLeft:
655 quad[0] = FloatPoint(x1, y1 + std::max(-adjacentWidth1, 0)); 709 quad[0] =
656 quad[1] = FloatPoint(x1, y2 - std::max(-adjacentWidth2, 0)); 710 FloatPoint(x1, saturatedAddition(y1, std::max(-adjacentWidth1, 0)));
657 quad[2] = FloatPoint(x2, y2 - std::max(adjacentWidth2, 0)); 711 quad[1] = FloatPoint(
658 quad[3] = FloatPoint(x2, y1 + std::max(adjacentWidth1, 0)); 712 x1, saturatedSubtraction(y2, std::max(-adjacentWidth2, 0)));
713 quad[2] =
714 FloatPoint(x2, saturatedSubtraction(y2, std::max(adjacentWidth2, 0)));
715 quad[3] =
716 FloatPoint(x2, saturatedAddition(y1, std::max(adjacentWidth1, 0)));
659 break; 717 break;
660 case BSRight: 718 case BSRight:
661 quad[0] = FloatPoint(x1, y1 + std::max(adjacentWidth1, 0)); 719 quad[0] =
662 quad[1] = FloatPoint(x1, y2 - std::max(adjacentWidth2, 0)); 720 FloatPoint(x1, saturatedAddition(y1, std::max(adjacentWidth1, 0)));
663 quad[2] = FloatPoint(x2, y2 - std::max(-adjacentWidth2, 0)); 721 quad[1] =
664 quad[3] = FloatPoint(x2, y1 + std::max(-adjacentWidth1, 0)); 722 FloatPoint(x1, saturatedSubtraction(y2, std::max(adjacentWidth2, 0)));
723 quad[2] = FloatPoint(
724 x2, saturatedSubtraction(y2, std::max(-adjacentWidth2, 0)));
725 quad[3] =
726 FloatPoint(x2, saturatedAddition(y1, std::max(-adjacentWidth1, 0)));
665 break; 727 break;
666 } 728 }
667 729
668 fillQuad(graphicsContext, quad, color, antialias); 730 fillQuad(graphicsContext, quad, color, antialias);
669 } 731 }
670 732
671 void ObjectPainter::paintAllPhasesAtomically(const PaintInfo& paintInfo, 733 void ObjectPainter::paintAllPhasesAtomically(const PaintInfo& paintInfo,
672 const LayoutPoint& paintOffset) { 734 const LayoutPoint& paintOffset) {
673 // Pass PaintPhaseSelection and PaintPhaseTextClip to the descendants so that 735 // Pass PaintPhaseSelection and PaintPhaseTextClip to the descendants so that
674 // they will paint for selection and text clip respectively. We don't need 736 // they will paint for selection and text clip respectively. We don't need
(...skipping 12 matching lines...) Expand all
687 m_layoutObject.paint(info, paintOffset); 749 m_layoutObject.paint(info, paintOffset);
688 info.phase = PaintPhaseFloat; 750 info.phase = PaintPhaseFloat;
689 m_layoutObject.paint(info, paintOffset); 751 m_layoutObject.paint(info, paintOffset);
690 info.phase = PaintPhaseForeground; 752 info.phase = PaintPhaseForeground;
691 m_layoutObject.paint(info, paintOffset); 753 m_layoutObject.paint(info, paintOffset);
692 info.phase = PaintPhaseOutline; 754 info.phase = PaintPhaseOutline;
693 m_layoutObject.paint(info, paintOffset); 755 m_layoutObject.paint(info, paintOffset);
694 } 756 }
695 757
696 } // namespace blink 758 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/platform/graphics/Color.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698