本文整理汇总了C++中LayoutMultiColumnFlowThread类的典型用法代码示例。如果您正苦于以下问题:C++ LayoutMultiColumnFlowThread类的具体用法?C++ LayoutMultiColumnFlowThread怎么用?C++ LayoutMultiColumnFlowThread使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了LayoutMultiColumnFlowThread类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: heightAdjustedForRowOffset
LayoutUnit MultiColumnFragmentainerGroup::calculateMaxColumnHeight() const
{
LayoutBlockFlow* multicolBlock = m_columnSet.multiColumnBlockFlow();
const ComputedStyle& multicolStyle = multicolBlock->styleRef();
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
LayoutUnit availableHeight = flowThread->columnHeightAvailable();
LayoutUnit maxColumnHeight = availableHeight ? availableHeight : LayoutUnit::max();
if (!multicolStyle.logicalMaxHeight().isMaxSizeNone()) {
LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(MaxSize, multicolStyle.logicalMaxHeight(), -1);
if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight)
maxColumnHeight = logicalMaxHeight;
}
LayoutUnit maxHeight = heightAdjustedForRowOffset(maxColumnHeight);
if (LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread()) {
if (enclosingFlowThread->isPageLogicalHeightKnown()) {
// We're nested inside another fragmentation context whose fragmentainer heights are
// known. This constrains the max height.
LayoutUnit remainingOuterLogicalHeight = enclosingFlowThread->pageRemainingLogicalHeightForOffset(blockOffsetInEnclosingFlowThread(), LayoutBlock::AssociateWithLatterPage);
ASSERT(remainingOuterLogicalHeight > 0);
if (maxHeight > remainingOuterLogicalHeight)
maxHeight = remainingOuterLogicalHeight;
}
}
return maxHeight;
}
示例2: LayoutMultiColumnFlowThread
LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::createAnonymous(Document& document, const ComputedStyle& parentStyle)
{
LayoutMultiColumnFlowThread* layoutObject = new LayoutMultiColumnFlowThread();
layoutObject->setDocumentForAnonymous(&document);
layoutObject->setStyle(ComputedStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK));
return layoutObject;
}
示例3: columnIndexAtOffset
LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) const
{
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
unsigned columnIndex = columnIndexAtOffset(offsetInFlowThread);
LayoutRect portionRect(flowThreadPortionRectAt(columnIndex));
flowThread->flipForWritingMode(portionRect);
LayoutRect columnRect(columnRectAt(columnIndex));
m_columnSet.flipForWritingMode(columnRect);
LayoutSize translationRelativeToGroup = columnRect.location() - portionRect.location();
LayoutSize enclosingTranslation;
if (LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread()) {
// Translation that would map points in the coordinate space of the outermost flow thread to
// visual points in the first column in the first fragmentainer group (row) in our multicol
// container.
LayoutSize enclosingTranslationOrigin = enclosingFlowThread->flowThreadTranslationAtOffset(flowThread->blockOffsetInEnclosingFragmentationContext());
// Translation that would map points in the coordinate space of the outermost flow thread to
// visual points in the first column in this fragmentainer group.
enclosingTranslation = enclosingFlowThread->flowThreadTranslationAtOffset(blockOffsetInEnclosingFragmentationContext());
// What we ultimately return from this method is a translation that maps points in the
// coordinate space of our flow thread to a visual point in a certain column in this
// fragmentainer group. We had to go all the way up to the outermost flow thread, since this
// fragmentainer group may be in a different outer column than the first outer column that
// this multicol container lives in. It's the visual distance between the first
// fragmentainer group and this fragmentainer group that we need to add to the translation.
enclosingTranslation -= enclosingTranslationOrigin;
}
return enclosingTranslation + translationRelativeToGroup + offsetFromColumnSet() + m_columnSet.topLeftLocationOffset() - flowThread->topLeftLocationOffset();
}
示例4: ASSERT
void MultiColumnFragmentainerGroup::expandToEncompassFlowThreadOverflow()
{
ASSERT(isLastGroup());
// Get the offset within the flow thread in its block progression direction. Then get the
// flow thread's remaining logical height including its overflow and expand our rect
// to encompass that remaining height and overflow. The idea is that we will generate
// additional columns and pages to hold that overflow, since people do write bad
// content like <body style="height:0px"> in multi-column layouts.
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
LayoutRect layoutRect = flowThread->layoutOverflowRect();
m_logicalBottomInFlowThread = flowThread->isHorizontalWritingMode() ? layoutRect.maxY() : layoutRect.maxX();
}
示例5: calculateMaxColumnHeight
LayoutUnit MultiColumnFragmentainerGroup::calculateMaxColumnHeight() const
{
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
LayoutUnit maxColumnHeight = flowThread->maxColumnLogicalHeight();
LayoutUnit maxHeight = heightAdjustedForRowOffset(maxColumnHeight);
if (FragmentationContext* enclosingFragmentationContext = flowThread->enclosingFragmentationContext()) {
if (enclosingFragmentationContext->isFragmentainerLogicalHeightKnown()) {
// We're nested inside another fragmentation context whose fragmentainer heights are
// known. This constrains the max height.
LayoutUnit remainingOuterLogicalHeight = enclosingFragmentationContext->remainingLogicalHeightAt(blockOffsetInEnclosingFragmentationContext());
ASSERT(remainingOuterLogicalHeight > 0);
if (maxHeight > remainingOuterLogicalHeight)
maxHeight = remainingOuterLogicalHeight;
}
}
return maxHeight;
}
示例6: calculateMaxColumnHeight
void MultiColumnFragmentainerGroup::resetColumnHeight()
{
// Nuke previously stored minimum column height. Contents may have changed for all we know.
m_minimumColumnHeight = 0;
m_maxColumnHeight = calculateMaxColumnHeight();
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread();
if (enclosingFlowThread && enclosingFlowThread->isPageLogicalHeightKnown()) {
// TODO(mstensho): Do this better. If height is auto here, we shouldn't set a
// height, or forced breaks and pagination struts might mess up column balancing.
LayoutUnit columnHeight = heightIsAuto() ? m_maxColumnHeight : heightAdjustedForRowOffset(flowThread->columnHeightAvailable());
setAndConstrainColumnHeight(columnHeight);
} else if (heightIsAuto()) {
m_columnHeight = LayoutUnit();
} else {
setAndConstrainColumnHeight(heightAdjustedForRowOffset(flowThread->columnHeightAvailable()));
}
}
示例7: fragmentainerGroupAtFlowThreadOffset
void LayoutMultiColumnSet::recordSpaceShortage(LayoutUnit offsetInFlowThread, LayoutUnit spaceShortage)
{
MultiColumnFragmentainerGroup& row = fragmentainerGroupAtFlowThreadOffset(offsetInFlowThread);
row.recordSpaceShortage(spaceShortage);
// Since we're at a potential break here, take the opportunity to check if we need another
// fragmentainer group. If we've run out of columns in the last fragmentainer group (column
// row), we need to insert another fragmentainer group to hold more columns.
if (!row.isLastGroup())
return;
LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread();
if (!flowThread->multiColumnBlockFlow()->isInsideFlowThread())
return; // Early bail. We're not nested, so waste no more time on this.
if (!flowThread->isInInitialLayoutPass())
return;
// Move the offset to where the next column starts, if we're not there already.
offsetInFlowThread += flowThread->pageRemainingLogicalHeightForOffset(offsetInFlowThread, AssociateWithFormerPage);
flowThread->appendNewFragmentainerGroupIfNeeded(offsetInFlowThread);
}
示例8: multiColumnFlowThread
bool LayoutMultiColumnSet::heightIsAuto() const
{
LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread();
if (!flowThread->isLayoutPagedFlowThread()) {
// If support for the column-fill property isn't enabled, we want to behave as if
// column-fill were auto, so that multicol containers with specified height don't get their
// columns balanced (auto-height multicol containers will still get their columns balanced,
// even if column-fill isn't 'balance' - in accordance with the spec). Pretending that
// column-fill is auto also matches the old multicol implementation, which has no support
// for this property.
if (multiColumnBlockFlow()->style()->getColumnFill() == ColumnFillBalance)
return true;
if (LayoutBox* next = nextSiblingBox()) {
if (next->isLayoutMultiColumnSpannerPlaceholder()) {
// If we're followed by a spanner, we need to balance.
return true;
}
}
}
return !flowThread->columnHeightAvailable();
}
示例9: previousInPreOrderSkippingOutOfFlow
// Find the previous layout object that has the multicol container in its containing block chain, skipping nested multicol containers.
static LayoutObject* previousInPreOrderSkippingOutOfFlow(LayoutMultiColumnFlowThread* flowThread, LayoutObject* descendant)
{
ASSERT(descendant->isDescendantOf(flowThread));
LayoutObject* object = descendant->previousInPreOrder(flowThread);
while (object && object != flowThread) {
if (object->isColumnSpanAll()) {
LayoutMultiColumnFlowThread* placeholderFlowThread = toLayoutBox(object)->spannerPlaceholder()->flowThread();
if (placeholderFlowThread == flowThread)
break;
// We're inside an inner multicol container. We have no business there. Continue on the outside.
object = placeholderFlowThread->parent();
ASSERT(object->isDescendantOf(flowThread));
continue;
}
if (object->flowThreadContainingBlock() == flowThread) {
LayoutObject* ancestor;
for (ancestor = object->parent(); ; ancestor = ancestor->parent()) {
if (ancestor == flowThread)
return object;
if (isMultiColumnContainer(*ancestor)) {
// We're inside an inner multicol container. We have no business there.
break;
}
}
object = ancestor;
ASSERT(ancestor->isDescendantOf(flowThread));
continue; // Continue on the outside of the inner flow thread.
}
// We're inside something that's out-of-flow. Keep looking upwards and backwards in the tree.
object = object->previousInPreOrder(flowThread);
}
if (!object || object == flowThread)
return nullptr;
#if ENABLE(ASSERT)
// Make sure that we didn't stumble into an inner multicol container.
for (LayoutObject* walker = object->parent(); walker && walker != flowThread; walker = walker->parent())
ASSERT(!isMultiColumnContainer(*walker));
#endif
return object;
}
示例10: addContentRun
void InitialColumnHeightFinder::examineBoxAfterEntering(
const LayoutBox& box,
EBreak previousBreakAfterValue) {
if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) {
if (box.needsForcedBreakBefore(previousBreakAfterValue)) {
addContentRun(flowThreadOffset());
} else {
ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut());
if (isFirstAfterBreak(flowThreadOffset())) {
// This box is first after a soft break.
recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut());
}
}
}
if (box.getPaginationBreakability() != LayoutBox::AllowAnyBreaks) {
LayoutUnit unsplittableLogicalHeight = box.logicalHeight();
if (box.isFloating())
unsplittableLogicalHeight += box.marginBefore() + box.marginAfter();
m_tallestUnbreakableLogicalHeight =
std::max(m_tallestUnbreakableLogicalHeight, unsplittableLogicalHeight);
return;
}
// Need to examine inner multicol containers to find their tallest unbreakable
// piece of content.
if (!box.isLayoutBlockFlow())
return;
LayoutMultiColumnFlowThread* innerFlowThread =
toLayoutBlockFlow(box).multiColumnFlowThread();
if (!innerFlowThread || innerFlowThread->isLayoutPagedFlowThread())
return;
LayoutUnit offsetInInnerFlowThread =
flowThreadOffset() -
innerFlowThread->blockOffsetInEnclosingFragmentationContext();
LayoutUnit innerUnbreakableHeight =
innerFlowThread->tallestUnbreakableLogicalHeight(offsetInInnerFlowThread);
m_tallestUnbreakableLogicalHeight =
std::max(m_tallestUnbreakableLogicalHeight, innerUnbreakableHeight);
}
示例11: collectLayerFragments
void MultiColumnFragmentainerGroup::collectLayerFragments(DeprecatedPaintLayerFragments& fragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) const
{
// |layerBoundingBox| is in the flow thread coordinate space, relative to the top/left edge of
// the flow thread, but note that it has been converted with respect to writing mode (so that
// it's visual/physical in that sense).
//
// |dirtyRect| is visual, relative to the multicol container.
//
// Then there's the output from this method - the stuff we put into the list of fragments. The
// fragment.paginationOffset point is the actual visual translation required to get from a
// location in the flow thread to a location in a given column. The fragment.paginationClip
// rectangle, on the other hand, is in flow thread coordinates, but otherwise completely
// physical in terms of writing mode.
//
// All other rectangles in this method are sized physically, and the inline direction coordinate
// is physical too, but the block direction coordinate is "logical top". This is the same as
// e.g. LayoutBox::frameRect(). These rectangles also pretend that there's only one long column,
// i.e. they are for the flow thread.
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
bool isHorizontalWritingMode = m_columnSet.isHorizontalWritingMode();
// Put the layer bounds into flow thread-local coordinates by flipping it first. Since we're in
// a layoutObject, most rectangles are represented this way.
LayoutRect layerBoundsInFlowThread(layerBoundingBox);
flowThread->flipForWritingMode(layerBoundsInFlowThread);
// Now we can compare with the flow thread portions owned by each column. First let's
// see if the rect intersects our flow thread portion at all.
LayoutRect clippedRect(layerBoundsInFlowThread);
clippedRect.intersect(m_columnSet.flowThreadPortionOverflowRect());
if (clippedRect.isEmpty())
return;
// Now we know we intersect at least one column. Let's figure out the logical top and logical
// bottom of the area we're checking.
LayoutUnit layerLogicalTop = isHorizontalWritingMode ? layerBoundsInFlowThread.y() : layerBoundsInFlowThread.x();
LayoutUnit layerLogicalBottom = (isHorizontalWritingMode ? layerBoundsInFlowThread.maxY() : layerBoundsInFlowThread.maxX()) - 1;
// Figure out the start and end columns and only check within that range so that we don't walk the
// entire column row.
unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
unsigned endColumn = columnIndexAtOffset(layerLogicalBottom);
LayoutUnit colLogicalWidth = m_columnSet.pageLogicalWidth();
LayoutUnit colGap = m_columnSet.columnGap();
unsigned colCount = actualColumnCount();
bool progressionIsInline = flowThread->progressionIsInline();
bool leftToRight = m_columnSet.style()->isLeftToRightDirection();
LayoutUnit initialBlockOffset = m_columnSet.logicalTop() + logicalTop() - flowThread->logicalTop();
for (unsigned i = startColumn; i <= endColumn; i++) {
// Get the portion of the flow thread that corresponds to this column.
LayoutRect flowThreadPortion = flowThreadPortionRectAt(i);
// Now get the overflow rect that corresponds to the column.
LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flowThreadPortion, i, colCount, colGap);
// In order to create a fragment we must intersect the portion painted by this column.
LayoutRect clippedRect(layerBoundsInFlowThread);
clippedRect.intersect(flowThreadOverflowPortion);
if (clippedRect.isEmpty())
continue;
// We also need to intersect the dirty rect. We have to apply a translation and shift based off
// our column index.
LayoutPoint translationOffset;
LayoutUnit inlineOffset = progressionIsInline ? i * (colLogicalWidth + colGap) : LayoutUnit();
if (!leftToRight)
inlineOffset = -inlineOffset;
translationOffset.setX(inlineOffset);
LayoutUnit blockOffset;
if (progressionIsInline) {
blockOffset = initialBlockOffset + (isHorizontalWritingMode ? -flowThreadPortion.y() : -flowThreadPortion.x());
} else {
// Column gap can apply in the block direction for page fragmentainers.
// There is currently no spec which calls for column-gap to apply
// for page fragmentainers at all, but it's applied here for compatibility
// with the old multicolumn implementation.
blockOffset = i * colGap;
}
if (isFlippedBlocksWritingMode(m_columnSet.style()->writingMode()))
blockOffset = -blockOffset;
translationOffset.setY(blockOffset);
if (!isHorizontalWritingMode)
translationOffset = translationOffset.transposedPoint();
// Shift the dirty rect to be in flow thread coordinates with this translation applied.
LayoutRect translatedDirtyRect(dirtyRect);
translatedDirtyRect.moveBy(-translationOffset);
// See if we intersect the dirty rect.
clippedRect = layerBoundingBox;
clippedRect.intersect(translatedDirtyRect);
if (clippedRect.isEmpty())
continue;
// Something does need to paint in this column. Make a fragment now and supply the physical translation
//.........这里部分代码省略.........
示例12: collectLayerFragments
void MultiColumnFragmentainerGroup::collectLayerFragments(PaintLayerFragments& fragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) const
{
// |layerBoundingBox| is in the flow thread coordinate space, relative to the top/left edge of
// the flow thread, but note that it has been converted with respect to writing mode (so that
// it's visual/physical in that sense).
//
// |dirtyRect| is visual, relative to the multicol container.
//
// Then there's the output from this method - the stuff we put into the list of fragments. The
// fragment.paginationOffset point is the actual visual translation required to get from a
// location in the flow thread to a location in a given column. The fragment.paginationClip
// rectangle, on the other hand, is in flow thread coordinates, but otherwise completely
// physical in terms of writing mode.
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
bool isHorizontalWritingMode = m_columnSet.isHorizontalWritingMode();
// Put the layer bounds into flow thread-local coordinates by flipping it first. Since we're in
// a layoutObject, most rectangles are represented this way.
LayoutRect layerBoundsInFlowThread(layerBoundingBox);
flowThread->flipForWritingMode(layerBoundsInFlowThread);
// Now we can compare with the flow thread portions owned by each column. First let's
// see if the rect intersects our flow thread portion at all.
LayoutRect clippedRect(layerBoundsInFlowThread);
clippedRect.intersect(m_columnSet.flowThreadPortionOverflowRect());
if (clippedRect.isEmpty())
return;
// Now we know we intersect at least one column. Let's figure out the logical top and logical
// bottom of the area we're checking.
LayoutUnit layerLogicalTop = isHorizontalWritingMode ? layerBoundsInFlowThread.y() : layerBoundsInFlowThread.x();
LayoutUnit layerLogicalBottom = (isHorizontalWritingMode ? layerBoundsInFlowThread.maxY() : layerBoundsInFlowThread.maxX());
// Figure out the start and end columns for the layer and only check within that range so that
// we don't walk the entire column row.
unsigned startColumn;
unsigned endColumn;
columnIntervalForBlockRangeInFlowThread(layerLogicalTop, layerLogicalBottom, startColumn, endColumn);
// Now intersect with the columns actually occupied by the dirty rect, to narrow it down even further.
unsigned firstColumnInDirtyRect, lastColumnInDirtyRect;
columnIntervalForVisualRect(dirtyRect, firstColumnInDirtyRect, lastColumnInDirtyRect);
if (firstColumnInDirtyRect > endColumn || lastColumnInDirtyRect < startColumn)
return; // The two column intervals are disjoint. There's nothing to collect.
if (startColumn < firstColumnInDirtyRect)
startColumn = firstColumnInDirtyRect;
if (endColumn > lastColumnInDirtyRect)
endColumn = lastColumnInDirtyRect;
ASSERT(endColumn >= startColumn);
for (unsigned i = startColumn; i <= endColumn; i++) {
PaintLayerFragment fragment;
// Set the physical translation offset.
fragment.paginationOffset = toLayoutPoint(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(i)));
// Set the overflow clip rect that corresponds to the column.
fragment.paginationClip = flowThreadPortionOverflowRectAt(i);
// Flip it into more a physical (PaintLayer-style) rectangle.
flowThread->flipForWritingMode(fragment.paginationClip);
fragments.append(fragment);
}
}
示例13: logicalBottomInFlowThread
LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(
LayoutUnit offsetInFlowThread,
LayoutBox::PageBoundaryRule rule,
CoordinateSpaceConversion mode) const {
LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
// A column out of range doesn't have a flow thread portion, so we need to
// clamp to make sure that we stay within the actual columns. This means that
// content in the overflow area will be mapped to the last actual column,
// instead of being mapped to an imaginary column further ahead.
unsigned columnIndex = offsetInFlowThread >= logicalBottomInFlowThread()
? actualColumnCount() - 1
: columnIndexAtOffset(offsetInFlowThread, rule);
LayoutRect portionRect(flowThreadPortionRectAt(columnIndex));
flowThread->flipForWritingMode(portionRect);
portionRect.moveBy(flowThread->topLeftLocation());
LayoutRect columnRect(columnRectAt(columnIndex));
columnRect.move(offsetFromColumnSet());
m_columnSet.flipForWritingMode(columnRect);
columnRect.moveBy(m_columnSet.topLeftLocation());
LayoutSize translationRelativeToFlowThread =
columnRect.location() - portionRect.location();
if (mode == CoordinateSpaceConversion::Containing)
return translationRelativeToFlowThread;
LayoutSize enclosingTranslation;
if (LayoutMultiColumnFlowThread* enclosingFlowThread =
flowThread->enclosingFlowThread()) {
const MultiColumnFragmentainerGroup& firstRow =
flowThread->firstMultiColumnSet()->firstFragmentainerGroup();
// Translation that would map points in the coordinate space of the
// outermost flow thread to visual points in the first column in the first
// fragmentainer group (row) in our multicol container.
LayoutSize enclosingTranslationOrigin =
enclosingFlowThread->flowThreadTranslationAtOffset(
firstRow.blockOffsetInEnclosingFragmentationContext(),
LayoutBox::AssociateWithLatterPage, mode);
// Translation that would map points in the coordinate space of the
// outermost flow thread to visual points in the first column in this
// fragmentainer group.
enclosingTranslation = enclosingFlowThread->flowThreadTranslationAtOffset(
blockOffsetInEnclosingFragmentationContext(),
LayoutBox::AssociateWithLatterPage, mode);
// What we ultimately return from this method is a translation that maps
// points in the coordinate space of our flow thread to a visual point in a
// certain column in this fragmentainer group. We had to go all the way up
// to the outermost flow thread, since this fragmentainer group may be in a
// different outer column than the first outer column that this multicol
// container lives in. It's the visual distance between the first
// fragmentainer group and this fragmentainer group that we need to add to
// the translation.
enclosingTranslation -= enclosingTranslationOrigin;
}
return enclosingTranslation + translationRelativeToFlowThread;
}