GapRects RenderBlockFlow::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) { GapRects result; bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth; if (!firstLineBox()) { if (containsStart) { // Go ahead and update our lastLogicalTop to be the bottom of the block. <hr>s or empty blocks with height can trip this // case. lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight(); lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); } return result; } RootInlineBox* lastSelectedLine = 0; RootInlineBox* curr; for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { } // Now paint the gaps for the lines. for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) { LayoutUnit selTop = curr->selectionTopAdjustedForPrecedingBlock(); LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock(); if (!containsStart && !lastSelectedLine && selectionState() != SelectionStart && selectionState() != SelectionBoth) { result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, paintInfo)); } LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight); logicalRect.move(offsetFromRootBlock); LayoutRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect); if (!paintInfo || (physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())) result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo)); lastSelectedLine = curr; } if (containsStart && !lastSelectedLine) { // VisibleSelection must start just after our last line. lastSelectedLine = lastRootBox(); } if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) { // Go ahead and update our lastY to be the bottom of the last selected line. lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + lastSelectedLine->selectionBottom(); lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); } return result; }
void RenderRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const { ASSERT(!needsLayout()); startOverhang = 0; endOverhang = 0; RenderRubyBase* rubyBase = this->rubyBase(); RenderRubyText* rubyText = this->rubyText(); if (!rubyBase || !rubyText) return; if (!rubyBase->firstRootBox()) return; int logicalWidth = this->logicalWidth(); int logicalLeftOverhang = numeric_limits<int>::max(); int logicalRightOverhang = numeric_limits<int>::max(); for (RootInlineBox* rootInlineBox = rubyBase->firstRootBox(); rootInlineBox; rootInlineBox = rootInlineBox->nextRootBox()) { logicalLeftOverhang = min<int>(logicalLeftOverhang, rootInlineBox->logicalLeft()); logicalRightOverhang = min<int>(logicalRightOverhang, logicalWidth - rootInlineBox->logicalRight()); } startOverhang = style()->isLeftToRightDirection() ? logicalLeftOverhang : logicalRightOverhang; endOverhang = style()->isLeftToRightDirection() ? logicalRightOverhang : logicalLeftOverhang; if (!startRenderer || !startRenderer->isText() || startRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) startOverhang = 0; if (!endRenderer || !endRenderer->isText() || endRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) endOverhang = 0; // We overhang a ruby only if the neighboring render object is a text. // We can overhang the ruby by no more than half the width of the neighboring text // and no more than half the font size. int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; if (startOverhang) startOverhang = min<int>(startOverhang, min<int>(toRenderText(startRenderer)->minLogicalWidth(), halfWidthOfFontSize)); if (endOverhang) endOverhang = min<int>(endOverhang, min<int>(toRenderText(endRenderer)->minLogicalWidth(), halfWidthOfFontSize)); }
void RenderRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const { ASSERT(!needsLayout()); startOverhang = 0; endOverhang = 0; RenderRubyBase* rubyBase = this->rubyBase(); RenderRubyText* rubyText = this->rubyText(); if (!rubyBase || !rubyText) return; if (!rubyBase->firstRootBox()) return; int logicalWidth = this->logicalWidth(); // No more than half a ruby is allowed to overhang. int logicalLeftOverhang = rubyText->style(firstLine)->fontSize() / 2; int logicalRightOverhang = logicalLeftOverhang; for (RootInlineBox* rootInlineBox = rubyBase->firstRootBox(); rootInlineBox; rootInlineBox = rootInlineBox->nextRootBox()) { logicalLeftOverhang = min<int>(logicalLeftOverhang, rootInlineBox->logicalLeft()); logicalRightOverhang = min<int>(logicalRightOverhang, logicalWidth - rootInlineBox->logicalRight()); } startOverhang = style()->isLeftToRightDirection() ? logicalLeftOverhang : logicalRightOverhang; endOverhang = style()->isLeftToRightDirection() ? logicalRightOverhang : logicalLeftOverhang; if (!startRenderer || !startRenderer->isText() || startRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) startOverhang = 0; if (!endRenderer || !endRenderer->isText() || endRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) endOverhang = 0; }