本文整理汇总了C++中InlineTextBox::start方法的典型用法代码示例。如果您正苦于以下问题:C++ InlineTextBox::start方法的具体用法?C++ InlineTextBox::start怎么用?C++ InlineTextBox::start使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类InlineTextBox
的用法示例。
在下文中一共展示了InlineTextBox::start方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: upstream
Position Position::upstream(EStayInBlock stayInBlock) const
{
Position start = equivalentDeepPosition();
NodeImpl *startNode = start.node();
if (!startNode)
return Position();
NodeImpl *block = startNode->enclosingBlockFlowOrTableElement();
Position lastVisible;
PositionIterator it(start);
for (; !it.atStart(); it.previous()) {
NodeImpl *currentNode = it.current().node();
if (stayInBlock) {
NodeImpl *currentBlock = currentNode->enclosingBlockFlowOrTableElement();
if (block != currentBlock)
return it.next();
}
RenderObject *renderer = currentNode->renderer();
if (!renderer)
continue;
if (renderer->style()->visibility() != VISIBLE)
continue;
lastVisible = it.current();
if (renderer->isReplaced() || renderer->isBR()) {
if (it.current().offset() >= renderer->caretMaxOffset())
return Position(currentNode, renderer->caretMaxOffset());
else
continue;
}
if (renderer->isText() && static_cast<RenderText *>(renderer)->firstTextBox()) {
if (currentNode != startNode)
return Position(currentNode, renderer->caretMaxOffset());
if (it.current().offset() < 0)
continue;
uint textOffset = it.current().offset();
RenderText *textRenderer = static_cast<RenderText *>(renderer);
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (textOffset > box->start() && textOffset <= box->start() + box->len())
return it.current();
else if (box != textRenderer->lastTextBox() &&
!box->nextOnLine() &&
textOffset == box->start() + box->len() + 1)
return it.current();
}
}
}
return lastVisible.isNotNull() ? lastVisible : *this;
}
示例2: logicalEndPositionForLine
static VisiblePosition logicalEndPositionForLine(const VisiblePosition& c)
{
if (c.isNull())
return VisiblePosition();
RootInlineBox* rootBox = rootBoxForLine(c);
if (!rootBox) {
// There are VisiblePositions at offset 0 in blocks without
// RootInlineBoxes, like empty editable blocks and bordered blocks.
Position p = c.deepEquivalent();
if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && !p.deprecatedEditingOffset())
return c;
return VisiblePosition();
}
InlineBox* logicalEndBox;
Node* logicalEndNode;
getLogicalEndBoxAndNode(rootBox, logicalEndBox, logicalEndNode);
if (!logicalEndNode)
return VisiblePosition();
int endOffset = 1;
if (logicalEndNode->hasTagName(brTag))
endOffset = 0;
else if (logicalEndBox->isInlineTextBox()) {
InlineTextBox* endTextBox = static_cast<InlineTextBox*>(logicalEndBox);
endOffset = endTextBox->start();
if (!endTextBox->isLineBreak())
endOffset += endTextBox->len();
}
return VisiblePosition(logicalEndNode, endOffset, VP_UPSTREAM_IF_POSSIBLE);
}
示例3: localCaretRect
LayoutRect LayoutSVGInlineText::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit*)
{
if (!box || !box->isInlineTextBox())
return LayoutRect();
InlineTextBox* textBox = toInlineTextBox(box);
if (static_cast<unsigned>(caretOffset) < textBox->start() || static_cast<unsigned>(caretOffset) > textBox->start() + textBox->len())
return LayoutRect();
// Use the edge of the selection rect to determine the caret rect.
if (static_cast<unsigned>(caretOffset) < textBox->start() + textBox->len()) {
LayoutRect rect = textBox->localSelectionRect(caretOffset, caretOffset + 1);
LayoutUnit x = box->isLeftToRightDirection() ? rect.x() : rect.maxX();
return LayoutRect(x, rect.y(), caretWidth, rect.height());
}
LayoutRect rect = textBox->localSelectionRect(caretOffset - 1, caretOffset);
LayoutUnit x = box->isLeftToRightDirection() ? rect.maxX() : rect.x();
return LayoutRect(x, rect.y(), caretWidth, rect.height());
}
示例4: ellipsisRectForBox
static IntRect ellipsisRectForBox(const InlineTextBox& box, unsigned start, unsigned end)
{
unsigned truncation = box.truncation();
if (truncation == cNoTruncation)
return IntRect();
auto ellipsis = box.root().ellipsisBox();
if (!ellipsis)
return IntRect();
IntRect rect;
unsigned ellipsisStartPosition = start > box.start() ? start - box.start() : 0;
ASSERT(end >= box.start());
unsigned ellipsisEndPosition = std::min(end - box.start(), box.len());
// The ellipsis should be considered to be selected if the end of
// the selection is past the beginning of the truncation and the
// beginning of the selection is before or at the beginning of the truncation.
if (ellipsisEndPosition < truncation && ellipsisStartPosition > truncation)
return IntRect();
return ellipsis->selectionRect();
}
示例5: writeTextRun
static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBox& run)
{
// FIXME: Table cell adjustment is temporary until results can be updated.
int y = run.m_y;
if (o.containingBlock()->isTableCell())
y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingTop();
ts << "text run at (" << run.m_x << "," << y << ") width " << run.m_width;
if (run.direction() == RTL || run.m_dirOverride) {
ts << (run.direction() == RTL ? " RTL" : " LTR");
if (run.m_dirOverride)
ts << " override";
}
ts << ": "
<< quoteAndEscapeNonPrintables(String(o.text()).substring(run.start(), run.len()))
<< "\n";
}
示例6: endPositionForLine
static VisiblePosition endPositionForLine(const VisiblePosition& c)
{
if (c.isNull())
return VisiblePosition();
RootInlineBox *rootBox = rootBoxForLine(c);
if (!rootBox) {
// There are VisiblePositions at offset 0 in blocks without
// RootInlineBoxes, like empty editable blocks and bordered blocks.
Position p = c.deepEquivalent();
if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.deprecatedEditingOffset() == 0)
return c;
return VisiblePosition();
}
// Generated content (e.g. list markers and CSS :before and :after
// pseudoelements) have no corresponding DOM element, and so cannot be
// represented by a VisiblePosition. Use whatever precedes instead.
Node *endNode;
InlineBox *endBox = rootBox->lastLeafChild();
while (1) {
if (!endBox)
return VisiblePosition();
RenderObject *endRenderer = endBox->renderer();
if (!endRenderer)
return VisiblePosition();
endNode = endRenderer->node();
if (endNode)
break;
endBox = endBox->prevLeafChild();
}
int endOffset = 1;
if (endNode->hasTagName(brTag)) {
endOffset = 0;
} else if (endBox->isInlineTextBox()) {
InlineTextBox *endTextBox = static_cast<InlineTextBox *>(endBox);
endOffset = endTextBox->start();
if (!endTextBox->isLineBreak())
endOffset += endTextBox->len();
}
return VisiblePosition(endNode, endOffset, VP_UPSTREAM_IF_POSSIBLE);
}
示例7: startPositionForLine
static VisiblePosition startPositionForLine(const VisiblePosition& c)
{
if (c.isNull())
return VisiblePosition();
RootInlineBox *rootBox = rootBoxForLine(c);
if (!rootBox) {
// There are VisiblePositions at offset 0 in blocks without
// RootInlineBoxes, like empty editable blocks and bordered blocks.
Position p = c.deepEquivalent();
if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.deprecatedEditingOffset() == 0)
return positionAvoidingFirstPositionInTable(c);
return VisiblePosition();
}
// Generated content (e.g. list markers and CSS :before and :after
// pseudoelements) have no corresponding DOM element, and so cannot be
// represented by a VisiblePosition. Use whatever follows instead.
InlineBox *startBox = rootBox->firstLeafChild();
Node *startNode;
while (1) {
if (!startBox)
return VisiblePosition();
RenderObject *startRenderer = startBox->renderer();
if (!startRenderer)
return VisiblePosition();
startNode = startRenderer->node();
if (startNode)
break;
startBox = startBox->nextLeafChild();
}
int startOffset = 0;
if (startBox->isInlineTextBox()) {
InlineTextBox *startTextBox = static_cast<InlineTextBox *>(startBox);
startOffset = startTextBox->start();
}
VisiblePosition visPos = VisiblePosition(startNode, startOffset, DOWNSTREAM);
return positionAvoidingFirstPositionInTable(visPos);
}
示例8: writeTextRun
static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBox& run)
{
// FIXME: For now use an "enclosingIntRect" model for x, y and logicalWidth, although this makes it harder
// to detect any changes caused by the conversion to floating point. :(
int x = run.x();
int y = run.y();
int logicalWidth = ceilf(run.left() + run.logicalWidth()) - x;
ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
if (!run.isLeftToRightDirection() || run.dirOverride()) {
ts << (!run.isLeftToRightDirection() ? " RTL" : " LTR");
if (run.dirOverride())
ts << " override";
}
ts << ": "
<< quoteAndEscapeNonPrintables(String(o.text()).substring(run.start(), run.len()));
if (run.hasHyphen())
ts << " + hyphen string " << quoteAndEscapeNonPrintables(o.style()->hyphenString());
ts << "\n";
}
示例9: writeTextRun
static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBox& run)
{
// FIXME: For now use an "enclosingIntRect" model for x, y and logicalWidth, although this makes it harder
// to detect any changes caused by the conversion to floating point. :(
int x = run.m_x;
int y = run.m_y;
int logicalWidth = ceilf(run.m_x + run.m_logicalWidth) - x;
// FIXME: Table cell adjustment is temporary until results can be updated.
if (o.containingBlock()->isTableCell())
y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore();
ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
if (!run.isLeftToRightDirection() || run.m_dirOverride) {
ts << (!run.isLeftToRightDirection() ? " RTL" : " LTR");
if (run.m_dirOverride)
ts << " override";
}
ts << ": "
<< quoteAndEscapeNonPrintables(String(o.text()).substring(run.start(), run.len()));
if (run.hasHyphen())
ts << " + hyphen string " << quoteAndEscapeNonPrintables(o.style()->hyphenString());
ts << "\n";
}
示例10: downstream
// P.downstream() returns the end of the range of positions that map to the same VisiblePosition as P.
Position Position::downstream() const
{
Node* startNode = node();
if (!startNode)
return Position();
// iterate forward from there, looking for a qualified position
Node* block = enclosingBlock(startNode);
PositionIterator lastVisible = *this;
PositionIterator currentPos = lastVisible;
Node* originalRoot = node()->rootEditableElement();
for (; !currentPos.atEnd(); currentPos.increment()) {
Node* currentNode = currentPos.node();
if (currentNode->rootEditableElement() != originalRoot)
break;
// stop before going above the body, up into the head
// return the last visible streamer position
if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
break;
// Do not enter a new enclosing block flow or table element, and don't leave the original one.
if (block != enclosingBlock(currentNode))
return lastVisible;
// skip position in unrendered or invisible node
RenderObject* renderer = currentNode->renderer();
if (!renderer || renderer->style()->visibility() != VISIBLE)
continue;
// track last visible streamer position
if (isStreamer(currentPos))
lastVisible = currentPos;
// Return position before brs, tables, and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || renderer->isBR() || isTableElement(currentNode)) {
if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
return Position(currentNode, renderer->caretMinOffset());
continue;
}
// return current position if it is in rendered text
if (renderer->isText() && static_cast<RenderText*>(renderer)->firstTextBox()) {
if (currentNode != startNode) {
ASSERT(currentPos.atStartOfNode());
return Position(currentNode, renderer->caretMinOffset());
}
unsigned textOffset = currentPos.offsetInLeafNode();
RenderText* textRenderer = static_cast<RenderText*>(renderer);
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (textOffset >= box->start() && textOffset <= box->end())
return currentPos;
if (box != textRenderer->lastTextBox() &&
!box->nextOnLine() &&
textOffset == box->start() + box->len()) {
return currentPos;
}
}
}
}
return lastVisible;
}
示例11: createVisiblePositionAfterAdjustingOffsetForBiDi
static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const InlineTextBox& box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
{
ASSERT(offset >= 0);
if (offset && static_cast<unsigned>(offset) < box.len())
return createVisiblePositionForBox(box, box.start() + offset, shouldAffinityBeDownstream);
bool positionIsAtStartOfBox = !offset;
if (positionIsAtStartOfBox == box.isLeftToRightDirection()) {
// offset is on the left edge
const InlineBox* prevBox = box.prevLeafChildIgnoringLineBreak();
if ((prevBox && prevBox->bidiLevel() == box.bidiLevel())
|| box.renderer().containingBlock()->style().direction() == box.direction()) // FIXME: left on 12CBA
return createVisiblePositionForBox(box, box.caretLeftmostOffset(), shouldAffinityBeDownstream);
if (prevBox && prevBox->bidiLevel() > box.bidiLevel()) {
// e.g. left of B in aDC12BAb
const InlineBox* leftmostBox;
do {
leftmostBox = prevBox;
prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
} while (prevBox && prevBox->bidiLevel() > box.bidiLevel());
return createVisiblePositionForBox(*leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream);
}
if (!prevBox || prevBox->bidiLevel() < box.bidiLevel()) {
// e.g. left of D in aDC12BAb
const InlineBox* rightmostBox;
const InlineBox* nextBox = &box;
do {
rightmostBox = nextBox;
nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
} while (nextBox && nextBox->bidiLevel() >= box.bidiLevel());
return createVisiblePositionForBox(*rightmostBox,
box.isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream);
}
return createVisiblePositionForBox(box, box.caretRightmostOffset(), shouldAffinityBeDownstream);
}
const InlineBox* nextBox = box.nextLeafChildIgnoringLineBreak();
if ((nextBox && nextBox->bidiLevel() == box.bidiLevel())
|| box.renderer().containingBlock()->style().direction() == box.direction())
return createVisiblePositionForBox(box, box.caretRightmostOffset(), shouldAffinityBeDownstream);
// offset is on the right edge
if (nextBox && nextBox->bidiLevel() > box.bidiLevel()) {
// e.g. right of C in aDC12BAb
const InlineBox* rightmostBox;
do {
rightmostBox = nextBox;
nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
} while (nextBox && nextBox->bidiLevel() > box.bidiLevel());
return createVisiblePositionForBox(*rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream);
}
if (!nextBox || nextBox->bidiLevel() < box.bidiLevel()) {
// e.g. right of A in aDC12BAb
const InlineBox* leftmostBox;
const InlineBox* prevBox = &box;
do {
leftmostBox = prevBox;
prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
} while (prevBox && prevBox->bidiLevel() >= box.bidiLevel());
return createVisiblePositionForBox(*leftmostBox,
box.isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream);
}
return createVisiblePositionForBox(box, box.caretLeftmostOffset(), shouldAffinityBeDownstream);
}
示例12: positionForPoint
VisiblePosition RenderTextLineBoxes::positionForPoint(const RenderText& renderer, const LayoutPoint& point) const
{
if (!m_first || !renderer.textLength())
return renderer.createVisiblePosition(0, DOWNSTREAM);
LayoutUnit pointLineDirection = m_first->isHorizontal() ? point.x() : point.y();
LayoutUnit pointBlockDirection = m_first->isHorizontal() ? point.y() : point.x();
bool blocksAreFlipped = renderer.style().isFlippedBlocksWritingMode();
InlineTextBox* lastBox = nullptr;
for (auto box = m_first; box; box = box->nextTextBox()) {
if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
box = box->nextTextBox();
auto& rootBox = box->root();
LayoutUnit top = std::min(rootBox.selectionTop(), rootBox.lineTop());
if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) {
LayoutUnit bottom = rootBox.selectionBottom();
if (rootBox.nextRootBox())
bottom = std::min(bottom, rootBox.nextRootBox()->lineTop());
if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
#if PLATFORM(IOS)
if (pointLineDirection != box->logicalLeft() && point.x() < box->x() + box->logicalWidth()) {
int half = box->x() + box->logicalWidth() / 2;
EAffinity affinity = point.x() < half ? DOWNSTREAM : VP_UPSTREAM_IF_POSSIBLE;
return renderer.createVisiblePosition(box->offsetForPosition(pointLineDirection) + box->start(), affinity);
}
#endif
if (lineDirectionPointFitsInBox(pointLineDirection, *box, shouldAffinityBeDownstream))
return createVisiblePositionAfterAdjustingOffsetForBiDi(*box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
}
}
lastBox = box;
}
if (lastBox) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
lineDirectionPointFitsInBox(pointLineDirection, *lastBox, shouldAffinityBeDownstream);
return createVisiblePositionAfterAdjustingOffsetForBiDi(*lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
}
return renderer.createVisiblePosition(0, DOWNSTREAM);
}
示例13: getRanges
void RenderNamedFlowThread::getRanges(Vector<RefPtr<Range> >& rangeObjects, const RenderRegion* region) const
{
LayoutUnit logicalTopForRegion;
LayoutUnit logicalBottomForRegion;
// extend the first region top to contain everything up to its logical height
if (region->isFirstRegion())
logicalTopForRegion = LayoutUnit::min();
else
logicalTopForRegion = region->logicalTopForFlowThreadContent();
// extend the last region to contain everything above its y()
if (region->isLastRegion())
logicalBottomForRegion = LayoutUnit::max();
else
logicalBottomForRegion = region->logicalBottomForFlowThreadContent();
Vector<Node*> nodes;
// eliminate the contentNodes that are descendants of other contentNodes
for (NamedFlowContentNodes::const_iterator it = contentNodes().begin(); it != contentNodes().end(); ++it) {
Node* node = *it;
if (!isContainedInNodes(nodes, node))
nodes.append(node);
}
for (size_t i = 0; i < nodes.size(); i++) {
Node* contentNode = nodes.at(i);
if (!contentNode->renderer())
continue;
RefPtr<Range> range = Range::create(contentNode->document());
bool foundStartPosition = false;
bool startsAboveRegion = true;
bool endsBelowRegion = true;
bool skipOverOutsideNodes = false;
Node* lastEndNode = 0;
for (Node* node = contentNode; node; node = nextNodeInsideContentNode(node, contentNode)) {
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
LayoutRect boundingBox;
if (renderer->isRenderInline())
boundingBox = toRenderInline(renderer)->linesBoundingBox();
else if (renderer->isText())
boundingBox = toRenderText(renderer)->linesBoundingBox();
else {
boundingBox = toRenderBox(renderer)->frameRect();
if (toRenderBox(renderer)->isRelPositioned())
boundingBox.move(toRenderBox(renderer)->relativePositionLogicalOffset());
}
LayoutUnit offsetTop = renderer->containingBlock()->offsetFromLogicalTopOfFirstPage();
const LayoutPoint logicalOffsetFromTop(isHorizontalWritingMode() ? LayoutUnit() : offsetTop,
isHorizontalWritingMode() ? offsetTop : LayoutUnit());
boundingBox.moveBy(logicalOffsetFromTop);
LayoutUnit logicalTopForRenderer = region->logicalTopOfFlowThreadContentRect(boundingBox);
LayoutUnit logicalBottomForRenderer = region->logicalBottomOfFlowThreadContentRect(boundingBox);
// if the bounding box of the current element doesn't intersect the region box
// close the current range only if the start element began inside the region,
// otherwise just move the start position after this node and keep skipping them until we found a proper start position.
if (!boxIntersectsRegion(logicalTopForRenderer, logicalBottomForRenderer, logicalTopForRegion, logicalBottomForRegion)) {
if (foundStartPosition) {
if (!startsAboveRegion) {
if (range->intersectsNode(node, IGNORE_EXCEPTION))
range->setEndBefore(node, IGNORE_EXCEPTION);
rangeObjects.append(range->cloneRange(IGNORE_EXCEPTION));
range = Range::create(contentNode->document());
startsAboveRegion = true;
} else
skipOverOutsideNodes = true;
}
if (skipOverOutsideNodes)
range->setStartAfter(node, IGNORE_EXCEPTION);
foundStartPosition = false;
continue;
}
// start position
if (logicalTopForRenderer < logicalTopForRegion && startsAboveRegion) {
if (renderer->isText()) { // Text crosses region top
// for Text elements, just find the last textbox that is contained inside the region and use its start() offset as start position
RenderText* textRenderer = toRenderText(renderer);
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (offsetTop + box->logicalBottom() < logicalTopForRegion)
continue;
range->setStart(Position(toText(node), box->start()));
startsAboveRegion = false;
break;
}
} else { // node crosses region top
// for all elements, except Text, just set the start position to be before their children
startsAboveRegion = true;
range->setStart(Position(node, Position::PositionIsBeforeChildren));
}
} else { // node starts inside region
//.........这里部分代码省略.........
示例14: placePositionedBoxesHorizontally
static int placePositionedBoxesHorizontally(InlineFlowBox* flow, int x, int& leftPosition, int& rightPosition, int& leftAlign, int& rightAlign, bool& needsWordSpacing, int xPos, bool positioned)
{
int mn = INT_MAX;
int mx = INT_MIN;
int amn = INT_MAX;
int amx = INT_MIN;
int startx = x;
bool seenPositionedElement = false;
flow->setXPos(x);
for (InlineBox* curr = flow->firstChild(); curr; curr = curr->nextOnLine()) {
if (curr->object()->isText()) {
mn = min(mn, x);
amn = min(amn, x);
InlineTextBox* text = static_cast<InlineTextBox*>(curr);
RenderText* rt = static_cast<RenderText*>(text->object());
if (rt->textLength()) {
if (needsWordSpacing && DeprecatedChar(rt->characters()[text->start()]).isSpace())
x += rt->style(flow->isFirstLineStyle())->font().wordSpacing();
needsWordSpacing = !DeprecatedChar(rt->characters()[text->end()]).isSpace();
}
text->setXPos(x);
x += text->width();
mx = max(mx, x);
amx = max(amx, x);
} else if (curr->object()->isInlineFlow()) {
InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
if (flow->object()->element()->hasTagName(aTag)) {
x = placePositionedBoxesHorizontally(flow, x, mn, mx, amn, amx, needsWordSpacing, xPos, false);
} else {
SVGTextPositioningElement* text = static_cast<SVGTextPositioningElement*>(flow->object()->element());
x += (int)(text->dx()->getFirst().value());
if (text->x()->numberOfItems() > 0)
x = (int)(text->x()->getFirst().value() - xPos);
if (text->x()->numberOfItems() > 0 || text->y()->numberOfItems() > 0 ||
text->dx()->numberOfItems() > 0 || text->dy()->numberOfItems() > 0) {
seenPositionedElement = true;
needsWordSpacing = false;
int ignoreX, ignoreY;
x = placePositionedBoxesHorizontally(flow, x, mn, mx, ignoreX, ignoreY, needsWordSpacing, xPos, true);
} else if (seenPositionedElement) {
int ignoreX, ignoreY;
x = placePositionedBoxesHorizontally(flow, x, mn, mx, ignoreX, ignoreY, needsWordSpacing, xPos, false);
} else
x = placePositionedBoxesHorizontally(flow, x, mn, mx, amn, amx, needsWordSpacing, xPos, false);
}
}
}
if (mn > mx)
mn = mx = startx;
if (amn > amx)
amn = amx = startx;
int width = mx - mn;
flow->setWidth(width);
int awidth = amx - amn;
int dx = 0;
if (positioned) {
switch (flow->object()->style()->svgStyle()->textAnchor()) {
case TA_MIDDLE:
translateBox(flow, dx = -awidth / 2, 0, true);
break;
case TA_END:
translateBox(flow, dx = -awidth, 0, true);
break;
case TA_START:
default:
break;
}
if (dx) {
x += dx;
mn += dx;
mx += dx;
}
}
leftPosition = min(leftPosition, mn);
rightPosition = max(rightPosition, mx);
leftAlign = min(leftAlign, amn);
rightAlign = max(rightAlign, amx);
return x;
}
示例15: downstream
Position Position::downstream(EStayInBlock stayInBlock) const
{
Position start = equivalentDeepPosition();
NodeImpl *startNode = start.node();
if (!startNode)
return Position();
NodeImpl *block = startNode->enclosingBlockFlowOrTableElement();
Position lastVisible;
PositionIterator it(start);
for (; !it.atEnd(); it.next()) {
NodeImpl *currentNode = it.current().node();
if (stayInBlock) {
NodeImpl *currentBlock = currentNode->enclosingBlockFlowOrTableElement();
if (block != currentBlock)
return it.previous();
}
RenderObject *renderer = currentNode->renderer();
if (!renderer)
continue;
if (renderer->style()->visibility() != VISIBLE)
continue;
lastVisible = it.current();
if (currentNode != startNode && renderer->isBlockFlow()) {
if (it.current().offset() == 0) {
// If no first child, or first visible child is a not a block, return; otherwise continue.
if (!currentNode->firstChild())
return Position(currentNode, 0);
for (NodeImpl *child = currentNode->firstChild(); child; child = child->nextSibling()) {
RenderObject *r = child->renderer();
if (r && r->style()->visibility() == VISIBLE) {
if (r->isBlockFlow())
break; // break causes continue code below to run.
else
return Position(child, 0);
}
}
continue;
}
}
if (renderer->isReplaced() || renderer->isBR()) {
if (it.current().offset() <= renderer->caretMinOffset())
return Position(currentNode, renderer->caretMinOffset());
else
continue;
}
if (renderer->isText() && static_cast<RenderText *>(renderer)->firstTextBox()) {
if (currentNode != start.node())
return Position(currentNode, renderer->caretMinOffset());
if (it.current().offset() < 0)
continue;
uint textOffset = it.current().offset();
RenderText *textRenderer = static_cast<RenderText *>(renderer);
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (textOffset >= box->start() && textOffset <= box->end())
return it.current();
else if (box != textRenderer->lastTextBox() &&
!box->nextOnLine() &&
textOffset == box->start() + box->len())
return it.current();
}
}
}
return lastVisible.isNotNull() ? lastVisible : *this;
}