本文整理汇总了C++中SVGInlineTextBox类的典型用法代码示例。如果您正苦于以下问题:C++ SVGInlineTextBox类的具体用法?C++ SVGInlineTextBox怎么用?C++ SVGInlineTextBox使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SVGInlineTextBox类的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: toRenderSVGInlineText
void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const FloatPoint&, DocumentMarker* marker, RenderStyle* style, const Font& font)
{
// SVG is only interested in the TextMatch markers.
if (marker->type() != DocumentMarker::TextMatch)
return;
RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
FloatRect markerRect;
AffineTransform fragmentTransform;
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (!box->isSVGInlineTextBox())
continue;
SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
int markerStartPosition = max<int>(marker->startOffset() - textBox->start(), 0);
int markerEndPosition = min<int>(marker->endOffset() - textBox->start(), textBox->len());
if (markerStartPosition >= markerEndPosition)
continue;
const Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = fragments.at(i);
int fragmentStartPosition = markerStartPosition;
int fragmentEndPosition = markerEndPosition;
if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
continue;
FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
fragment.buildFragmentTransform(fragmentTransform);
bool fragmentTransformIsIdentity = fragmentTransform.isIdentity();
// Draw the marker highlight.
if (renderer()->frame()->editor().markedTextMatchesAreHighlighted()) {
Color color = marker->activeMatch() ?
RenderTheme::theme().platformActiveTextSearchHighlightColor() :
RenderTheme::theme().platformInactiveTextSearchHighlightColor();
GraphicsContextStateSaver stateSaver(*context);
if (!fragmentTransformIsIdentity)
context->concatCTM(fragmentTransform);
context->setFillColor(color);
context->fillRect(fragmentRect, color);
}
if (!fragmentTransformIsIdentity)
fragmentRect = fragmentTransform.mapRect(fragmentRect);
markerRect.unite(fragmentRect);
}
}
toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
示例2: ASSERT
void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText* textRenderer)
{
ASSERT(textRenderer);
Node* node = textRenderer->node();
if (!node || !node->inDocument())
return;
RenderStyle* style = textRenderer->style();
ASSERT(style);
Document* document = textRenderer->document();
Vector<DocumentMarker> markers = document->markers()->markersForNode(textRenderer->node());
Vector<DocumentMarker>::iterator markerEnd = markers.end();
for (Vector<DocumentMarker>::iterator markerIt = markers.begin(); markerIt != markerEnd; ++markerIt) {
const DocumentMarker& marker = *markerIt;
// SVG is only interessted in the TextMatch marker, for now.
if (marker.type != DocumentMarker::TextMatch)
continue;
FloatRect markerRect;
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
ASSERT(box->isSVGInlineTextBox());
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(box);
int markerStartPosition = max<int>(marker.startOffset - textBox->start(), 0);
int markerEndPosition = min<int>(marker.endOffset - textBox->start(), textBox->len());
if (markerStartPosition >= markerEndPosition)
continue;
int fragmentStartPosition = 0;
int fragmentEndPosition = 0;
const Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = fragments.at(i);
fragmentStartPosition = markerStartPosition;
fragmentEndPosition = markerEndPosition;
if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
continue;
FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
if (!fragment.transform.isIdentity())
fragmentRect = fragment.transform.mapRect(fragmentRect);
markerRect.unite(fragmentRect);
}
}
document->markers()->setRenderedRectForMarker(node, marker, textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
}
示例3: ASSERT
void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRect)
{
for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
FloatRect boxRect;
if (child->isSVGInlineTextBox()) {
ASSERT(child->renderer().isSVGInlineText());
SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
boxRect = textBox->calculateBoundaries();
textBox->setX(boxRect.x());
textBox->setY(boxRect.y());
textBox->setLogicalWidth(boxRect.width());
textBox->setLogicalHeight(boxRect.height());
} else {
// Skip generated content.
if (!child->renderer().node())
continue;
ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());
SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
layoutChildBoxes(flowBox);
boxRect = flowBox->calculateBoundaries();
flowBox->setX(boxRect.x());
flowBox->setY(boxRect.y());
flowBox->setLogicalWidth(boxRect.width());
flowBox->setLogicalHeight(boxRect.height());
}
if (childRect)
childRect->unite(boxRect);
}
}
示例4: ASSERT
void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start)
{
for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
if (child->isSVGInlineTextBox()) {
ASSERT(child->renderer());
ASSERT(child->renderer()->isSVGInlineText());
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(child);
IntRect boxRect = textBox->calculateBoundaries();
textBox->setX(boxRect.x());
textBox->setY(boxRect.y());
textBox->setLogicalWidth(boxRect.width());
textBox->setLogicalHeight(boxRect.height());
} else {
ASSERT(child->isInlineFlowBox());
// Skip generated content.
if (!child->renderer()->node())
continue;
SVGInlineFlowBox* flowBox = static_cast<SVGInlineFlowBox*>(child);
layoutChildBoxes(flowBox);
IntRect boxRect = flowBox->calculateBoundaries();
flowBox->setX(boxRect.x());
flowBox->setY(boxRect.y());
flowBox->setLogicalWidth(boxRect.width());
flowBox->setLogicalHeight(boxRect.height());
}
}
}
示例5: finalizeTransformMatrices
void SVGTextLayoutEngine::finalizeTransformMatrices(Vector<SVGInlineTextBox*>& boxes)
{
unsigned boxCount = boxes.size();
if (!boxCount)
return;
for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
SVGInlineTextBox* textBox = boxes.at(boxPosition);
AffineTransform textBoxTransformation = m_chunkLayoutBuilder.transformationForTextBox(textBox);
if (textBoxTransformation.isIdentity())
continue;
Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned fragmentCount = fragments.size();
for (unsigned i = 0; i < fragmentCount; ++i) {
ASSERT(fragments[i].lengthAdjustTransform.isIdentity());
fragments[i].lengthAdjustTransform = textBoxTransformation;
}
}
boxes.clear();
}
示例6: dumpTextBoxes
static inline void dumpTextBoxes(Vector<SVGInlineTextBox*>& boxes)
{
unsigned boxCount = boxes.size();
fprintf(stderr, "Dumping all text fragments in text sub tree, %i boxes\n", boxCount);
for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
SVGInlineTextBox* textBox = boxes.at(boxPosition);
Vector<SVGTextFragment>& fragments = textBox->textFragments();
fprintf(stderr, "-> Box %i: Dumping text fragments for SVGInlineTextBox, textBox=%p, textRenderer=%p\n", boxPosition, textBox, textBox->textRenderer());
fprintf(stderr, " textBox properties, start=%i, len=%i, box direction=%i\n", textBox->start(), textBox->len(), textBox->direction());
fprintf(stderr, " textRenderer properties, textLength=%i\n", textBox->textRenderer()->textLength());
const UChar* characters = textBox->textRenderer()->characters();
unsigned fragmentCount = fragments.size();
for (unsigned i = 0; i < fragmentCount; ++i) {
SVGTextFragment& fragment = fragments.at(i);
String fragmentString(characters + fragment.characterOffset, fragment.length);
fprintf(stderr, " -> Fragment %i, x=%lf, y=%lf, width=%lf, height=%lf, characterOffset=%i, length=%i, characters='%s'\n"
, i, fragment.x, fragment.y, fragment.width, fragment.height, fragment.characterOffset, fragment.length, fragmentString.utf8().data());
}
}
}
示例7: calculateLength
void SVGTextChunk::calculateLength(float& length, unsigned& characters) const
{
SVGTextFragment* lastFragment = 0;
unsigned boxCount = m_boxes.size();
for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
SVGInlineTextBox* textBox = m_boxes.at(boxPosition);
Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned size = fragments.size();
if (!size)
continue;
for (unsigned i = 0; i < size; ++i) {
SVGTextFragment& fragment = fragments.at(i);
characters += fragment.length;
if (m_chunkStyle & VerticalText)
length += fragment.height;
else
length += fragment.width;
if (!lastFragment) {
lastFragment = &fragment;
continue;
}
// Resepect gap between chunks.
if (m_chunkStyle & VerticalText)
length += fragment.y - (lastFragment->y + lastFragment->height);
else
length += fragment.x - (lastFragment->x + lastFragment->width);
lastFragment = &fragment;
}
}
}
示例8: findInlineTextBoxInTextChunks
static Vector<SVGInlineTextBox*> findInlineTextBoxInTextChunks(const SVGTextContentElement* element, const Vector<SVGTextChunk>& chunks)
{
Vector<SVGTextChunk>::const_iterator it = chunks.begin();
const Vector<SVGTextChunk>::const_iterator end = chunks.end();
Vector<SVGInlineTextBox*> boxes;
for (; it != end; ++it) {
Vector<SVGInlineBoxCharacterRange>::const_iterator boxIt = it->boxes.begin();
const Vector<SVGInlineBoxCharacterRange>::const_iterator boxEnd = it->boxes.end();
for (; boxIt != boxEnd; ++boxIt) {
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(boxIt->box);
Node* textElement = textBox->textObject()->parent()->element();
ASSERT(textElement);
if (textElement == element || textElement->parent() == element)
boxes.append(textBox);
}
}
return boxes;
}
示例9: reverseInlineBoxRangeAndValueListsIfNeeded
static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Vector<InlineBox*>::iterator first, Vector<InlineBox*>::iterator last)
{
ASSERT(userData);
Vector<SVGTextLayoutAttributes*>& attributes = *reinterpret_cast<Vector<SVGTextLayoutAttributes*>*>(userData);
// This is a copy of std::reverse(first, last). It additionally assures that the metrics map within the renderers belonging to the InlineBoxes are reordered as well.
while (true) {
if (first == last || first == --last)
return;
if (!(*last)->isSVGInlineTextBox() || !(*first)->isSVGInlineTextBox()) {
InlineBox* temp = *first;
*first = *last;
*last = temp;
++first;
continue;
}
SVGInlineTextBox* firstTextBox = toSVGInlineTextBox(*first);
SVGInlineTextBox* lastTextBox = toSVGInlineTextBox(*last);
// Reordering is only necessary for BiDi text that is _absolutely_ positioned.
if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len()) {
RenderSVGInlineText& firstContext = firstTextBox->renderer();
RenderSVGInlineText& lastContext = lastTextBox->renderer();
SVGTextLayoutAttributes* firstAttributes = 0;
SVGTextLayoutAttributes* lastAttributes = 0;
findFirstAndLastAttributesInVector(attributes, &firstContext, &lastContext, firstAttributes, lastAttributes);
swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTextBox->start(), lastTextBox->start());
}
InlineBox* temp = *first;
*first = *last;
*last = temp;
++first;
}
}
示例10: toLayoutSVGInlineText
void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* context, const LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font& font)
{
// SVG is only interested in the TextMatch markers.
if (marker->type() != DocumentMarker::TextMatch)
return;
LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(m_svgInlineTextBox.layoutObject());
AffineTransform fragmentTransform;
for (InlineTextBox* box = textLayoutObject.firstTextBox(); box; box = box->nextTextBox()) {
if (!box->isSVGInlineTextBox())
continue;
SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
int markerStartPosition = std::max<int>(marker->startOffset() - textBox->start(), 0);
int markerEndPosition = std::min<int>(marker->endOffset() - textBox->start(), textBox->len());
if (markerStartPosition >= markerEndPosition)
continue;
const Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = fragments.at(i);
int fragmentStartPosition = markerStartPosition;
int fragmentEndPosition = markerEndPosition;
if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
continue;
FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
fragment.buildFragmentTransform(fragmentTransform);
// Draw the marker highlight.
if (m_svgInlineTextBox.layoutObject().frame()->editor().markedTextMatchesAreHighlighted()) {
Color color = marker->activeMatch() ?
LayoutTheme::theme().platformActiveTextSearchHighlightColor() :
LayoutTheme::theme().platformInactiveTextSearchHighlightColor();
GraphicsContextStateSaver stateSaver(*context);
if (!fragmentTransform.isIdentity())
context->concatCTM(fragmentTransform);
context->setFillColor(color);
context->fillRect(fragmentRect, color);
}
}
}
}
示例11: createVisiblePosition
VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
{
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(firstTextBox());
if (!textBox || textLength() == 0)
return createVisiblePosition(0, DOWNSTREAM);
SVGRootInlineBox* rootBox = textBox->svgRootInlineBox();
RenderBlock* object = rootBox ? rootBox->block() : 0;
if (!object)
return createVisiblePosition(0, DOWNSTREAM);
int closestOffsetInBox = 0;
// FIXME: This approach is wrong. The correct code would first find the
// closest SVGInlineTextBox to the point, and *then* ask only that inline box
// what the closest text offset to that point is. This code instead walks
// through all boxes in order, so when you click "near" a box, you'll actually
// end up returning the nearest offset in the last box, even if the
// nearest offset to your click is contained in another box.
for (SVGInlineTextBox* box = textBox; box; box = static_cast<SVGInlineTextBox*>(box->nextTextBox())) {
if (box->svgCharacterHitsPosition(point.x() + object->x(), point.y() + object->y(), closestOffsetInBox)) {
// If we're not at the end/start of the box, stop looking for other selected boxes.
if (box->direction() == LTR) {
if (closestOffsetInBox <= (int) box->end() + 1)
break;
} else {
if (closestOffsetInBox > (int) box->start())
break;
}
}
}
return createVisiblePosition(closestOffsetInBox, DOWNSTREAM);
}
示例12: cummulatedWidthOrHeightOfTextChunk
static float cummulatedWidthOrHeightOfTextChunk(SVGTextChunk& chunk, bool calcWidthOnly)
{
float length = 0.0f;
Vector<SVGChar>::iterator charIt = chunk.start;
Vector<SVGInlineBoxCharacterRange>::iterator it = chunk.boxes.begin();
Vector<SVGInlineBoxCharacterRange>::iterator end = chunk.boxes.end();
for (; it != end; ++it) {
SVGInlineBoxCharacterRange& range = *it;
SVGInlineTextBox* box = static_cast<SVGInlineTextBox*>(range.box);
RenderStyle* style = box->renderer()->style();
for (int i = range.startOffset; i < range.endOffset; ++i) {
ASSERT(charIt <= chunk.end);
// Determine how many characters - starting from the current - can be measured at once.
// Important for non-absolute positioned non-latin1 text (ie. Arabic) where ie. the width
// of a string is not the sum of the boundaries of all contained glyphs.
Vector<SVGChar>::iterator itSearch = charIt + 1;
Vector<SVGChar>::iterator endSearch = charIt + range.endOffset - i;
while (itSearch != endSearch) {
// No need to check for 'isHidden()' here as this function is not called for text paths.
if (itSearch->drawnSeperated)
break;
itSearch++;
}
unsigned int positionOffset = itSearch - charIt;
// Calculate width/height of subrange
SVGInlineBoxCharacterRange subRange;
subRange.box = range.box;
subRange.startOffset = i;
subRange.endOffset = i + positionOffset;
if (calcWidthOnly)
length += cummulatedWidthOfInlineBoxCharacterRange(subRange);
else
length += cummulatedHeightOfInlineBoxCharacterRange(subRange);
// Calculate gap between the previous & current range
// <text x="10 50 70">ABCD</text> - we need to take the gaps between A & B into account
// so add "40" as width, and analogous for B & C, add "20" as width.
if (itSearch > chunk.start && itSearch < chunk.end) {
SVGChar& lastCharacter = *(itSearch - 1);
SVGChar& currentCharacter = *itSearch;
int charsConsumed = 0;
float glyphWidth = 0.0f;
float glyphHeight = 0.0f;
String glyphName;
String unicodeString;
box->measureCharacter(style, i + positionOffset - 1, charsConsumed, glyphName, unicodeString, glyphWidth, glyphHeight);
if (calcWidthOnly)
length += currentCharacter.x - lastCharacter.x - glyphWidth;
else
length += currentCharacter.y - lastCharacter.y - glyphHeight;
}
// Advance processed characters
i += positionOffset - 1;
charIt = itSearch;
}
}
ASSERT(charIt == chunk.end);
return length;
}
示例13: processTextLengthSpacingCorrection
void SVGTextChunkBuilder::processTextChunk(const SVGTextChunk& chunk)
{
bool processTextLength = chunk.hasDesiredTextLength();
bool processTextAnchor = chunk.hasTextAnchor();
if (!processTextAnchor && !processTextLength)
return;
const Vector<SVGInlineTextBox*>& boxes = chunk.boxes();
unsigned boxCount = boxes.size();
if (!boxCount)
return;
// Calculate absolute length of whole text chunk (starting from text box 'start', spanning 'length' text boxes).
float chunkLength = 0;
unsigned chunkCharacters = 0;
chunk.calculateLength(chunkLength, chunkCharacters);
bool isVerticalText = chunk.isVerticalText();
if (processTextLength) {
if (chunk.hasLengthAdjustSpacing()) {
float textLengthShift = (chunk.desiredTextLength() - chunkLength) / chunkCharacters;
unsigned atCharacter = 0;
for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
Vector<SVGTextFragment>& fragments = boxes[boxPosition]->textFragments();
if (fragments.isEmpty())
continue;
processTextLengthSpacingCorrection(isVerticalText, textLengthShift, fragments, atCharacter);
}
} else {
ASSERT(chunk.hasLengthAdjustSpacingAndGlyphs());
float textLengthScale = chunk.desiredTextLength() / chunkLength;
AffineTransform spacingAndGlyphsTransform;
bool foundFirstFragment = false;
for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
SVGInlineTextBox* textBox = boxes[boxPosition];
Vector<SVGTextFragment>& fragments = textBox->textFragments();
if (fragments.isEmpty())
continue;
if (!foundFirstFragment) {
foundFirstFragment = true;
buildSpacingAndGlyphsTransform(isVerticalText, textLengthScale, fragments.first(), spacingAndGlyphsTransform);
}
m_textBoxTransformations.set(textBox, spacingAndGlyphsTransform);
}
}
}
if (!processTextAnchor)
return;
// If we previously applied a lengthAdjust="spacing" correction, we have to recalculate the chunk length, to be able to apply the text-anchor shift.
if (processTextLength && chunk.hasLengthAdjustSpacing()) {
chunkLength = 0;
chunkCharacters = 0;
chunk.calculateLength(chunkLength, chunkCharacters);
}
float textAnchorShift = chunk.calculateTextAnchorShift(chunkLength);
for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
Vector<SVGTextFragment>& fragments = boxes[boxPosition]->textFragments();
if (fragments.isEmpty())
continue;
processTextAnchorCorrection(isVerticalText, textAnchorShift, fragments);
}
}
示例14: ASSERT
void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart,
BoxListConstIterator boxEnd) {
ASSERT(*boxStart);
const LineLayoutSVGInlineText textLineLayout =
LineLayoutSVGInlineText((*boxStart)->getLineLayoutItem());
const ComputedStyle& style = textLineLayout.styleRef();
// Handle 'lengthAdjust' property.
float desiredTextLength = 0;
SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown;
if (SVGTextContentElement* textContentElement =
SVGTextContentElement::elementFromLineLayoutItem(
textLineLayout.parent())) {
lengthAdjust =
textContentElement->lengthAdjust()->currentValue()->enumValue();
SVGLengthContext lengthContext(textContentElement);
if (textContentElement->textLengthIsSpecifiedByUser())
desiredTextLength =
textContentElement->textLength()->currentValue()->value(
lengthContext);
else
desiredTextLength = 0;
}
bool processTextLength = desiredTextLength > 0;
bool processTextAnchor = needsTextAnchorAdjustment(style);
if (!processTextAnchor && !processTextLength)
return;
bool isVerticalText = !style.isHorizontalWritingMode();
// Calculate absolute length of whole text chunk (starting from text box
// 'start', spanning 'length' text boxes).
ChunkLengthAccumulator lengthAccumulator(isVerticalText);
lengthAccumulator.processRange(boxStart, boxEnd);
if (processTextLength) {
float chunkLength = lengthAccumulator.length();
if (lengthAdjust == SVGLengthAdjustSpacing) {
float textLengthShift =
(desiredTextLength - chunkLength) / lengthAccumulator.numCharacters();
unsigned atCharacter = 0;
for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) {
Vector<SVGTextFragment>& fragments = (*boxIter)->textFragments();
if (fragments.isEmpty())
continue;
processTextLengthSpacingCorrection(isVerticalText, textLengthShift,
fragments, atCharacter);
}
// Fragments have been adjusted, we have to recalculate the chunk
// length, to be able to apply the text-anchor shift.
if (processTextAnchor) {
lengthAccumulator.reset();
lengthAccumulator.processRange(boxStart, boxEnd);
}
} else {
ASSERT(lengthAdjust == SVGLengthAdjustSpacingAndGlyphs);
float textLengthScale = desiredTextLength / chunkLength;
float textLengthBias = 0;
bool foundFirstFragment = false;
for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) {
SVGInlineTextBox* textBox = *boxIter;
Vector<SVGTextFragment>& fragments = textBox->textFragments();
if (fragments.isEmpty())
continue;
if (!foundFirstFragment) {
foundFirstFragment = true;
textLengthBias =
computeTextLengthBias(fragments.first(), textLengthScale);
}
applyTextLengthScaleAdjustment(textLengthScale, textLengthBias,
fragments);
}
}
}
if (!processTextAnchor)
return;
float textAnchorShift =
calculateTextAnchorShift(style, lengthAccumulator.length());
for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) {
Vector<SVGTextFragment>& fragments = (*boxIter)->textFragments();
if (fragments.isEmpty())
continue;
processTextAnchorCorrection(isVerticalText, textAnchorShift, fragments);
}
}