Diff
Modified: trunk/Source/WebCore/ChangeLog (207001 => 207002)
--- trunk/Source/WebCore/ChangeLog 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/ChangeLog 2016-10-10 17:02:52 UTC (rev 207002)
@@ -1,3 +1,28 @@
+2016-10-10 Brent Fulgham <[email protected]>
+
+ Reduce code duplication between CG, Cairo, and Direct2D
+ https://bugs.webkit.org/show_bug.cgi?id=163157
+
+ Reviewed by Darin Adler.
+
+ Move a number of routines that have been copied-and-pasted to different
+ platform files into the main GraphicsContext.cpp file.
+
+ No new tests because there is no change in behavior.
+
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::dashedLineCornerWidthForStrokeWidth): Added.
+ (WebCore::GraphicsContext::dashedLinePatternWidthForStrokeWidth): Added.
+ (WebCore::GraphicsContext::dashedLinePatternOffsetForPatternAndStrokeWidth): Added.
+ (WebCore::GraphicsContext::centerLineAndCutOffCorners): Added.
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::drawLine): Call new helper function.
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ (WebCore::GraphicsContext::drawLine): Ditto.
+ * platform/graphics/win/GraphicsContextDirect2D.cpp:
+ (WebCore::GraphicsContext::drawLine): Ditto.
+
2016-10-10 Carlos Garcia Campos <[email protected]>
REGRESSION(r206731): [SOUP] Network process crash in gotHeadersCallback
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (207001 => 207002)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp 2016-10-10 17:02:52 UTC (rev 207002)
@@ -1126,4 +1126,55 @@
setPlatformShouldSmoothFonts(state.shouldSmoothFonts);
}
+float GraphicsContext::dashedLineCornerWidthForStrokeWidth(float strokeWidth) const
+{
+ float thickness = strokeThickness();
+ return strokeStyle() == DottedStroke ? thickness : std::min(2.0f * thickness, std::max(thickness, strokeWidth / 3.0f));
}
+
+float GraphicsContext::dashedLinePatternWidthForStrokeWidth(float strokeWidth) const
+{
+ float thickness = strokeThickness();
+ return strokeStyle() == DottedStroke ? thickness : std::min(3.0f * thickness, std::max(thickness, strokeWidth / 3.0f));
+}
+
+float GraphicsContext::dashedLinePatternOffsetForPatternAndStrokeWidth(float patternWidth, float strokeWidth) const
+{
+ // Pattern starts with full fill and ends with the empty fill.
+ // 1. Let's start with the empty phase after the corner.
+ // 2. Check if we've got odd or even number of patterns and whether they fully cover the line.
+ // 3. In case of even number of patterns and/or remainder, move the pattern start position
+ // so that the pattern is balanced between the corners.
+ float patternOffset = patternWidth;
+ int numberOfSegments = std::floor(strokeWidth / patternWidth);
+ bool oddNumberOfSegments = numberOfSegments % 2;
+ float remainder = strokeWidth - (numberOfSegments * patternWidth);
+ if (oddNumberOfSegments && remainder)
+ patternOffset -= remainder / 2.0f;
+ else if (!oddNumberOfSegments) {
+ if (remainder)
+ patternOffset += patternOffset - (patternWidth + remainder) / 2.0f;
+ else
+ patternOffset += patternWidth / 2.0f;
+ }
+
+ return patternOffset;
+}
+
+Vector<FloatPoint> GraphicsContext::centerLineAndCutOffCorners(bool isVerticalLine, float cornerWidth, FloatPoint point1, FloatPoint point2) const
+{
+ // Center line and cut off corners for pattern patining.
+ if (isVerticalLine) {
+ float centerOffset = (point2.x() - point1.x()) / 2.0f;
+ point1.move(centerOffset, cornerWidth);
+ point2.move(-centerOffset, -cornerWidth);
+ } else {
+ float centerOffset = (point2.y() - point1.y()) / 2.0f;
+ point1.move(cornerWidth, centerOffset);
+ point2.move(-cornerWidth, -centerOffset);
+ }
+
+ return { point1, point2 };
+}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (207001 => 207002)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h 2016-10-10 17:02:52 UTC (rev 207002)
@@ -618,6 +618,11 @@
FloatRect computeLineBoundsAndAntialiasingModeForText(const FloatPoint&, float width, bool printing, Color&);
+ float dashedLineCornerWidthForStrokeWidth(float) const;
+ float dashedLinePatternWidthForStrokeWidth(float) const;
+ float dashedLinePatternOffsetForPatternAndStrokeWidth(float patternWidth, float strokeWidth) const;
+ Vector<FloatPoint> centerLineAndCutOffCorners(bool isVerticalLine, float cornerWidth, FloatPoint point1, FloatPoint point2) const;
+
GraphicsContextPlatformPrivate* m_data { nullptr };
DisplayList::Recorder* m_displayListRecorder { nullptr };
Modified: trunk/Source/WebCore/platform/graphics/Pattern.h (207001 => 207002)
--- trunk/Source/WebCore/platform/graphics/Pattern.h 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/platform/graphics/Pattern.h 2016-10-10 17:02:52 UTC (rev 207002)
@@ -37,6 +37,8 @@
#if USE(CG)
typedef struct CGPattern* CGPatternRef;
typedef CGPatternRef PlatformPatternPtr;
+#elif USE(DIRECT2D)
+typedef void* PlatformPatternPtr;
#elif USE(CAIRO)
#include <cairo.h>
typedef cairo_pattern_t* PlatformPatternPtr;
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (207001 => 207002)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2016-10-10 17:02:52 UTC (rev 207002)
@@ -324,7 +324,7 @@
if (drawsDashedLine) {
cairo_save(cairoContext);
// Figure out end points to ensure we always paint corners.
- cornerWidth = strokeStyle == DottedStroke ? thickness : std::min(2 * thickness, std::max(thickness, strokeWidth / 3));
+ cornerWidth = dashedLineCornerWidthForStrokeWidth(strokeWidth);
if (isVerticalLine) {
fillRectWithColor(cairoContext, FloatRect(point1.x(), point1.y(), thickness, cornerWidth), strokeColor);
fillRectWithColor(cairoContext, FloatRect(point1.x(), point2.y() - cornerWidth, thickness, cornerWidth), strokeColor);
@@ -333,7 +333,7 @@
fillRectWithColor(cairoContext, FloatRect(point2.x() - cornerWidth, point1.y(), cornerWidth, thickness), strokeColor);
}
strokeWidth -= 2 * cornerWidth;
- float patternWidth = strokeStyle == DottedStroke ? thickness : std::min(3 * thickness, std::max(thickness, strokeWidth / 3));
+ float patternWidth = dashedLinePatternWidthForStrokeWidth(strokeWidth);
// Check if corner drawing sufficiently covers the line.
if (strokeWidth <= patternWidth + 1) {
cairo_restore(cairoContext);
@@ -340,23 +340,7 @@
return;
}
- // Pattern starts with full fill and ends with the empty fill.
- // 1. Let's start with the empty phase after the corner.
- // 2. Check if we've got odd or even number of patterns and whether they fully cover the line.
- // 3. In case of even number of patterns and/or remainder, move the pattern start position
- // so that the pattern is balanced between the corners.
- float patternOffset = patternWidth;
- int numberOfSegments = std::floor(strokeWidth / patternWidth);
- bool oddNumberOfSegments = numberOfSegments % 2;
- float remainder = strokeWidth - (numberOfSegments * patternWidth);
- if (oddNumberOfSegments && remainder)
- patternOffset -= remainder / 2.f;
- else if (!oddNumberOfSegments) {
- if (remainder)
- patternOffset += patternOffset - (patternWidth + remainder) / 2.f;
- else
- patternOffset += patternWidth / 2.f;
- }
+ float patternOffset = dashedLinePatternOffsetForPatternAndStrokeWidth(patternWidth, strokeWidth);
const double dashedLine[2] = { static_cast<double>(patternWidth), static_cast<double>(patternWidth) };
cairo_set_dash(cairoContext, dashedLine, 2, patternOffset);
} else {
@@ -366,18 +350,9 @@
}
- FloatPoint p1 = point1;
- FloatPoint p2 = point2;
- // Center line and cut off corners for pattern patining.
- if (isVerticalLine) {
- float centerOffset = (p2.x() - p1.x()) / 2;
- p1.move(centerOffset, cornerWidth);
- p2.move(-centerOffset, -cornerWidth);
- } else {
- float centerOffset = (p2.y() - p1.y()) / 2;
- p1.move(cornerWidth, centerOffset);
- p2.move(-cornerWidth, -centerOffset);
- }
+ auto centeredPoints = centerLineAndCutOffCorners(isVerticalLine, cornerWidth, point1, point2);
+ auto p1 = centeredPoints[0];
+ auto p2 = centeredPoints[1];
if (shouldAntialias())
cairo_set_antialias(cairoContext, CAIRO_ANTIALIAS_NONE);
Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (207001 => 207002)
--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp 2016-10-10 17:02:52 UTC (rev 207002)
@@ -470,7 +470,7 @@
CGContextStateSaver stateSaver(context, drawsDashedLine);
if (drawsDashedLine) {
// Figure out end points to ensure we always paint corners.
- cornerWidth = strokeStyle == DottedStroke ? thickness : std::min(2 * thickness, std::max(thickness, strokeWidth / 3));
+ cornerWidth = dashedLineCornerWidthForStrokeWidth(strokeWidth);
setCGFillColor(context, strokeColor());
if (isVerticalLine) {
CGContextFillRect(context, FloatRect(point1.x(), point1.y(), thickness, cornerWidth));
@@ -480,44 +480,19 @@
CGContextFillRect(context, FloatRect(point2.x() - cornerWidth, point1.y(), cornerWidth, thickness));
}
strokeWidth -= 2 * cornerWidth;
- float patternWidth = strokeStyle == DottedStroke ? thickness : std::min(3 * thickness, std::max(thickness, strokeWidth / 3));
+ float patternWidth = dashedLinePatternWidthForStrokeWidth(strokeWidth);
// Check if corner drawing sufficiently covers the line.
if (strokeWidth <= patternWidth + 1)
return;
- // Pattern starts with full fill and ends with the empty fill.
- // 1. Let's start with the empty phase after the corner.
- // 2. Check if we've got odd or even number of patterns and whether they fully cover the line.
- // 3. In case of even number of patterns and/or remainder, move the pattern start position
- // so that the pattern is balanced between the corners.
- float patternOffset = patternWidth;
- int numberOfSegments = floorf(strokeWidth / patternWidth);
- bool oddNumberOfSegments = numberOfSegments % 2;
- float remainder = strokeWidth - (numberOfSegments * patternWidth);
- if (oddNumberOfSegments && remainder)
- patternOffset -= remainder / 2;
- else if (!oddNumberOfSegments) {
- if (remainder)
- patternOffset += patternOffset - (patternWidth + remainder) / 2;
- else
- patternOffset += patternWidth / 2;
- }
+ float patternOffset = dashedLinePatternOffsetForPatternAndStrokeWidth(patternWidth, strokeWidth);
const CGFloat dashedLine[2] = { static_cast<CGFloat>(patternWidth), static_cast<CGFloat>(patternWidth) };
CGContextSetLineDash(context, patternOffset, dashedLine, 2);
}
- FloatPoint p1 = point1;
- FloatPoint p2 = point2;
- // Center line and cut off corners for pattern patining.
- if (isVerticalLine) {
- float centerOffset = (p2.x() - p1.x()) / 2;
- p1.move(centerOffset, cornerWidth);
- p2.move(-centerOffset, -cornerWidth);
- } else {
- float centerOffset = (p2.y() - p1.y()) / 2;
- p1.move(cornerWidth, centerOffset);
- p2.move(-cornerWidth, -centerOffset);
- }
+ auto centeredPoints = centerLineAndCutOffCorners(isVerticalLine, cornerWidth, point1, point2);
+ auto p1 = centeredPoints[0];
+ auto p2 = centeredPoints[1];
if (shouldAntialias()) {
#if PLATFORM(IOS)
Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (207001 => 207002)
--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp 2016-10-10 17:00:15 UTC (rev 207001)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp 2016-10-10 17:02:52 UTC (rev 207002)
@@ -502,49 +502,22 @@
D2DContextStateSaver stateSaver(*m_data, drawsDashedLine);
if (drawsDashedLine) {
// Figure out end points to ensure we always paint corners.
- cornerWidth = strokeStyle == DottedStroke ? thickness : std::min(2 * thickness, std::max(thickness, strokeWidth / 3));
+ cornerWidth = dashedLineCornerWidthForStrokeWidth(strokeWidth);
strokeWidth -= 2 * cornerWidth;
- float patternWidth = strokeStyle == DottedStroke ? thickness : std::min(3 * thickness, std::max(thickness, strokeWidth / 3));
+ float patternWidth = dashedLinePatternWidthForStrokeWidth(strokeWidth);
// Check if corner drawing sufficiently covers the line.
if (strokeWidth <= patternWidth + 1)
return;
- // Pattern starts with full fill and ends with the empty fill.
- // 1. Let's start with the empty phase after the corner.
- // 2. Check if we've got odd or even number of patterns and whether they fully cover the line.
- // 3. In case of even number of patterns and/or remainder, move the pattern start position
- // so that the pattern is balanced between the corners.
- float patternOffset = patternWidth;
- int numberOfSegments = floorf(strokeWidth / patternWidth);
- bool oddNumberOfSegments = numberOfSegments % 2;
- float remainder = strokeWidth - (numberOfSegments * patternWidth);
- if (oddNumberOfSegments && remainder)
- patternOffset -= remainder / 2;
- else if (!oddNumberOfSegments) {
- if (remainder)
- patternOffset += patternOffset - (patternWidth + remainder) / 2;
- else
- patternOffset += patternWidth / 2;
- }
+ float patternOffset = dashedLinePatternOffsetForPatternAndStrokeWidth(patternWidth, strokeWidth);
const float dashes[2] = { patternWidth, patternWidth };
-
auto strokeStyleProperties = D2D1::StrokeStyleProperties();
-
GraphicsContext::systemFactory()->CreateStrokeStyle(&strokeStyleProperties, dashes, ARRAYSIZE(dashes), &d2dStrokeStyle);
}
- FloatPoint p1 = point1;
- FloatPoint p2 = point2;
- // Center line and cut off corners for pattern patining.
- if (isVerticalLine) {
- float centerOffset = (p2.x() - p1.x()) / 2;
- p1.move(centerOffset, cornerWidth);
- p2.move(-centerOffset, -cornerWidth);
- } else {
- float centerOffset = (p2.y() - p1.y()) / 2;
- p1.move(cornerWidth, centerOffset);
- p2.move(-cornerWidth, -centerOffset);
- }
+ auto centeredPoints = centerLineAndCutOffCorners(isVerticalLine, cornerWidth, point1, point2);
+ auto p1 = centeredPoints[0];
+ auto p2 = centeredPoints[1];
context->SetTags(1, __LINE__);