LayoutRect LayoutMultiColumnSet::flowThreadPortionRect() const { LayoutRect portionRect(LayoutUnit(), logicalTopInFlowThread(), pageLogicalWidth(), logicalHeightInFlowThread()); if (!isHorizontalWritingMode()) return portionRect.transposedRect(); return portionRect; }
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(); }
LayoutSize RenderMultiColumnFlowThread::physicalTranslationOffsetFromFlowToRegion(const RenderRegion* renderRegion, const LayoutUnit logicalOffset) const { // Now that we know which multicolumn set we hit, we need to get the appropriate translation offset for the column. const RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(renderRegion); LayoutPoint translationOffset = columnSet->columnTranslationForOffset(logicalOffset); // Now we know how we want the rect to be translated into the region. At this point we're converting // back to physical coordinates. if (style().isFlippedBlocksWritingMode()) { LayoutRect portionRect(columnSet->flowThreadPortionRect()); LayoutRect columnRect = columnSet->columnRectAt(0); LayoutUnit physicalDeltaFromPortionBottom = logicalHeight() - columnSet->logicalBottomInFlowThread(); if (isHorizontalWritingMode()) columnRect.setHeight(portionRect.height()); else columnRect.setWidth(portionRect.width()); columnSet->flipForWritingMode(columnRect); if (isHorizontalWritingMode()) translationOffset.move(0, columnRect.y() - portionRect.y() - physicalDeltaFromPortionBottom); else translationOffset.move(columnRect.x() - portionRect.x() - physicalDeltaFromPortionBottom, 0); } return LayoutSize(translationOffset.x(), translationOffset.y()); }
LayoutSize RenderMultiColumnSet::flowThreadTranslationAtOffset(LayoutUnit blockOffset) const { unsigned columnIndex = columnIndexAtOffset(blockOffset); LayoutRect portionRect(flowThreadPortionRectAt(columnIndex)); flipForWritingMode(portionRect); LayoutRect columnRect(columnRectAt(columnIndex)); flipForWritingMode(columnRect); return contentBoxRect().location() + columnRect.location() - portionRect.location(); }
LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) const { LayoutFlowThread* flowThread = m_columnSet.flowThread(); 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(); return translationRelativeToGroup + offsetFromColumnSet() + m_columnSet.topLeftLocationOffset() - flowThread->topLeftLocationOffset(); }
void CTestContainer::Draw(const TRect& /*aRect*/) const { switch(iBackgroundType) { case EBackgroundBlackRedGreenYellowStripes: { const TRect rect=Rect(); CWindowGc& gc=SystemGc(); gc.SetPenStyle(CGraphicsContext::ENullPen); gc.SetBrushStyle(CGraphicsContext::ESolidBrush); gc.SetBrushColor(iColor); TInt yOffset = rect.Height() / 4; TRect portionRect(rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iTl.iY + yOffset); gc.DrawRect(portionRect); gc.SetBrushColor(KRgbRed); portionRect.iTl.iY = portionRect.iBr.iY; portionRect.iBr.iY += yOffset; gc.DrawRect(portionRect); gc.SetBrushColor(KRgbGreen); portionRect.iTl.iY = portionRect.iBr.iY; portionRect.iBr.iY += yOffset; gc.DrawRect(portionRect); gc.SetBrushColor(KRgbYellow); portionRect.iTl.iY = portionRect.iBr.iY; portionRect.iBr.iY = rect.iBr.iY; gc.DrawRect(portionRect); gc.SetBrushColor(KRgbWhite); } break; case EBackgroundYellow: { const TRect rect=Rect(); CWindowGc& gc=SystemGc(); gc.SetPenStyle(CGraphicsContext::ENullPen); gc.SetBrushStyle(CGraphicsContext::ESolidBrush); gc.SetBrushColor(KRgbYellow); gc.DrawRect(rect); } break; case EBackgroundBlue: { const TRect rect=Rect(); CWindowGc& gc=SystemGc(); gc.SetPenStyle(CGraphicsContext::ENullPen); gc.SetBrushStyle(CGraphicsContext::ESolidBrush); gc.SetBrushColor(KRgbBlue); gc.DrawRect(rect); } break; default: break; } }
unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset) const { LayoutRect portionRect(flowThreadPortionRect()); LayoutUnit flowThreadLogicalTop = isHorizontalWritingMode() ? portionRect.y() : portionRect.x(); LayoutUnit flowThreadLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX(); // Handle the offset being out of range. if (offset < flowThreadLogicalTop) return 0; if (offset >= flowThreadLogicalBottom) return columnCount() - 1; // Just divide by the column height to determine the correct column. return static_cast<float>(offset - flowThreadLogicalTop) / computedColumnHeight(); }
unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset, ColumnIndexCalculationMode mode) const { LayoutRect portionRect(flowThreadPortionRect()); // Handle the offset being out of range. LayoutUnit flowThreadLogicalTop = isHorizontalWritingMode() ? portionRect.y() : portionRect.x(); if (offset < flowThreadLogicalTop) return 0; // If we're laying out right now, we cannot constrain against some logical bottom, since it // isn't known yet. Otherwise, just return the last column if we're past the logical bottom. if (mode == ClampToExistingColumns) { LayoutUnit flowThreadLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX(); if (offset >= flowThreadLogicalBottom) return columnCount() - 1; } // Just divide by the column height to determine the correct column. return (offset - flowThreadLogicalTop).toFloat() / computedColumnHeight().toFloat(); }
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; }