示例#1
0
void SVGLayoutSupport::applyStrokeStyleToStrokeData(StrokeData& strokeData,
                                                    const ComputedStyle& style,
                                                    const LayoutObject& object,
                                                    float dashScaleFactor) {
  ASSERT(object.node());
  ASSERT(object.node()->isSVGElement());

  const SVGComputedStyle& svgStyle = style.svgStyle();

  SVGLengthContext lengthContext(toSVGElement(object.node()));
  strokeData.setThickness(lengthContext.valueForLength(svgStyle.strokeWidth()));
  strokeData.setLineCap(svgStyle.capStyle());
  strokeData.setLineJoin(svgStyle.joinStyle());
  strokeData.setMiterLimit(svgStyle.strokeMiterLimit());

  DashArray dashArray =
      resolveSVGDashArray(*svgStyle.strokeDashArray(), style, lengthContext);
  float dashOffset =
      lengthContext.valueForLength(svgStyle.strokeDashOffset(), style);
  // Apply scaling from 'pathLength'.
  if (dashScaleFactor != 1) {
    ASSERT(dashScaleFactor >= 0);
    dashOffset *= dashScaleFactor;
    for (auto& dashItem : dashArray)
      dashItem *= dashScaleFactor;
  }
  strokeData.setLineDash(dashArray, dashOffset);
}
void SVGLayoutSupport::applyStrokeStyleToStrokeData(StrokeData& strokeData, const ComputedStyle& style, const LayoutObject& object)
{
    ASSERT(object.node());
    ASSERT(object.node()->isSVGElement());

    const SVGComputedStyle& svgStyle = style.svgStyle();

    SVGLengthContext lengthContext(toSVGElement(object.node()));
    strokeData.setThickness(lengthContext.valueForLength(svgStyle.strokeWidth()));
    strokeData.setLineCap(svgStyle.capStyle());
    strokeData.setLineJoin(svgStyle.joinStyle());
    strokeData.setMiterLimit(svgStyle.strokeMiterLimit());

    DashArray dashArray = resolveSVGDashArray(*svgStyle.strokeDashArray(), style, lengthContext);
    strokeData.setLineDash(dashArray, lengthContext.valueForLength(svgStyle.strokeDashOffset(), style));
}
void CanvasRenderingContext2D::drawFocusRing(const Path& path) {
  m_usageCounters.numDrawFocusCalls++;
  if (!drawingCanvas())
    return;

  SkColor color = LayoutTheme::theme().focusRingColor().rgb();
  const int focusRingWidth = 5;

  drawPlatformFocusRing(path.getSkPath(), drawingCanvas(), color,
                        focusRingWidth);

  // We need to add focusRingWidth to dirtyRect.
  StrokeData strokeData;
  strokeData.setThickness(focusRingWidth);

  SkIRect dirtyRect;
  if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect))
    return;

  didDraw(dirtyRect);
}
void SVGInlineTextBoxPainter::paintTextWithShadows(const PaintInfo& paintInfo, const ComputedStyle& style,
    TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition,
    LayoutSVGResourceMode resourceMode)
{
    LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(m_svgInlineTextBox.layoutObject());

    float scalingFactor = textLayoutObject.scalingFactor();
    ASSERT(scalingFactor);

    const Font& scaledFont = textLayoutObject.scaledFont();
    const ShadowList* shadowList = style.textShadow();
    GraphicsContext* context = paintInfo.context;

    // Text shadows are disabled when printing. http://crbug.com/258321
    bool hasShadow = shadowList && !context->printing();

    FloatPoint textOrigin(fragment.x, fragment.y);
    FloatSize textSize(fragment.width, fragment.height);
    AffineTransform paintServerTransform;
    const AffineTransform* additionalPaintServerTransform = 0;

    GraphicsContextStateSaver stateSaver(*context, false);
    if (scalingFactor != 1) {
        textOrigin.scale(scalingFactor, scalingFactor);
        textSize.scale(scalingFactor);
        stateSaver.save();
        context->scale(1 / scalingFactor, 1 / scalingFactor);
        // Adjust the paint-server coordinate space.
        paintServerTransform.scale(scalingFactor);
        additionalPaintServerTransform = &paintServerTransform;
    }

    SkPaint paint;
    if (!SVGPaintContext::paintForLayoutObject(paintInfo, style, m_svgInlineTextBox.parent()->layoutObject(), resourceMode, paint, additionalPaintServerTransform))
        return;
    paint.setAntiAlias(true);

    if (hasShadow) {
        OwnPtr<DrawLooperBuilder> drawLooperBuilder = shadowList->createDrawLooper(DrawLooperBuilder::ShadowRespectsAlpha, style.visitedDependentColor(CSSPropertyColor));
        RefPtr<SkDrawLooper> drawLooper = drawLooperBuilder->detachDrawLooper();
        paint.setLooper(drawLooper.get());
    }

    if (resourceMode == ApplyToStrokeMode) {
        StrokeData strokeData;
        SVGLayoutSupport::applyStrokeStyleToStrokeData(strokeData, style, m_svgInlineTextBox.parent()->layoutObject());
        if (style.svgStyle().vectorEffect() != VE_NON_SCALING_STROKE)
            strokeData.setThickness(strokeData.thickness() * scalingFactor);
        strokeData.setupPaint(&paint);
    }

    TextRunPaintInfo textRunPaintInfo(textRun);
    textRunPaintInfo.from = startPosition;
    textRunPaintInfo.to = endPosition;

    float baseline = scaledFont.fontMetrics().floatAscent();
    textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baseline,
        textSize.width(), textSize.height());

    context->drawText(scaledFont, textRunPaintInfo, textOrigin, paint);
}
void SVGInlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, TextDecoration decoration, const SVGTextFragment& fragment)
{
    if (m_svgInlineTextBox.layoutObject().style()->textDecorationsInEffect() == TextDecorationNone)
        return;

    if (fragment.width <= 0)
        return;

    // Find out which style defined the text-decoration, as its fill/stroke properties have to be used for drawing instead of ours.
    LayoutObject* decorationLayoutObject = findLayoutObjectDefininingTextDecoration(m_svgInlineTextBox.parent());
    const ComputedStyle& decorationStyle = decorationLayoutObject->styleRef();

    if (decorationStyle.visibility() == HIDDEN)
        return;

    float scalingFactor = 1;
    Font scaledFont;
    LayoutSVGInlineText::computeNewScaledFontForStyle(decorationLayoutObject, &decorationStyle, scalingFactor, scaledFont);
    ASSERT(scalingFactor);

    float thickness = thicknessForDecoration(decoration, scaledFont);
    if (thickness <= 0)
        return;

    float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.fontMetrics(), thickness);
    FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scalingFactor);

    Path path;
    path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness / scalingFactor)));

    const SVGComputedStyle& svgDecorationStyle = decorationStyle.svgStyle();

    for (int i = 0; i < 3; i++) {
        switch (svgDecorationStyle.paintOrderType(i)) {
        case PT_FILL:
            if (svgDecorationStyle.hasFill()) {
                SkPaint fillPaint;
                if (!SVGPaintContext::paintForLayoutObject(paintInfo, decorationStyle, *decorationLayoutObject, ApplyToFillMode, fillPaint))
                    break;
                fillPaint.setAntiAlias(true);
                paintInfo.context->drawPath(path.skPath(), fillPaint);
            }
            break;
        case PT_STROKE:
            if (svgDecorationStyle.hasVisibleStroke()) {
                SkPaint strokePaint;
                if (!SVGPaintContext::paintForLayoutObject(paintInfo, decorationStyle, *decorationLayoutObject, ApplyToStrokeMode, strokePaint))
                    break;
                strokePaint.setAntiAlias(true);
                StrokeData strokeData;
                SVGLayoutSupport::applyStrokeStyleToStrokeData(strokeData, decorationStyle, *decorationLayoutObject);
                if (svgDecorationStyle.vectorEffect() == VE_NON_SCALING_STROKE)
                    strokeData.setThickness(strokeData.thickness() / scalingFactor);
                strokeData.setupPaint(&strokePaint);
                paintInfo.context->drawPath(path.skPath(), strokePaint);
            }
            break;
        case PT_MARKERS:
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
}