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()); }
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)); }
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)); }
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())); }