static inline void calculateGlyphBoundaries(const QueryData* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent) { float scalingFactor = queryData->textLayoutObject->scalingFactor(); ASSERT(scalingFactor); FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, startPosition); glyphPosition.move(0, -queryData->textLayoutObject->scaledFont().fontMetrics().floatAscent() / scalingFactor); extent.setLocation(glyphPosition); // Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends // time attempting to compute more correct glyph bounds already, handling // cursive scripts to some degree.) const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLayoutObject->layoutAttributes()->textMetricsValues(); const SVGTextMetrics& metrics = findMetricsForCharacter(textMetricsValues, fragment, startPosition); // TODO(fs): Negative glyph extents seems kind of weird to have, but // presently it can occur in some cases (like Arabic.) FloatSize glyphSize(std::max<float>(metrics.width(), 0), std::max<float>(metrics.height(), 0)); extent.setSize(glyphSize); // If RTL, adjust the starting point to align with the LHS of the glyph bounding box. if (!queryData->textBox->isLeftToRightDirection()) { if (queryData->isVerticalText) extent.move(0, -glyphSize.height()); else extent.move(-glyphSize.width(), 0); } AffineTransform fragmentTransform; fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength); extent = fragmentTransform.mapRect(extent); }
static FloatPoint calculateGlyphPosition(const QueryData* queryData, const SVGTextFragment& fragment, int offsetInFragment) { FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, offsetInFragment); if (fragment.isTransformed()) { AffineTransform fragmentTransform = fragment.buildFragmentTransform(SVGTextFragment::TransformIgnoringTextLength); glyphPosition = fragmentTransform.mapPoint(glyphPosition); } return glyphPosition; }