本文整理汇总了C++中SVGInlineTextBox::textFragments方法的典型用法代码示例。如果您正苦于以下问题:C++ SVGInlineTextBox::textFragments方法的具体用法?C++ SVGInlineTextBox::textFragments怎么用?C++ SVGInlineTextBox::textFragments使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SVGInlineTextBox
的用法示例。
在下文中一共展示了SVGInlineTextBox::textFragments方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: positionForPoint
VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point)
{
if (!firstTextBox() || !textLength())
return createVisiblePosition(0, DOWNSTREAM);
float baseline = m_scaledFont.fontMetrics().floatAscent();
RenderBlock* containingBlock = this->containingBlock();
ASSERT(containingBlock);
// Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates.
FloatPoint absolutePoint(point);
absolutePoint.moveBy(containingBlock->location());
float closestDistance = std::numeric_limits<float>::max();
float closestDistancePosition = 0;
const SVGTextFragment* closestDistanceFragment = 0;
SVGInlineTextBox* closestDistanceBox = 0;
AffineTransform fragmentTransform;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
if (!box->isSVGInlineTextBox())
continue;
SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = fragments.at(i);
FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
fragment.buildFragmentTransform(fragmentTransform);
if (!fragmentTransform.isIdentity())
fragmentRect = fragmentTransform.mapRect(fragmentRect);
float distance = powf(fragmentRect.x() - absolutePoint.x(), 2) +
powf(fragmentRect.y() + fragmentRect.height() / 2 - absolutePoint.y(), 2);
if (distance < closestDistance) {
closestDistance = distance;
closestDistanceBox = textBox;
closestDistanceFragment = &fragment;
closestDistancePosition = fragmentRect.x();
}
}
}
if (!closestDistanceFragment)
return createVisiblePosition(0, DOWNSTREAM);
int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, absolutePoint.x() - closestDistancePosition, true);
return createVisiblePosition(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
示例2: paintTextMatchMarker
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);
}
}
}
}
示例3: positionForPoint
PositionWithAffinity LayoutSVGInlineText::positionForPoint(const LayoutPoint& point)
{
if (!hasTextBoxes() || !textLength())
return createPositionWithAffinity(0);
ASSERT(m_scalingFactor);
float baseline = m_scaledFont.getFontMetrics().floatAscent() / m_scalingFactor;
LayoutBlock* containingBlock = this->containingBlock();
ASSERT(containingBlock);
// Map local point to absolute point, as the character origins stored in the text fragments use absolute coordinates.
FloatPoint absolutePoint(point);
absolutePoint.moveBy(containingBlock->location());
float closestDistance = std::numeric_limits<float>::max();
float closestDistancePosition = 0;
const SVGTextFragment* closestDistanceFragment = nullptr;
SVGInlineTextBox* closestDistanceBox = nullptr;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
if (!box->isSVGInlineTextBox())
continue;
SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
for (const SVGTextFragment& fragment : textBox->textFragments()) {
FloatRect fragmentRect = fragment.boundingBox(baseline);
float distance = 0;
if (!fragmentRect.contains(absolutePoint))
distance = fragmentRect.squaredDistanceTo(absolutePoint);
if (distance <= closestDistance) {
closestDistance = distance;
closestDistanceBox = textBox;
closestDistanceFragment = &fragment;
closestDistancePosition = fragmentRect.x();
}
}
}
if (!closestDistanceFragment)
return createPositionWithAffinity(0);
int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, LayoutUnit(absolutePoint.x() - closestDistancePosition), true);
return createPositionWithAffinity(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : TextAffinity::Downstream);
}
示例4: 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();
}
示例5: fragmentString
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());
}
}
}
示例6: 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;
}
}
}
示例7: processTextChunk
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);
}
}
示例8: computeTextMatchMarkerRectForRenderer
void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText* textRenderer)
{
ASSERT(textRenderer);
Node* node = textRenderer->node();
if (!node || !node->inDocument())
return;
RenderStyle* style = textRenderer->style();
ASSERT(style);
AffineTransform fragmentTransform;
Document* document = textRenderer->document();
Vector<DocumentMarker*> markers = document->markers()->markersFor(textRenderer->node());
Vector<DocumentMarker*>::iterator markerEnd = markers.end();
for (Vector<DocumentMarker*>::iterator markerIt = markers.begin(); markerIt != markerEnd; ++markerIt) {
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()) {
if (!box->isSVGInlineTextBox())
continue;
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);
fragment.buildFragmentTransform(fragmentTransform);
if (!fragmentTransform.isIdentity())
fragmentRect = fragmentTransform.mapRect(fragmentRect);
markerRect.unite(fragmentRect);
}
}
toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
}
示例9: handleTextChunk
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);
}
}