Created
July 13, 2016 17:39
-
-
Save annulen/2aaa66d6fbbef562bdb8b53996d57f63 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void GraphicsContext::drawLine(const FloatPoint& point1, const FloatPoint& point2) | |
{ | |
if (paintingDisabled()) | |
return; | |
if (strokeStyle() == NoStroke) | |
return; | |
if (isRecording()) { | |
m_displayListRecorder->drawLine(point1, point2); | |
return; | |
} | |
const Color& strokeColor = this->strokeColor(); | |
float thickness = strokeThickness(); | |
bool isVerticalLine = (point1.x() + thickness == point2.x()); | |
float strokeWidth = isVerticalLine ? point2.y() - point1.y() : point2.x() - point1.x(); | |
if (!thickness || !strokeWidth) | |
return; | |
QPainter* p = platformContext(); | |
const bool savedAntiAlias = p->testRenderHint(QPainter::Antialiasing); | |
p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); | |
StrokeStyle strokeStyle = this->strokeStyle(); | |
float cornerWidth = 0; | |
bool drawsDashedLine = strokeStyle == DottedStroke || strokeStyle == DashedStroke; | |
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)); | |
if (isVerticalLine) { | |
// fill FloatRect(point1.x(), point1.y(), thickness, cornerWidth) | |
// fill FloatRect(point1.x(), point2.y() - cornerWidth, thickness, cornerWidth) | |
} else { | |
// fill FloatRect(point1.x(), point1.y(), cornerWidth, thickness) | |
// fill 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)); | |
// Check if corner drawing sufficiently covers the line. | |
if (strokeWidth <= patternWidth + 1) { | |
// restore painter | |
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; | |
} | |
// FIXME | |
QPen pen = p->pen(); | |
QVector<qreal> dashes { patternWidth, patternWidth }; | |
pen.setDashPattern(dashes); | |
pen.setDashOffset(patternOffset); | |
// p->setPen(pen); | |
} else { | |
// Dotted here | |
} | |
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); | |
} | |
// Qt interprets geometric units as end-point inclusive, while WebCore interprets geomtric units as endpoint exclusive. | |
// This means we need to subtract one from the endpoint, or the line will be painted one pixel too long. | |
if (p1.x() == p2.x()) | |
p->drawLine(p1, p2 - FloatSize(0, 1)); | |
else | |
p->drawLine(p1, p2 - FloatSize(1, 0)); | |
// if (patWidth) | |
// p->restore(); | |
p->setRenderHint(QPainter::Antialiasing, savedAntiAlias); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment