summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/svg/SVGTextQuery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/svg/SVGTextQuery.cpp')
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.cpp108
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