std::pair<float, float> SVGGlyphToPathTranslator::extents()
{
    AffineTransform glyphPathTransform = transform();
    FloatPoint beginning = glyphPathTransform.mapPoint(m_currentPoint);
    FloatSize end = glyphPathTransform.mapSize(FloatSize(m_glyphBuffer.advanceAt(m_index)));
    return std::make_pair(beginning.x(), beginning.x() + end.width());
}
예제 #2
0
LayoutRect SVGLayoutSupport::transformPaintInvalidationRect(
    const LayoutObject& object,
    const AffineTransform& rootTransform,
    const FloatRect& localRect) {
  FloatRect adjustedRect = rootTransform.mapRect(localRect);

  if (object.isSVGShape() && object.styleRef().svgStyle().hasStroke()) {
    if (float strokeWidthForHairlinePadding =
            toLayoutSVGShape(object).strokeWidth()) {
      // For hairline strokes (stroke-width < 1 in device space), Skia
      // rasterizes up to 0.4(9) off the stroke center. That means
      // enclosingIntRect is not enough - we must also pad to 0.5.
      // This is still fragile as it misses out on CC/DSF CTM components.
      const FloatSize strokeSize = rootTransform.mapSize(FloatSize(
          strokeWidthForHairlinePadding, strokeWidthForHairlinePadding));
      if (strokeSize.width() < 1 || strokeSize.height() < 1) {
        float pad =
            0.5f - std::min(strokeSize.width(), strokeSize.height()) / 2;
        DCHECK_GT(pad, 0);
        // Additionally, square/round caps can potentially introduce an outset
        // <= 0.5
        if (object.styleRef().svgStyle().capStyle() != ButtCap)
          pad += 0.5f;
        adjustedRect.inflate(pad);
      }
    }
  }

  if (adjustedRect.isEmpty())
    return LayoutRect();

  // Use enclosingIntRect because we cannot properly apply subpixel offset of
  // the SVGRoot since we don't know the desired subpixel accumulation at this
  // point.
  return LayoutRect(enclosingIntRect(adjustedRect));
}
예제 #3
0
LayoutRect SVGLayoutSupport::transformPaintInvalidationRect(const LayoutObject& object, const AffineTransform& rootTransform, const FloatRect& localRect)
{
    FloatRect adjustedRect = rootTransform.mapRect(localRect);

    if (object.isSVGShape() && object.styleRef().svgStyle().hasStroke()) {
        if (float strokeWidthForHairlinePadding = toLayoutSVGShape(object).strokeWidth()) {
            // For hairline strokes (stroke-width < 1 in device space), Skia rasterizes up to 0.4(9) off
            // the stroke center. That means enclosingIntRect is not enough - we must also pad to 0.5.
            // This is still fragile as it misses out on CC/DSF CTM components.
            const FloatSize strokeSize = rootTransform.mapSize(
                FloatSize(strokeWidthForHairlinePadding, strokeWidthForHairlinePadding));
            if (strokeSize.width() < 1 || strokeSize.height() < 1) {
                const float pad = 0.5f - std::min(strokeSize.width(), strokeSize.height()) / 2;
                ASSERT(pad > 0);
                adjustedRect.inflate(pad);
            }
        }
    }

    if (adjustedRect.isEmpty())
        return LayoutRect();

    return LayoutRect(enclosingIntRect(adjustedRect));
}
예제 #4
0
std::pair<float, float> CairoGlyphToPathTranslator::extents()
{
    FloatPoint beginning = m_translation.mapPoint(FloatPoint());
    FloatSize end = m_translation.mapSize(m_glyphBuffer.advanceAt(m_index));
    return std::make_pair(static_cast<float>(beginning.x()), static_cast<float>(beginning.x() + end.width()));
}