Changeset 41659 in webkit


Ignore:
Timestamp:
Mar 12, 2009 8:10:31 PM (15 years ago)
Author:
treat@webkit.org
Message:

2009-03-12 Adam Treat <adam.treat@torchmobile.com>

Reviewed by Oliver Hunt.

https://bugs.webkit.org/show_bug.cgi?id=24498
Fix the Qt port to use the same algorithm for drawing dashed and dotted
borders as the other ports. This makes the Qt port pixel-for-pixel perfect
compared to border drawing with Apple's canonical mac port and much closer
to konqueror and firefox behavior.

  • platform/graphics/qt/GraphicsContextQt.cpp: (WebCore::GraphicsContext::drawLine):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r41657 r41659  
     12009-03-12  Adam Treat  <adam.treat@torchmobile.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=24498
     6        Fix the Qt port to use the same algorithm for drawing dashed and dotted
     7        borders as the other ports.  This makes the Qt port pixel-for-pixel perfect
     8        compared to border drawing with Apple's canonical mac port and much closer
     9        to konqueror and firefox behavior.
     10
     11        * platform/graphics/qt/GraphicsContextQt.cpp:
     12        (WebCore::GraphicsContext::drawLine):
     13
    1142009-02-26  Eric Seidel  <eric@webkit.org>
    215
  • trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

    r41420 r41659  
    447447        return;
    448448
     449    StrokeStyle style = strokeStyle();
     450    Color color = strokeColor();
     451    if (style == NoStroke || !color.alpha())
     452        return;
     453
     454    float width = strokeThickness();
     455
    449456    FloatPoint p1 = point1;
    450457    FloatPoint p2 = point2;
     458    bool isVerticalLine = (p1.x() == p2.x());
    451459
    452460    QPainter *p = m_data->p();
    453461    const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
    454462    p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
    455     adjustLineToPixelBoundaries(p1, p2, strokeThickness(), strokeStyle());
     463    adjustLineToPixelBoundaries(p1, p2, width, style);
    456464
    457465    IntSize shadowSize;
     
    466474    }
    467475
     476    int patWidth = 0;
     477    switch (style) {
     478        case NoStroke:
     479        case SolidStroke:
     480            break;
     481        case DottedStroke:
     482            patWidth = (int)width;
     483            break;
     484        case DashedStroke:
     485            patWidth = 3 * (int)width;
     486            break;
     487    }
     488
     489    if (patWidth) {
     490        p->save();
     491
     492        // Do a rect fill of our endpoints.  This ensures we always have the
     493        // appearance of being a border.  We then draw the actual dotted/dashed line.
     494        if (isVerticalLine) {
     495            p->fillRect(FloatRect(p1.x() - width / 2, p1.y() - width, width, width), color);
     496            p->fillRect(FloatRect(p2.x() - width / 2, p2.y(), width, width), color);
     497        } else {
     498            p->fillRect(FloatRect(p1.x() - width, p1.y() - width / 2, width, width), color);
     499            p->fillRect(FloatRect(p2.x(), p2.y() - width / 2, width, width), color);
     500        }
     501
     502        // Example: 80 pixels with a width of 30 pixels.
     503        // Remainder is 20.  The maximum pixels of line we could paint
     504        // will be 50 pixels.
     505        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*(int)width;
     506        int remainder = distance % patWidth;
     507        int coverage = distance - remainder;
     508        int numSegments = coverage / patWidth;
     509
     510        float patternOffset = 0.0f;
     511        // Special case 1px dotted borders for speed.
     512        if (patWidth == 1)
     513            patternOffset = 1.0f;
     514        else {
     515            bool evenNumberOfSegments = numSegments % 2 == 0;
     516            if (remainder)
     517                evenNumberOfSegments = !evenNumberOfSegments;
     518            if (evenNumberOfSegments) {
     519                if (remainder) {
     520                    patternOffset += patWidth - remainder;
     521                    patternOffset += remainder / 2;
     522                } else
     523                    patternOffset = patWidth / 2;
     524            } else {
     525                if (remainder)
     526                    patternOffset = (patWidth - remainder)/2;
     527            }
     528        }
     529
     530        QVector<qreal> dashes;
     531        dashes << qreal(patWidth) / width << qreal(patWidth) / width;
     532
     533        QPen pen = p->pen();
     534        pen.setWidthF(width);
     535        pen.setCapStyle(Qt::FlatCap);
     536        pen.setDashPattern(dashes);
     537        pen.setDashOffset(patternOffset / width);
     538        p->setPen(pen);
     539    }
     540
    468541    p->drawLine(p1, p2);
     542
     543    if (patWidth)
     544        p->restore();
    469545
    470546    p->setRenderHint(QPainter::Antialiasing, antiAlias);
Note: See TracChangeset for help on using the changeset viewer.