| Index: Source/core/layout/svg/SVGTextQuery.cpp
|
| diff --git a/Source/core/layout/svg/SVGTextQuery.cpp b/Source/core/layout/svg/SVGTextQuery.cpp
|
| index 46543ffaa507858c41ff97ea518ef1e325513f4e..7de7003f55040e91f1bbf4e372dc34a8fd7dfd4b 100644
|
| --- a/Source/core/layout/svg/SVGTextQuery.cpp
|
| +++ b/Source/core/layout/svg/SVGTextQuery.cpp
|
| @@ -279,6 +279,37 @@ struct StartPositionOfCharacterData : SVGTextQuery::Data {
|
| FloatPoint startPosition;
|
| };
|
|
|
| +static FloatPoint calculateGlyphPositionWithoutTransform(const SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int offsetInFragment)
|
| +{
|
| + float glyphOffsetInDirection = 0;
|
| + if (offsetInFragment) {
|
| + SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textLayoutObject, fragment.characterOffset, offsetInFragment, queryData->textLayoutObject->styleRef().direction());
|
| + if (queryData->isVerticalText)
|
| + glyphOffsetInDirection = metrics.height();
|
| + else
|
| + glyphOffsetInDirection = metrics.width();
|
| + }
|
| +
|
| + FloatPoint glyphPosition(fragment.x, fragment.y);
|
| + if (queryData->isVerticalText)
|
| + glyphPosition.move(0, glyphOffsetInDirection);
|
| + else
|
| + glyphPosition.move(glyphOffsetInDirection, 0);
|
| +
|
| + return glyphPosition;
|
| +}
|
| +
|
| +static FloatPoint calculateGlyphPosition(const SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int offsetInFragment)
|
| +{
|
| + FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, offsetInFragment);
|
| + AffineTransform fragmentTransform;
|
| + fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
|
| + if (!fragmentTransform.isIdentity())
|
| + glyphPosition = fragmentTransform.mapPoint(glyphPosition);
|
| +
|
| + return glyphPosition;
|
| +}
|
| +
|
| bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTextFragment& fragment) const
|
| {
|
| StartPositionOfCharacterData* data = static_cast<StartPositionOfCharacterData*>(queryData);
|
| @@ -288,22 +319,7 @@ bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTe
|
| if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
|
| return false;
|
|
|
| - data->startPosition = FloatPoint(fragment.x, fragment.y);
|
| -
|
| - if (startPosition) {
|
| - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textLayoutObject, fragment.characterOffset, startPosition, queryData->textLayoutObject->styleRef().direction());
|
| - if (queryData->isVerticalText)
|
| - data->startPosition.move(0, metrics.height());
|
| - else
|
| - data->startPosition.move(metrics.width(), 0);
|
| - }
|
| -
|
| - AffineTransform fragmentTransform;
|
| - fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
|
| - if (fragmentTransform.isIdentity())
|
| - return true;
|
| -
|
| - data->startPosition = fragmentTransform.mapPoint(data->startPosition);
|
| + data->startPosition = calculateGlyphPosition(queryData, fragment, startPosition);
|
| return true;
|
| }
|
|
|
| @@ -334,20 +350,10 @@ bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGText
|
| if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
|
| return false;
|
|
|
| - data->endPosition = FloatPoint(fragment.x, fragment.y);
|
| -
|
| - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textLayoutObject, fragment.characterOffset, startPosition + 1, queryData->textLayoutObject->styleRef().direction());
|
| - if (queryData->isVerticalText)
|
| - data->endPosition.move(0, metrics.height());
|
| - else
|
| - data->endPosition.move(metrics.width(), 0);
|
| -
|
| - AffineTransform fragmentTransform;
|
| - fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
|
| - if (fragmentTransform.isIdentity())
|
| - return true;
|
| -
|
| - data->endPosition = fragmentTransform.mapPoint(data->endPosition);
|
| + // TODO(fs): mapStartEndPositionsIntoFragmentCoordinates(...) above applies
|
| + // some heuristics for ligatures, so why not just use endPosition here?
|
| + // (rather than startPosition+1)
|
| + data->endPosition = calculateGlyphPosition(queryData, fragment, startPosition + 1);
|
| return true;
|
| }
|
|
|
| @@ -414,15 +420,9 @@ static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const
|
| float scalingFactor = queryData->textLayoutObject->scalingFactor();
|
| ASSERT(scalingFactor);
|
|
|
| - extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textLayoutObject->scaledFont().fontMetrics().floatAscent() / scalingFactor));
|
| -
|
| - if (startPosition) {
|
| - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textLayoutObject, fragment.characterOffset, startPosition, queryData->textLayoutObject->styleRef().direction());
|
| - if (queryData->isVerticalText)
|
| - extent.move(0, metrics.height());
|
| - else
|
| - extent.move(metrics.width(), 0);
|
| - }
|
| + FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, startPosition);
|
| + glyphPosition.move(0, -queryData->textLayoutObject->scaledFont().fontMetrics().floatAscent() / scalingFactor);
|
| + extent.setLocation(glyphPosition);
|
|
|
| SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textLayoutObject, fragment.characterOffset + startPosition, 1, queryData->textLayoutObject->styleRef().direction());
|
| extent.setSize(FloatSize(metrics.width(), metrics.height()));
|
|
|