本文整理汇总了C++中LayoutPoint::setY方法的典型用法代码示例。如果您正苦于以下问题:C++ LayoutPoint::setY方法的具体用法?C++ LayoutPoint::setY怎么用?C++ LayoutPoint::setY使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类LayoutPoint
的用法示例。
在下文中一共展示了LayoutPoint::setY方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: entryAndExitPointsForDirection
// This method calculates the exitPoint from the startingRect and the entryPoint into the candidate rect.
// The line between those 2 points is the closest distance between the 2 rects.
void entryAndExitPointsForDirection(FocusDirection direction, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint)
{
switch (direction) {
case FocusDirectionLeft:
exitPoint.setX(startingRect.x());
entryPoint.setX(potentialRect.maxX());
break;
case FocusDirectionUp:
exitPoint.setY(startingRect.y());
entryPoint.setY(potentialRect.maxY());
break;
case FocusDirectionRight:
exitPoint.setX(startingRect.maxX());
entryPoint.setX(potentialRect.x());
break;
case FocusDirectionDown:
exitPoint.setY(startingRect.maxY());
entryPoint.setY(potentialRect.y());
break;
default:
ASSERT_NOT_REACHED();
}
switch (direction) {
case FocusDirectionLeft:
case FocusDirectionRight:
if (below(startingRect, potentialRect)) {
exitPoint.setY(startingRect.y());
entryPoint.setY(potentialRect.maxY());
} else if (below(potentialRect, startingRect)) {
exitPoint.setY(startingRect.maxY());
entryPoint.setY(potentialRect.y());
} else {
exitPoint.setY(std::max(startingRect.y(), potentialRect.y()));
entryPoint.setY(exitPoint.y());
}
break;
case FocusDirectionUp:
case FocusDirectionDown:
if (rightOf(startingRect, potentialRect)) {
exitPoint.setX(startingRect.x());
entryPoint.setX(potentialRect.maxX());
} else if (rightOf(potentialRect, startingRect)) {
exitPoint.setX(startingRect.maxX());
entryPoint.setX(potentialRect.x());
} else {
exitPoint.setX(std::max(startingRect.x(), potentialRect.x()));
entryPoint.setX(exitPoint.x());
}
break;
default:
ASSERT_NOT_REACHED();
}
}
示例2: UIEventWithKeyState
MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> abstractView,
int detail, const LayoutPoint& screenLocation, const LayoutPoint& windowLocation,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool isSimulated)
: UIEventWithKeyState(eventType, canBubble, cancelable, abstractView, detail, ctrlKey, altKey, shiftKey, metaKey)
, m_screenLocation(screenLocation)
, m_isSimulated(isSimulated)
{
LayoutPoint adjustedPageLocation;
LayoutPoint scrollPosition;
Frame* frame = view() ? view()->frame() : 0;
if (frame && !isSimulated) {
if (FrameView* frameView = frame->view()) {
scrollPosition = frameView->scrollPosition();
adjustedPageLocation = frameView->windowToContents(windowLocation);
float pageZoom = frame->pageZoomFactor();
if (pageZoom != 1.0f) {
// Adjust our pageX and pageY to account for the page zoom.
adjustedPageLocation.scale(1 / pageZoom, 1 / pageZoom);
// FIXME: Change this to use float math and proper rounding (or
// better yet, use LayoutPoint::scale).
scrollPosition.setX(scrollPosition.x() / pageZoom);
scrollPosition.setY(scrollPosition.y() / pageZoom);
}
}
}
m_clientLocation = adjustedPageLocation - toSize(scrollPosition);
m_pageLocation = adjustedPageLocation;
initCoordinates();
}
示例3: paint
void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
RenderMathMLBlock::paint(info, paintOffset);
if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground)
return;
if (!firstChild() ||!m_lineThickness)
return;
LayoutUnit verticalOffset = 0;
// The children are always RenderMathMLBlock instances
if (firstChild()->isRenderMathMLBlock()) {
int adjustForThickness = m_lineThickness > 1 ? int(m_lineThickness / 2) : 1;
if (int(m_lineThickness) % 2 == 1)
adjustForThickness++;
RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
if (numerator->isRenderMathMLRow())
verticalOffset = numerator->offsetHeight() + adjustForThickness;
else
verticalOffset = numerator->offsetHeight();
}
LayoutPoint adjustedPaintOffset = paintOffset + location();
adjustedPaintOffset.setY(adjustedPaintOffset.y() + verticalOffset);
GraphicsContextStateSaver stateSaver(*info.context);
info.context->setStrokeThickness(m_lineThickness);
info.context->setStrokeStyle(SolidStroke);
info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceSRGB);
info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + offsetWidth(), adjustedPaintOffset.y()));
}
示例4: layout
void LayoutSliderContainer::layout()
{
HTMLInputElement* input = toHTMLInputElement(node()->shadowHost());
bool isVertical = hasVerticalAppearance(input);
mutableStyleRef().setFlexDirection(isVertical ? FlowColumn : FlowRow);
TextDirection oldTextDirection = style()->direction();
if (isVertical) {
// FIXME: Work around rounding issues in RTL vertical sliders. We want them to
// render identically to LTR vertical sliders. We can remove this work around when
// subpixel rendering is enabled on all ports.
mutableStyleRef().setDirection(LTR);
}
Element* thumbElement = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb());
Element* trackElement = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack());
LayoutBox* thumb = thumbElement ? thumbElement->layoutBox() : 0;
LayoutBox* track = trackElement ? trackElement->layoutBox() : 0;
SubtreeLayoutScope layoutScope(*this);
// Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place.
// FIXME: Make a custom layout class for the track and move the thumb positioning code there.
if (track)
layoutScope.setChildNeedsLayout(track);
LayoutFlexibleBox::layout();
mutableStyleRef().setDirection(oldTextDirection);
// These should always exist, unless someone mutates the shadow DOM (e.g., in the inspector).
if (!thumb || !track)
return;
double percentageOffset = sliderPosition(input).toDouble();
LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->contentWidth();
availableExtent -= isVertical ? thumb->size().height() : thumb->size().width();
LayoutUnit offset = percentageOffset * availableExtent;
LayoutPoint thumbLocation = thumb->location();
if (isVertical)
thumbLocation.setY(thumbLocation.y() + track->contentHeight() - thumb->size().height() - offset);
else if (style()->isLeftToRightDirection())
thumbLocation.setX(thumbLocation.x() + offset);
else
thumbLocation.setX(thumbLocation.x() - offset);
thumb->setLocation(thumbLocation);
// We need one-off invalidation code here because painting of the timeline element does not go through style.
// Instead it has a custom implementation in C++ code.
// Therefore the style system cannot understand when it needs to be paint invalidated.
setShouldDoFullPaintInvalidation();
}
示例5: adjustRegionBoundsFromFlowThreadPortionRect
void RenderMultiColumnSet::adjustRegionBoundsFromFlowThreadPortionRect(const LayoutPoint& layerOffset, LayoutRect& regionBounds)
{
LayoutUnit layerLogicalTop = isHorizontalWritingMode() ? layerOffset.y() : layerOffset.x();
unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
LayoutUnit colGap = columnGap();
LayoutUnit colLogicalWidth = computedColumnWidth();
LayoutRect flowThreadPortion = flowThreadPortionRectAt(startColumn);
LayoutPoint translationOffset;
RenderBlockFlow* parentFlow = toRenderBlockFlow(parent());
bool progressionReversed = parentFlow->multiColumnFlowThread()->progressionIsReversed();
bool progressionIsInline = parentFlow->multiColumnFlowThread()->progressionIsInline();
LayoutUnit initialBlockOffset = initialBlockOffsetForPainting();
LayoutUnit inlineOffset = progressionIsInline ? startColumn * (colLogicalWidth + colGap) : LayoutUnit();
bool leftToRight = style().isLeftToRightDirection() ^ progressionReversed;
if (!leftToRight) {
inlineOffset = -inlineOffset;
if (progressionReversed)
inlineOffset += contentLogicalWidth() - colLogicalWidth;
}
translationOffset.setX(inlineOffset);
LayoutUnit blockOffset = initialBlockOffset + (isHorizontalWritingMode() ? -flowThreadPortion.y() : -flowThreadPortion.x());
if (!progressionIsInline) {
if (!progressionReversed)
blockOffset = startColumn * colGap;
else
blockOffset -= startColumn * (computedColumnHeight() + colGap);
}
if (isFlippedBlocksWritingMode(style().writingMode()))
blockOffset = -blockOffset;
translationOffset.setY(blockOffset);
if (!isHorizontalWritingMode())
translationOffset = translationOffset.transposedPoint();
// FIXME: The translation needs to include the multicolumn set's content offset within the
// multicolumn block as well. This won't be an issue until we start creating multiple multicolumn sets.
regionBounds.moveBy(roundedIntPoint(-translationOffset));
}
示例6: layout
void RenderSliderContainer::layout()
{
ASSERT(element()->shadowHost());
auto& input = downcast<HTMLInputElement>(*element()->shadowHost());
bool isVertical = hasVerticalAppearance(input);
mutableStyle().setFlexDirection(isVertical ? FlowColumn : FlowRow);
TextDirection oldTextDirection = style().direction();
if (isVertical) {
// FIXME: Work around rounding issues in RTL vertical sliders. We want them to
// render identically to LTR vertical sliders. We can remove this work around when
// subpixel rendering is enabled on all ports.
mutableStyle().setDirection(LTR);
}
RenderBox* thumb = input.sliderThumbElement() ? input.sliderThumbElement()->renderBox() : nullptr;
RenderBox* track = input.sliderTrackElement() ? input.sliderTrackElement()->renderBox() : nullptr;
// Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place.
// FIXME: Make a custom Render class for the track and move the thumb positioning code there.
if (track)
track->setChildNeedsLayout(MarkOnlyThis);
RenderFlexibleBox::layout();
mutableStyle().setDirection(oldTextDirection);
// These should always exist, unless someone mutates the shadow DOM (e.g., in the inspector).
if (!thumb || !track)
return;
double percentageOffset = sliderPosition(input).toDouble();
LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->contentWidth();
availableExtent -= isVertical ? thumb->height() : thumb->width();
LayoutUnit offset = percentageOffset * availableExtent;
LayoutPoint thumbLocation = thumb->location();
if (isVertical)
thumbLocation.setY(thumbLocation.y() + track->contentHeight() - thumb->height() - offset);
else if (style().isLeftToRightDirection())
thumbLocation.setX(thumbLocation.x() + offset);
else
thumbLocation.setX(thumbLocation.x() - offset);
thumb->setLocation(thumbLocation);
thumb->repaint();
}
示例7: collectLayerFragments
void RenderMultiColumnSet::collectLayerFragments(LayerFragments& fragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect)
{
// The two rectangles passed to this method are physical, except that we pretend that there's
// only one long column (that's how a flow thread works).
//
// Then there's the output from this method - the stuff we put into the list of fragments. The
// fragment.paginationOffset point is the actual physical 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 the same coordinate system as the two rectangles passed
// to this method (flow thread coordinates).
//
// 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. RenderBox::frameRect(). These rectangles also pretend that there's only one long column,
// i.e. they are for the flow thread.
// Put the layer bounds into flow thread-local coordinates by flipping it first. Since we're in
// a renderer, 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(RenderRegion::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 set.
unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
unsigned endColumn = columnIndexAtOffset(layerLogicalBottom);
LayoutUnit colLogicalWidth = computedColumnWidth();
LayoutUnit colGap = columnGap();
unsigned colCount = columnCount();
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 = i * (colLogicalWidth + colGap);
if (!style()->isLeftToRightDirection())
inlineOffset = -inlineOffset;
translationOffset.setX(inlineOffset);
LayoutUnit blockOffset = isHorizontalWritingMode() ? -flowThreadPortion.y() : -flowThreadPortion.x();
if (isFlippedBlocksWritingMode(style()->writingMode()))
blockOffset = -blockOffset;
translationOffset.setY(blockOffset);
if (!isHorizontalWritingMode())
translationOffset = translationOffset.transposedPoint();
// FIXME: The translation needs to include the multicolumn set's content offset within the
// multicolumn block as well. This won't be an issue until we start creating multiple multicolumn sets.
// 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
// offset and the clip rect for the column with that offset applied.
LayerFragment fragment;
fragment.paginationOffset = translationOffset;
LayoutRect flippedFlowThreadOverflowPortion(flowThreadOverflowPortion);
// Flip it into more a physical (RenderLayer-style) rectangle.
flowThread()->flipForWritingMode(flippedFlowThreadOverflowPortion);
fragment.paginationClip = flippedFlowThreadOverflowPortion;
fragments.append(fragment);
}
}
示例8: entryAndExitPointsForDirection
// This method calculates the exitPoint from the startingRect and the entryPoint into the candidate rect.
// The line between those 2 points is the closest distance between the 2 rects.
// Takes care of overlapping rects, defining points so that the distance between them
// is zero where necessary
void entryAndExitPointsForDirection(FocusType type, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint)
{
switch (type) {
case FocusTypeLeft:
exitPoint.setX(startingRect.x());
if (potentialRect.maxX() < startingRect.x())
entryPoint.setX(potentialRect.maxX());
else
entryPoint.setX(startingRect.x());
break;
case FocusTypeUp:
exitPoint.setY(startingRect.y());
if (potentialRect.maxY() < startingRect.y())
entryPoint.setY(potentialRect.maxY());
else
entryPoint.setY(startingRect.y());
break;
case FocusTypeRight:
exitPoint.setX(startingRect.maxX());
if (potentialRect.x() > startingRect.maxX())
entryPoint.setX(potentialRect.x());
else
entryPoint.setX(startingRect.maxX());
break;
case FocusTypeDown:
exitPoint.setY(startingRect.maxY());
if (potentialRect.y() > startingRect.maxY())
entryPoint.setY(potentialRect.y());
else
entryPoint.setY(startingRect.maxY());
break;
default:
ASSERT_NOT_REACHED();
}
switch (type) {
case FocusTypeLeft:
case FocusTypeRight:
if (below(startingRect, potentialRect)) {
exitPoint.setY(startingRect.y());
if (potentialRect.maxY() < startingRect.y())
entryPoint.setY(potentialRect.maxY());
else
entryPoint.setY(startingRect.y());
} else if (below(potentialRect, startingRect)) {
exitPoint.setY(startingRect.maxY());
if (potentialRect.y() > startingRect.maxY())
entryPoint.setY(potentialRect.y());
else
entryPoint.setY(startingRect.maxY());
} else {
exitPoint.setY(max(startingRect.y(), potentialRect.y()));
entryPoint.setY(exitPoint.y());
}
break;
case FocusTypeUp:
case FocusTypeDown:
if (rightOf(startingRect, potentialRect)) {
exitPoint.setX(startingRect.x());
if (potentialRect.maxX() < startingRect.x())
entryPoint.setX(potentialRect.maxX());
else
entryPoint.setX(startingRect.x());
} else if (rightOf(potentialRect, startingRect)) {
exitPoint.setX(startingRect.maxX());
if (potentialRect.x() > startingRect.maxX())
entryPoint.setX(potentialRect.x());
else
entryPoint.setX(startingRect.maxX());
} else {
exitPoint.setX(max(startingRect.x(), potentialRect.x()));
entryPoint.setX(exitPoint.x());
}
break;
default:
ASSERT_NOT_REACHED();
}
}
示例9: 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
//.........这里部分代码省略.........
示例10: collectLayerFragments
void RenderMultiColumnSet::collectLayerFragments(LayerFragments& fragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect)
{
// Let's start by introducing the different coordinate systems involved here. They are different
// in how they deal with writing modes and columns. RenderLayer rectangles tend to be more
// physical than the rectangles used in RenderObject & co.
//
// The two rectangles passed to this method are physical, except that we pretend that there's
// only one long column (that's the flow thread). They are relative to the top left corner of
// the flow thread. All rectangles being compared to the dirty rect also need to be in this
// coordinate system.
//
// Then there's the output from this method - the stuff we put into the list of fragments. The
// translationOffset point is the actual physical translation required to get from a location in
// the flow thread to a location in some column. The paginationClip rectangle is in the same
// coordinate system as the two rectangles passed to this method (i.e. physical, in flow thread
// coordinates, pretending that there's only one long column).
//
// All other rectangles in this method are slightly less physical, when it comes to how they are
// used with different writing modes, but they aren't really logical either. They are just like
// RenderBox::frameRect(). More precisely, the sizes are physical, and the inline direction
// coordinate is too, but the block direction coordinate is always "logical top". These
// rectangles also pretend that there's only one long column, i.e. they are for the flow thread.
//
// To sum up: input and output from this method are "physical" RenderLayer-style rectangles and
// points, while inside this method we mostly use the RenderObject-style rectangles (with the
// block direction coordinate always being logical top).
// Put the layer bounds into flow thread-local coordinates by flipping it first. Since we're in
// a renderer, 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(RenderRegion::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 set.
unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
unsigned endColumn = columnIndexAtOffset(layerLogicalBottom);
LayoutUnit colLogicalWidth = computedColumnWidth();
LayoutUnit colGap = columnGap();
unsigned colCount = columnCount();
RenderBlockFlow* parentFlow = toRenderBlockFlow(parent());
bool progressionReversed = parentFlow->multiColumnFlowThread()->progressionIsReversed();
bool progressionIsInline = parentFlow->multiColumnFlowThread()->progressionIsInline();
LayoutUnit initialBlockOffset = initialBlockOffsetForPainting();
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();
bool leftToRight = style().isLeftToRightDirection() ^ progressionReversed;
if (!leftToRight) {
inlineOffset = -inlineOffset;
if (progressionReversed)
inlineOffset += contentLogicalWidth() - colLogicalWidth;
}
translationOffset.setX(inlineOffset);
LayoutUnit blockOffset = initialBlockOffset + (isHorizontalWritingMode() ? -flowThreadPortion.y() : -flowThreadPortion.x());
if (!progressionIsInline) {
if (!progressionReversed)
blockOffset = i * colGap;
else
blockOffset -= i * (computedColumnHeight() + colGap);
}
if (isFlippedBlocksWritingMode(style().writingMode()))
blockOffset = -blockOffset;
translationOffset.setY(blockOffset);
if (!isHorizontalWritingMode())
translationOffset = translationOffset.transposedPoint();
// FIXME: The translation needs to include the multicolumn set's content offset within the
// multicolumn block as well. This won't be an issue until we start creating multiple multicolumn sets.
// Shift the dirty rect to be in flow thread coordinates with this translation applied.
//.........这里部分代码省略.........
示例11: adjustedPositionRelativeToOffsetParent
LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject& boxModelObject, const LayoutPoint& startPoint)
{
LayoutPoint referencePoint = startPoint;
// FIXME: This needs to be adapted for different writing modes inside the flow thread.
RenderMultiColumnSet* startColumnSet = columnSetAtBlockOffset(referencePoint.y());
if (startColumnSet) {
// Take into account the offset coordinates of the columnSet.
RenderObject* currObject = startColumnSet;
RenderObject* currOffsetParentRenderer;
Element* currOffsetParentElement;
while ((currOffsetParentElement = currObject->offsetParent()) && (currOffsetParentRenderer = currOffsetParentElement->renderer())) {
if (currObject->isBoxModelObject())
referencePoint.move(toRenderBoxModelObject(currObject)->offsetLeft(), toRenderBoxModelObject(currObject)->offsetTop());
// Since we're looking for the offset relative to the body, we must also
// take into consideration the borders of the columnSet's offsetParent.
if (currOffsetParentRenderer->isBox() && !currOffsetParentRenderer->isBody())
referencePoint.move(toRenderBox(currOffsetParentRenderer)->borderLeft(), toRenderBox(currOffsetParentRenderer)->borderTop());
currObject = currOffsetParentRenderer;
}
// We need to check if any of this box's containing blocks start in a different columnSet
// and if so, drop the object's top position (which was computed relative to its containing block
// and is no longer valid) and recompute it using the columnSet in which it flows as reference.
bool wasComputedRelativeToOtherRegion = false;
const RenderBlock* objContainingBlock = boxModelObject.containingBlock();
while (objContainingBlock) {
// Check if this object is in a different columnSet.
RenderMultiColumnSet* parentStartRegion = 0;
RenderMultiColumnSet* parentEndRegion = 0;
getRegionRangeForBox(objContainingBlock, parentStartRegion, parentEndRegion);
if (parentStartRegion && parentStartRegion != startColumnSet) {
wasComputedRelativeToOtherRegion = true;
break;
}
objContainingBlock = objContainingBlock->containingBlock();
}
if (wasComputedRelativeToOtherRegion) {
// Get the logical top coordinate of the current object.
LayoutUnit top = 0;
if (boxModelObject.isRenderBlock()) {
top = toRenderBlock(&boxModelObject)->offsetFromLogicalTopOfFirstPage();
} else {
if (boxModelObject.containingBlock())
top = boxModelObject.containingBlock()->offsetFromLogicalTopOfFirstPage();
if (boxModelObject.isBox())
top += toRenderBox(&boxModelObject)->topLeftLocation().y();
else if (boxModelObject.isRenderInline())
top -= toRenderInline(&boxModelObject)->borderTop();
}
// Get the logical top of the columnSet this object starts in
// and compute the object's top, relative to the columnSet's top.
LayoutUnit regionLogicalTop = startColumnSet->pageLogicalTopForOffset(top);
LayoutUnit topRelativeToRegion = top - regionLogicalTop;
referencePoint.setY(startColumnSet->offsetTop() + topRelativeToRegion);
// Since the top has been overriden, check if the
// relative positioning must be reconsidered.
if (boxModelObject.isRelPositioned())
referencePoint.move(0, boxModelObject.relativePositionOffset().height());
}
// Since we're looking for the offset relative to the body, we must also
// take into consideration the borders of the columnSet.
referencePoint.move(startColumnSet->borderLeft(), startColumnSet->borderTop());
}
return referencePoint;
}