예제 #1
0
    void applyStrokeStyle()
    {
        if (strokeStyle == DottedStroke) {
            VGfloat vgFloatArray[2] = { 1.0, 1.0 };
            vgSetfv(VG_STROKE_DASH_PATTERN, 2, vgFloatArray);
            vgSetf(VG_STROKE_DASH_PHASE, 0.0);
        } else if (strokeStyle == DashedStroke) {
            if (!strokeDashArray.size()) {
                VGfloat vgFloatArray[2] = { 4.0, 3.0 };
                vgSetfv(VG_STROKE_DASH_PATTERN, 2, vgFloatArray);
            } else {
                Vector<VGfloat> vgFloatArray(strokeDashArray.size());
                for (int i = 0; i < strokeDashArray.size(); ++i)
                    vgFloatArray[i] = strokeDashArray[i];

                vgSetfv(VG_STROKE_DASH_PATTERN, vgFloatArray.size(), vgFloatArray.data());
            }
            vgSetf(VG_STROKE_DASH_PHASE, strokeDashOffset);
        } else {
            vgSetfv(VG_STROKE_DASH_PATTERN, 0, 0);
            vgSetf(VG_STROKE_DASH_PHASE, 0.0);
        }

        ASSERT_VG_NO_ERROR();
    }
예제 #2
0
void GraphicsContext::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleUnderlines)
{
    if (paintingDisabled())
        return;

    if (widths.size() <= 0)
        return;

    Color localStrokeColor(strokeColor());

    bool shouldAntialiasLine;
    FloatRect bounds = computeLineBoundsAndAntialiasingModeForText(point, widths.last(), printing, shouldAntialiasLine, localStrokeColor);

    Vector<FloatRect, 4> dashBounds;
    ASSERT(!(widths.size() % 2));
    dashBounds.reserveInitialCapacity(dashBounds.size() / 2);
    for (size_t i = 0; i < widths.size(); i += 2)
        dashBounds.append(FloatRect(FloatPoint(bounds.x() + widths[i], bounds.y()), FloatSize(widths[i+1] - widths[i], bounds.height())));

    if (doubleUnderlines) {
        // The space between double underlines is equal to the height of the underline
        for (size_t i = 0; i < widths.size(); i += 2)
            dashBounds.append(FloatRect(FloatPoint(bounds.x() + widths[i], bounds.y() + 2 * bounds.height()), FloatSize(widths[i+1] - widths[i], bounds.height())));
    }

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

    for (auto& dash : dashBounds)
        fillRectWithColor(cr, dash, localStrokeColor);

    cairo_restore(cr);
}
void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    if (paintingDisabled())
        return;

    platformContext()->setLineDash(dashes.data(), dashes.size(), dashOffset);
}
예제 #4
0
void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    if (paintingDisabled())
        return;

    // FIXME: This is lifted directly off SkiaSupport, lines 49-74
    // so it is not guaranteed to work correctly.
    size_t dashLength = dashes.size();
    if (!dashLength) {
        // If no dash is set, revert to solid stroke
        // FIXME: do we need to set NoStroke in some cases?
        platformContext()->setStrokeStyle(SolidStroke);
        platformContext()->setDashPathEffect(0);
        return;
    }

    size_t count = !(dashLength % 2) ? dashLength : dashLength * 2;
    SkScalar* intervals = new SkScalar[count];

    for (unsigned int i = 0; i < count; i++)
        intervals[i] = dashes[i % dashLength];

    platformContext()->setDashPathEffect(new SkDashPathEffect(intervals, count, dashOffset));

    delete[] intervals;
}
예제 #5
0
static void drawSkipInkUnderline(GraphicsContext& context, const FontCascade& font, const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& localOrigin,
    float underlineOffset, float width, bool isPrinting, bool doubleLines, StrokeStyle strokeStyle)
{
    FloatPoint adjustedLocalOrigin = localOrigin;
    adjustedLocalOrigin.move(0, underlineOffset);
    FloatRect underlineBoundingBox = context.computeUnderlineBoundsForText(adjustedLocalOrigin, width, isPrinting);
    DashArray intersections = font.dashesForIntersectionsWithRect(textRun, textOrigin, underlineBoundingBox);
    DashArray a = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), width);
    ASSERT(!(a.size() % 2));
    context.drawLinesForText(adjustedLocalOrigin, a, isPrinting, doubleLines, strokeStyle);
}
void PlatformGraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    size_t dashLength = dashes.size();
    if (!dashLength)
        return;

    size_t count = !(dashLength % 2) ? dashLength : dashLength * 2;
    SkScalar* intervals = new SkScalar[count];

    for (unsigned int i = 0; i < count; i++)
        intervals[i] = SkFloatToScalar(dashes[i % dashLength]);
    SkPathEffect **effectPtr = &m_state->pathEffect;
    SkSafeUnref(*effectPtr);
    *effectPtr = new SkDashPathEffect(intervals, count, SkFloatToScalar(dashOffset));

    delete[] intervals;
}
예제 #7
0
static DashArray translateIntersectionPointsToSkipInkBoundaries(const DashArray& intersections, float dilationAmount, float totalWidth)
{
    ASSERT(!(intersections.size() % 2));
    
    // Step 1: Make pairs so we can sort based on range starting-point. We dilate the ranges in this step as well.
    Vector<std::pair<float, float>> tuples;
    for (auto i = intersections.begin(); i != intersections.end(); i++, i++)
        tuples.append(std::make_pair(*i - dilationAmount, *(i + 1) + dilationAmount));
    std::sort(tuples.begin(), tuples.end(), &compareTuples);

    // Step 2: Deal with intersecting ranges.
    Vector<std::pair<float, float>> intermediateTuples;
    if (tuples.size() >= 2) {
        intermediateTuples.append(*tuples.begin());
        for (auto i = tuples.begin() + 1; i != tuples.end(); i++) {
            float& firstEnd = intermediateTuples.last().second;
            float secondStart = i->first;
            float secondEnd = i->second;
            if (secondStart <= firstEnd && secondEnd <= firstEnd) {
                // Ignore this range completely
            } else if (secondStart <= firstEnd)
                firstEnd = secondEnd;
            else
                intermediateTuples.append(*i);
        }
    } else
        intermediateTuples = tuples;

    // Step 3: Output the space between the ranges, but only if the space warrants an underline.
    float previous = 0;
    DashArray result;
    for (const auto& tuple : intermediateTuples) {
        if (tuple.first - previous > dilationAmount) {
            result.append(previous);
            result.append(tuple.first);
        }
        previous = tuple.second;
    }
    if (totalWidth - previous > dilationAmount) {
        result.append(previous);
        result.append(totalWidth);
    }
    
    return result;
}
void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    QPainter* p = m_data->p();
    QPen pen = p->pen();
    unsigned dashLength = dashes.size();
    if (dashLength) {
        QVector<qreal> pattern;
        unsigned count = dashLength;
        if (dashLength % 2)
            count *= 2;

        float penWidth = narrowPrecisionToFloat(double(pen.widthF()));
        for (unsigned i = 0; i < count; i++)
            pattern.append(dashes[i % dashLength] / penWidth);

        pen.setDashPattern(pattern);
        pen.setDashOffset(dashOffset);
    }
    p->setPen(pen);
}
void StrokeData::setLineDash(const DashArray& dashes, float dashOffset)
{
    // FIXME: This is lifted directly off SkiaSupport, lines 49-74
    // so it is not guaranteed to work correctly.
    size_t dashLength = dashes.size();
    if (!dashLength) {
        // If no dash is set, revert to solid stroke
        // FIXME: do we need to set NoStroke in some cases?
        m_style = SolidStroke;
        m_dash.clear();
        return;
    }

    size_t count = !(dashLength % 2) ? dashLength : dashLength * 2;
    OwnArrayPtr<SkScalar> intervals = adoptArrayPtr(new SkScalar[count]);

    for (unsigned i = 0; i < count; i++)
        intervals[i] = dashes[i % dashLength];

    m_dash = adoptRef(new SkDashPathEffect(intervals.get(), count, dashOffset));
}
예제 #10
0
void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    CGContextSetLineDash(platformContext(), dashOffset, dashes.data(), dashes.size());
}
예제 #11
0
void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    cairo_set_dash(platformContext()->cr(), dashes.data(), dashes.size(), dashOffset);
}