Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
{
    if (paintingDisabled())
        return;

    StrokeStyle style = strokeStyle();
    if (style == NoStroke)
        return;

    cairo_t* cr = platformContext()->cr();
    cairo_save(cr);

    float width = strokeThickness();
    if (width < 1)
        width = 1;

    FloatPoint p1 = point1;
    FloatPoint p2 = point2;
    bool isVerticalLine = (p1.x() == p2.x());

    adjustLineToPixelBoundaries(p1, p2, width, style);
    cairo_set_line_width(cr, width);

    int patWidth = 0;
    switch (style) {
    case NoStroke:
    case SolidStroke:
        break;
    case DottedStroke:
        patWidth = static_cast<int>(width);
        break;
    case DashedStroke:
        patWidth = 3*static_cast<int>(width);
        break;
    }

    setSourceRGBAFromColor(cr, strokeColor());

    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);

    if (patWidth) {
        // Do a rect fill of our endpoints.  This ensures we always have the
        // appearance of being a border.  We then draw the actual dotted/dashed line.
        if (isVerticalLine) {
            fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());
            fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());
        } else {
            fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());
            fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());
        }

        // Example: 80 pixels with a width of 30 pixels.
        // Remainder is 20.  The maximum pixels of line we could paint
        // will be 50 pixels.
        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);
        int remainder = distance%patWidth;
        int coverage = distance-remainder;
        int numSegments = coverage/patWidth;

        float patternOffset = 0;
        // Special case 1px dotted borders for speed.
        if (patWidth == 1)
            patternOffset = 1.0;
        else {
            bool evenNumberOfSegments = !(numSegments % 2);
            if (remainder)
                evenNumberOfSegments = !evenNumberOfSegments;
            if (evenNumberOfSegments) {
                if (remainder) {
                    patternOffset += patWidth - remainder;
                    patternOffset += remainder / 2;
                } else
                    patternOffset = patWidth / 2;
            } else if (!evenNumberOfSegments) {
                if (remainder)
                    patternOffset = (patWidth - remainder) / 2;
            }
        }

        double dash = patWidth;
        cairo_set_dash(cr, &dash, 1, patternOffset);
    }

    cairo_move_to(cr, p1.x(), p1.y());
    cairo_line_to(cr, p2.x(), p2.y());

    cairo_stroke(cr);
    cairo_restore(cr);
}
// This is only used to draw borders.
This is only used to draw borders.
This is only used to draw borders .
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
{
    if (paintingDisabled())
        return;
    StrokeStyle style = strokeStyle();
    if (style == NoStroke)
        return;
    cairo_t* cr = platformContext()->cr();
    cairo_save(cr);
    float width = strokeThickness();
    if (width < 1)
        width = 1;
    FloatPoint p1 = point1;
    FloatPoint p2 = point2;
    bool isVerticalLine = (p1.x() == p2.x());
    adjustLineToPixelBoundaries(p1, p2, width, style);
    cairo_set_line_width(cr, width);
    int patWidth = 0;
    switch (style) {
    case NoStroke:
    case SolidStroke:
        break;
    case DottedStroke:
        patWidth = static_cast<int>(width);
        break;
    case DashedStroke:
        patWidth = 3*static_cast<int>(width);
        break;
    }
    setSourceRGBAFromColor(cr, strokeColor());
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
    if (patWidth) {
        if (isVerticalLine) {
            fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());
            fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());
        } else {
            fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());
            fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());
        }
        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);
        int remainder = distance%patWidth;
        int coverage = distance-remainder;
        int numSegments = coverage/patWidth;
        float patternOffset = 0;
        if (patWidth == 1)
            patternOffset = 1.0;
        else {
            bool evenNumberOfSegments = !(numSegments % 2);
            if (remainder)
                evenNumberOfSegments = !evenNumberOfSegments;
            if (evenNumberOfSegments) {
                if (remainder) {
                    patternOffset += patWidth - remainder;
                    patternOffset += remainder / 2;
                } else
                    patternOffset = patWidth / 2;
            } else if (!evenNumberOfSegments) {
                if (remainder)
                    patternOffset = (patWidth - remainder) / 2;
            }
        }
        double dash = patWidth;
        cairo_set_dash(cr, &dash, 1, patternOffset);
    }
    cairo_move_to(cr, p1.x(), p1.y());
    cairo_line_to(cr, p2.x(), p2.y());
    cairo_stroke(cr);
    cairo_restore(cr);
}
void GraphicsContext :: drawLine ( const IntPoint & point1 , const IntPoint & point2 ) { if ( paintingDisabled ( ) ) return ; StrokeStyle style = strokeStyle ( ) ; if ( style == NoStroke ) return ; cairo_t * cr = platformContext ( ) -> cr ( ) ; cairo_save ( cr ) ; float width = strokeThickness ( ) ; if ( width < 1 ) width = 1 ; FloatPoint p1 = point1 ; FloatPoint p2 = point2 ; bool isVerticalLine = ( p1 . x ( ) == p2 . x ( ) ) ; adjustLineToPixelBoundaries ( p1 , p2 , width , style ) ; cairo_set_line_width ( cr , width ) ; int patWidth = 0 ; switch ( style ) { case NoStroke : case SolidStroke : break ; case DottedStroke : patWidth = static_cast < int > ( width ) ; break ; case DashedStroke : patWidth = 3 * static_cast < int > ( width ) ; break ; } setSourceRGBAFromColor ( cr , strokeColor ( ) ) ; cairo_set_antialias ( cr , CAIRO_ANTIALIAS_NONE ) ; if ( patWidth ) { if ( isVerticalLine ) { fillRectSourceOver ( cr , FloatRect ( p1 . x ( ) - width / 2 , p1 . y ( ) - width , width , width ) , strokeColor ( ) ) ; fillRectSourceOver ( cr , FloatRect ( p2 . x ( ) - width / 2 , p2 . y ( ) , width , width ) , strokeColor ( ) ) ; } else { fillRectSourceOver ( cr , FloatRect ( p1 . x ( ) - width , p1 . y ( ) - width / 2 , width , width ) , strokeColor ( ) ) ; fillRectSourceOver ( cr , FloatRect ( p2 . x ( ) , p2 . y ( ) - width / 2 , width , width ) , strokeColor ( ) ) ; } int distance = ( isVerticalLine ? ( point2 . y ( ) - point1 . y ( ) ) : ( point2 . x ( ) - point1 . x ( ) ) ) - 2 * static_cast < int > ( width ) ; int remainder = distance % patWidth ; int coverage = distance - remainder ; int numSegments = coverage / patWidth ; float patternOffset = 0 ; if ( patWidth == 1 ) patternOffset = 1.0 ; else { bool evenNumberOfSegments = ! ( numSegments % 2 ) ; if ( remainder ) evenNumberOfSegments = ! evenNumberOfSegments ; if ( evenNumberOfSegments ) { if ( remainder ) { patternOffset += patWidth - remainder ; patternOffset += remainder / 2 ; } else patternOffset = patWidth / 2 ; } else if ( ! evenNumberOfSegments ) { if ( remainder ) patternOffset = ( patWidth - remainder ) / 2 ; } } double dash = patWidth ; cairo_set_dash ( cr , & dash , 1 , patternOffset ) ; } cairo_move_to ( cr , p1 . x ( ) , p1 . y ( ) ) ; cairo_line_to ( cr , p2 . x ( ) , p2 . y ( ) ) ; cairo_stroke ( cr ) ; cairo_restore ( cr ) ; }
This is only used to draw borders.
This is only used to draw borders .
// Do a rect fill of our endpoints.  This ensures we always have the // appearance of being a border.  We then draw the actual dotted/dashed line. // Example: 80 pixels with a width of 30 pixels. // Remainder is 20.  The maximum pixels of line we could paint // will be 50 pixels. // Special case 1px dotted borders for speed.