📄 rootinlinebox.cpp
字号:
m_blockHeight += dy;}void RootInlineBox::childRemoved(InlineBox* box){ if (box->renderer() == m_lineBreakObj) setLineBreakInfo(0, 0, BidiStatus()); for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == box->renderer(); prev = prev->prevRootBox()) { prev->setLineBreakInfo(0, 0, BidiStatus()); prev->markDirty(); }}GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, const RenderObject::PaintInfo* paintInfo){ RenderObject::SelectionState lineState = selectionState(); bool leftGap, rightGap; block()->getHorizontalSelectionGapInfo(lineState, leftGap, rightGap); GapRects result; InlineBox* firstBox = firstSelectedBox(); InlineBox* lastBox = lastSelectedBox(); if (leftGap) result.uniteLeft(block()->fillLeftSelectionGap(firstBox->parent()->renderer(), firstBox->x(), selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo)); if (rightGap) result.uniteRight(block()->fillRightSelectionGap(lastBox->parent()->renderer(), lastBox->x() + lastBox->width(), selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo)); // When dealing with bidi text, a non-contiguous selection region is possible. // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capitals LTR) is layed out // visually as 3 text runs |aaa|bbb|AAA| if we select 4 characters from the start of the text the // selection will look like (underline denotes selection): // |aaa|bbb|AAA| // ___ _ // We can see that the |bbb| run is not part of the selection while the runs around it are. if (firstBox && firstBox != lastBox) { // Now fill in any gaps on the line that occurred between two selected elements. int lastX = firstBox->x() + firstBox->width(); bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject::SelectionNone; for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) { if (box->selectionState() != RenderObject::SelectionNone) { if (isPreviousBoxSelected) // VisibleSelection may be non-contiguous, see comment above. result.uniteCenter(block()->fillHorizontalSelectionGap(box->parent()->renderer(), lastX + tx, selTop + ty, box->x() - lastX, selHeight, paintInfo)); lastX = box->x() + box->width(); } if (box == lastBox) break; isPreviousBoxSelected = box->selectionState() != RenderObject::SelectionNone; } } return result;}void RootInlineBox::setHasSelectedChildren(bool b){ if (m_hasSelectedChildren == b) return; m_hasSelectedChildren = b;}RenderObject::SelectionState RootInlineBox::selectionState(){ // Walk over all of the selected boxes. RenderObject::SelectionState state = RenderObject::SelectionNone; for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) { RenderObject::SelectionState boxState = box->selectionState(); if ((boxState == RenderObject::SelectionStart && state == RenderObject::SelectionEnd) || (boxState == RenderObject::SelectionEnd && state == RenderObject::SelectionStart)) state = RenderObject::SelectionBoth; else if (state == RenderObject::SelectionNone || ((boxState == RenderObject::SelectionStart || boxState == RenderObject::SelectionEnd) && (state == RenderObject::SelectionNone || state == RenderObject::SelectionInside))) state = boxState; if (state == RenderObject::SelectionBoth) break; } return state;}InlineBox* RootInlineBox::firstSelectedBox(){ for (InlineBox* box = firstLeafChild(); box; box = box->nextLeafChild()) { if (box->selectionState() != RenderObject::SelectionNone) return box; } return 0;}InlineBox* RootInlineBox::lastSelectedBox(){ for (InlineBox* box = lastLeafChild(); box; box = box->prevLeafChild()) { if (box->selectionState() != RenderObject::SelectionNone) return box; } return 0;}int RootInlineBox::selectionTop(){ int selectionTop = m_overflow ? m_overflow->m_selectionTop : m_y; if (!prevRootBox()) return selectionTop; int prevBottom = prevRootBox()->selectionBottom(); if (prevBottom < selectionTop && block()->containsFloats()) { // This line has actually been moved further down, probably from a large line-height, but possibly because the // line was forced to clear floats. If so, let's check the offsets, and only be willing to use the previous // line's bottom overflow if the offsets are greater on both sides. int prevLeft = block()->leftOffset(prevBottom, !prevRootBox()); int prevRight = block()->rightOffset(prevBottom, !prevRootBox()); int newLeft = block()->leftOffset(selectionTop, !prevRootBox()); int newRight = block()->rightOffset(selectionTop, !prevRootBox()); if (prevLeft > newLeft || prevRight < newRight) return selectionTop; } return prevBottom;}RenderBlock* RootInlineBox::block() const{ return toRenderBlock(renderer());}static bool isEditableLeaf(InlineBox* leaf){ return leaf && leaf->renderer() && leaf->renderer()->node() && leaf->renderer()->node()->isContentEditable();}InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves){ InlineBox* firstLeaf = firstLeafChildAfterBox(); InlineBox* lastLeaf = lastLeafChildBeforeBox(); if (firstLeaf == lastLeaf && (!onlyEditableLeaves || isEditableLeaf(firstLeaf))) return firstLeaf; // Avoid returning a list marker when possible. if (x <= firstLeaf->m_x && !firstLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf))) // The x coordinate is less or equal to left edge of the firstLeaf. // Return it. return firstLeaf; if (x >= lastLeaf->m_x + lastLeaf->m_width && !lastLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf))) // The x coordinate is greater or equal to right edge of the lastLeaf. // Return it. return lastLeaf; InlineBox* closestLeaf = 0; for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChild()) { if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) { closestLeaf = leaf; if (x < leaf->m_x + leaf->m_width) // The x coordinate is less than the right edge of the box. // Return it. return leaf; } } return closestLeaf ? closestLeaf : lastLeaf;}BidiStatus RootInlineBox::lineBreakBidiStatus() const{ return BidiStatus(m_lineBreakBidiStatusEor, m_lineBreakBidiStatusLastStrong, m_lineBreakBidiStatusLast, m_lineBreakContext);}void RootInlineBox::setLineBreakInfo(RenderObject* obj, unsigned breakPos, const BidiStatus& status){ m_lineBreakObj = obj; m_lineBreakPos = breakPos; m_lineBreakBidiStatusEor = status.eor; m_lineBreakBidiStatusLastStrong = status.lastStrong; m_lineBreakBidiStatusLast = status.last; m_lineBreakContext = status.context;}EllipsisBox* RootInlineBox::ellipsisBox() const{ if (!m_hasEllipsisBox) return false; return gEllipsisBoxMap->get(this);}void RootInlineBox::setVerticalOverflowPositions(int top, int bottom) { if (!m_overflow) { const Font& font = renderer()->style(m_firstLine)->font(); if (top == m_y && bottom == m_y + font.height()) return; m_overflow = new (renderer()->renderArena()) Overflow(this); } m_overflow->m_topOverflow = top; m_overflow->m_bottomOverflow = bottom; }void RootInlineBox::removeLineBoxFromRenderObject(){ block()->lineBoxes()->removeLineBox(this);}void RootInlineBox::extractLineBoxFromRenderObject(){ block()->lineBoxes()->extractLineBox(this);}void RootInlineBox::attachLineBoxToRenderObject(){ block()->lineBoxes()->attachLineBox(this);}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -