diff options
Diffstat (limited to 'Source/WebCore/rendering/svg/SVGTextQuery.cpp')
-rw-r--r-- | Source/WebCore/rendering/svg/SVGTextQuery.cpp | 108 |
1 files changed, 52 insertions, 56 deletions
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.cpp b/Source/WebCore/rendering/svg/SVGTextQuery.cpp index f25dedcad..86e4bf2f3 100644 --- a/Source/WebCore/rendering/svg/SVGTextQuery.cpp +++ b/Source/WebCore/rendering/svg/SVGTextQuery.cpp @@ -20,11 +20,11 @@ #include "config.h" #include "SVGTextQuery.h" -#if ENABLE(SVG) #include "FloatConversion.h" #include "InlineFlowBox.h" #include "RenderBlockFlow.h" #include "RenderInline.h" +#include "RenderSVGText.h" #include "SVGInlineTextBox.h" #include "VisiblePosition.h" @@ -51,12 +51,12 @@ struct SVGTextQuery::Data { static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer) { if (!renderer) - return 0; + return nullptr; - if (renderer->isRenderBlockFlow()) { + if (is<RenderBlockFlow>(*renderer)) { // If we're given a block element, it has to be a RenderSVGText. - ASSERT(renderer->isSVGText()); - RenderBlockFlow& renderBlock = toRenderBlockFlow(*renderer); + ASSERT(is<RenderSVGText>(*renderer)); + RenderBlockFlow& renderBlock = downcast<RenderBlockFlow>(*renderer); // RenderSVGText only ever contains a single line box. auto flowBox = renderBlock.firstRootBox(); @@ -64,9 +64,9 @@ static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer) return flowBox; } - if (renderer->isRenderInline()) { + if (is<RenderInline>(*renderer)) { // We're given a RenderSVGInline or objects that derive from it (RenderSVGTSpan / RenderSVGTextPath) - RenderInline& renderInline = toRenderInline(*renderer); + RenderInline& renderInline = downcast<RenderInline>(*renderer); // RenderSVGInline only ever contains a single line box. InlineFlowBox* flowBox = renderInline.firstLineBox(); @@ -75,7 +75,7 @@ static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer) } ASSERT_NOT_REACHED(); - return 0; + return nullptr; } SVGTextQuery::SVGTextQuery(RenderObject* renderer) @@ -89,17 +89,17 @@ void SVGTextQuery::collectTextBoxesInFlowBox(InlineFlowBox* flowBox) return; for (InlineBox* child = flowBox->firstChild(); child; child = child->nextOnLine()) { - if (child->isInlineFlowBox()) { + if (is<InlineFlowBox>(*child)) { // Skip generated content. if (!child->renderer().node()) continue; - collectTextBoxesInFlowBox(toInlineFlowBox(child)); + collectTextBoxesInFlowBox(downcast<InlineFlowBox>(child)); continue; } - if (child->isSVGInlineTextBox()) - m_textBoxes.append(toSVGInlineTextBox(child)); + if (is<SVGInlineTextBox>(*child)) + m_textBoxes.append(downcast<SVGInlineTextBox>(child)); } } @@ -115,7 +115,7 @@ bool SVGTextQuery::executeQuery(Data* queryData, ProcessTextFragmentCallback fra queryData->textBox = m_textBoxes.at(textBoxPosition); queryData->textRenderer = &queryData->textBox->renderer(); - queryData->isVerticalText = queryData->textRenderer->style().svgStyle().isVerticalWritingMode(); + queryData->isVerticalText = queryData->textRenderer->style().isVerticalWritingMode(); const Vector<SVGTextFragment>& fragments = queryData->textBox->textFragments(); // Loop over all text fragments in this text box, firing a callback for each. @@ -134,13 +134,15 @@ bool SVGTextQuery::executeQuery(Data* queryData, ProcessTextFragmentCallback fra return false; } -bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) const +bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, const SVGTextFragment& fragment, unsigned& startPosition, unsigned& endPosition) const { // Reuse the same logic used for text selection & painting, to map our query start/length into start/endPositions of the current text fragment. + ASSERT(startPosition >= queryData->processedCharacters); + ASSERT(endPosition >= queryData->processedCharacters); startPosition -= queryData->processedCharacters; endPosition -= queryData->processedCharacters; - if (startPosition >= endPosition || startPosition < 0 || endPosition < 0) + if (startPosition >= endPosition) return false; modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosition); @@ -151,7 +153,7 @@ bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, return true; } -void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, int& startPosition, int& endPosition) const +void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, unsigned& startPosition, unsigned& endPosition) const { SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutAttributes(); Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsValues(); @@ -167,7 +169,7 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i bool alterStartPosition = true; bool alterEndPosition = true; - int lastPositionOffset = -1; + std::optional<unsigned> lastPositionOffset; for (; textMetricsOffset < textMetricsSize && positionOffset < positionSize; ++textMetricsOffset) { SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; @@ -182,21 +184,21 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i break; // If the start position maps to a character in the metrics list, we don't need to modify it. - if (startPosition == static_cast<int>(positionOffset)) + if (startPosition == positionOffset) alterStartPosition = false; // If the start position maps to a character in the metrics list, we don't need to modify it. - if (endPosition == static_cast<int>(positionOffset)) + if (endPosition == positionOffset) alterEndPosition = false; // Detect ligatures. - if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) { - if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) { - startPosition = lastPositionOffset; + if (lastPositionOffset && lastPositionOffset.value() - positionOffset > 1) { + if (alterStartPosition && startPosition > lastPositionOffset.value() && startPosition < positionOffset) { + startPosition = lastPositionOffset.value(); alterStartPosition = false; } - if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) { + if (alterEndPosition && endPosition > lastPositionOffset.value() && endPosition < positionOffset) { endPosition = positionOffset; alterEndPosition = false; } @@ -212,16 +214,12 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i if (!alterStartPosition && !alterEndPosition) return; - if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) { - if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) { - startPosition = lastPositionOffset; - alterStartPosition = false; - } + if (lastPositionOffset && lastPositionOffset.value() - positionOffset > 1) { + if (alterStartPosition && startPosition > lastPositionOffset.value() && startPosition < positionOffset) + startPosition = lastPositionOffset.value(); - if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) { + if (alterEndPosition && endPosition > lastPositionOffset.value() && endPosition < positionOffset) endPosition = positionOffset; - alterEndPosition = false; - } } } @@ -288,12 +286,12 @@ bool SVGTextQuery::subStringLengthCallback(Data* queryData, const SVGTextFragmen { SubStringLengthData* data = static_cast<SubStringLengthData*>(queryData); - int startPosition = data->startPosition; - int endPosition = startPosition + data->length; + unsigned startPosition = data->startPosition; + unsigned endPosition = startPosition + data->length; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) return false; - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset + startPosition, endPosition - startPosition); + SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset + startPosition, endPosition - startPosition); data->subStringLength += queryData->isVerticalText ? metrics.height() : metrics.width(); return false; } @@ -323,15 +321,15 @@ bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTe { StartPositionOfCharacterData* data = static_cast<StartPositionOfCharacterData*>(queryData); - int startPosition = data->position; - int endPosition = startPosition + 1; + unsigned startPosition = data->position; + unsigned endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) return false; data->startPosition = FloatPoint(fragment.x, fragment.y); if (startPosition) { - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition); + SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset, startPosition); if (queryData->isVerticalText) data->startPosition.move(0, metrics.height()); else @@ -347,10 +345,10 @@ bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTe return true; } -SVGPoint SVGTextQuery::startPositionOfCharacter(unsigned position) const +FloatPoint SVGTextQuery::startPositionOfCharacter(unsigned position) const { if (m_textBoxes.isEmpty()) - return SVGPoint(); + return { }; StartPositionOfCharacterData data(position); executeQuery(&data, &SVGTextQuery::startPositionOfCharacterCallback); @@ -372,14 +370,14 @@ bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGText { EndPositionOfCharacterData* data = static_cast<EndPositionOfCharacterData*>(queryData); - int startPosition = data->position; - int endPosition = startPosition + 1; + unsigned startPosition = data->position; + unsigned endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) return false; data->endPosition = FloatPoint(fragment.x, fragment.y); - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition + 1); + SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset, startPosition + 1); if (queryData->isVerticalText) data->endPosition.move(0, metrics.height()); else @@ -394,10 +392,10 @@ bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGText return true; } -SVGPoint SVGTextQuery::endPositionOfCharacter(unsigned position) const +FloatPoint SVGTextQuery::endPositionOfCharacter(unsigned position) const { if (m_textBoxes.isEmpty()) - return SVGPoint(); + return { }; EndPositionOfCharacterData data(position); executeQuery(&data, &SVGTextQuery::endPositionOfCharacterCallback); @@ -420,8 +418,8 @@ bool SVGTextQuery::rotationOfCharacterCallback(Data* queryData, const SVGTextFra { RotationOfCharacterData* data = static_cast<RotationOfCharacterData*>(queryData); - int startPosition = data->position; - int endPosition = startPosition + 1; + unsigned startPosition = data->position; + unsigned endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) return false; @@ -458,7 +456,7 @@ struct ExtentOfCharacterData : SVGTextQuery::Data { FloatRect extent; }; -static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent) +static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, unsigned startPosition, FloatRect& extent) { float scalingFactor = queryData->textRenderer->scalingFactor(); ASSERT(scalingFactor); @@ -466,14 +464,14 @@ static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor)); if (startPosition) { - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition); + SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset, startPosition); if (queryData->isVerticalText) extent.move(0, metrics.height()); else extent.move(metrics.width(), 0); } - SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset + startPosition, 1); + SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset + startPosition, 1); extent.setSize(FloatSize(metrics.width(), metrics.height())); AffineTransform fragmentTransform; @@ -488,8 +486,8 @@ bool SVGTextQuery::extentOfCharacterCallback(Data* queryData, const SVGTextFragm { ExtentOfCharacterData* data = static_cast<ExtentOfCharacterData*>(queryData); - int startPosition = data->position; - int endPosition = startPosition + 1; + unsigned startPosition = data->position; + unsigned endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) return false; @@ -523,8 +521,8 @@ bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGT FloatRect extent; for (unsigned i = 0; i < fragment.length; ++i) { - int startPosition = data->processedCharacters + i; - int endPosition = startPosition + 1; + unsigned startPosition = data->processedCharacters + i; + unsigned endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) continue; @@ -538,7 +536,7 @@ bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGT return false; } -int SVGTextQuery::characterNumberAtPosition(const SVGPoint& position) const +int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const { if (m_textBoxes.isEmpty()) return -1; @@ -551,5 +549,3 @@ int SVGTextQuery::characterNumberAtPosition(const SVGPoint& position) const } } - -#endif |