コード例 #1
0
bool hitTestFlow(const RenderBlockFlow& flow, const Layout& layout, const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
{
    if (hitTestAction != HitTestForeground)
        return false;

    if (!layout.runCount())
        return false;

    RenderStyle& style = flow.style();
    if (style.visibility() != VISIBLE || style.pointerEvents() == PE_NONE)
        return false;

    RenderObject& renderer = *flow.firstChild();
    LayoutRect rangeRect = locationInContainer.boundingBox();
    rangeRect.moveBy(-accumulatedOffset);

    auto resolver = lineResolver(flow, layout);
    for (FloatRect lineRect : resolver.rangeForRect(rangeRect)) {
        lineRect.moveBy(accumulatedOffset);
        if (!locationInContainer.intersects(lineRect))
            continue;
        renderer.updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
        if (!result.addNodeToRectBasedTestResult(renderer.node(), request, locationInContainer, lineRect))
            return true;
    }

    return false;
}
コード例 #2
0
ファイル: RenderMultiColumnSet.cpp プロジェクト: boska/webkit
LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const
{
    LayoutUnit colLogicalWidth = computedColumnWidth();
    LayoutUnit colLogicalHeight = computedColumnHeight();
    LayoutUnit colLogicalTop = borderAndPaddingBefore();
    LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft();
    LayoutUnit colGap = columnGap();
    
    RenderBlockFlow* parentFlow = toRenderBlockFlow(parent());
    bool progressionReversed = parentFlow->multiColumnFlowThread()->progressionIsReversed();
    bool progressionInline = parentFlow->multiColumnFlowThread()->progressionIsInline();
    
    if (progressionInline) {
        if (style().isLeftToRightDirection() ^ progressionReversed)
            colLogicalLeft += index * (colLogicalWidth + colGap);
        else
            colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
    } else {
        if (!progressionReversed)
            colLogicalTop += index * (colLogicalHeight + colGap);
        else
            colLogicalTop += contentLogicalHeight() - colLogicalHeight - index * (colLogicalHeight + colGap);
    }
    
    if (isHorizontalWritingMode())
        return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
    return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
}
コード例 #3
0
ファイル: SVGTextQuery.cpp プロジェクト: 335969568/Blink-1
static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer)
{
    if (!renderer)
        return 0;

    if (renderer->isRenderBlock()) {
        // If we're given a block element, it has to be a RenderSVGText.
        ASSERT(renderer->isSVGText());
        RenderBlockFlow* renderBlockFlow = toRenderBlockFlow(renderer);

        // RenderSVGText only ever contains a single line box.
        InlineFlowBox* flowBox = renderBlockFlow->firstLineBox();
        ASSERT(flowBox == renderBlockFlow->lastLineBox());
        return flowBox;
    }

    if (renderer->isRenderInline()) {
        // We're given a RenderSVGInline or objects that derive from it (RenderSVGTSpan / RenderSVGTextPath)
        RenderInline* renderInline = toRenderInline(renderer);

        // RenderSVGInline only ever contains a single line box.
        InlineFlowBox* flowBox = renderInline->firstLineBox();
        ASSERT(flowBox == renderInline->lastLineBox());
        return flowBox;
    }

    ASSERT_NOT_REACHED();
    return 0;
}
コード例 #4
0
void LayoutState::establishLineGrid(RenderBlockFlow* block)
{
    // First check to see if this grid has been established already.
    if (m_lineGrid) {
        if (m_lineGrid->style().lineGrid() == block->style().lineGrid())
            return;
        RenderBlockFlow* currentGrid = m_lineGrid;
        for (LayoutState* currentState = m_next.get(); currentState; currentState = currentState->m_next.get()) {
            if (currentState->m_lineGrid == currentGrid)
                continue;
            currentGrid = currentState->m_lineGrid;
            if (!currentGrid)
                break;
            if (currentGrid->style().lineGrid() == block->style().lineGrid()) {
                m_lineGrid = currentGrid;
                m_lineGridOffset = currentState->m_lineGridOffset;
                return;
            }
        }
    }
    
    // We didn't find an already-established grid with this identifier. Our render object establishes the grid.
    m_lineGrid = block;
    m_lineGridOffset = m_layoutOffset; 
}
コード例 #5
0
TextFragmentIterator::TextFragmentIterator(const RenderBlockFlow& flow)
    : m_flowContents(flow)
    , m_currentSegment(m_flowContents.begin())
    , m_lineBreakIterator(m_currentSegment->text, flow.style().locale())
    , m_style(flow.style())
{
}
コード例 #6
0
inline static float availableWidthAtOffset(const RenderBlockFlow& block, const LayoutUnit& offset, IndentTextOrNot shouldIndentText,
    float& newLineLeft, float& newLineRight, const LayoutUnit& lineHeight = 0)
{
    newLineLeft = block.logicalLeftOffsetForLine(offset, shouldIndentText, lineHeight);
    newLineRight = block.logicalRightOffsetForLine(offset, shouldIndentText, lineHeight);
    return std::max(0.0f, newLineRight - newLineLeft);
}
コード例 #7
0
LayoutUnit RenderMultiColumnSet::columnGap() const
{
    RenderBlockFlow* parentBlock = multiColumnBlockFlow();
    if (parentBlock->style()->hasNormalColumnGap())
        return parentBlock->style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
    return parentBlock->style()->columnGap();
}
コード例 #8
0
ファイル: RenderRuby.cpp プロジェクト: 335969568/Blink-1
static RenderBlockFlow* createAnonymousRubyInlineBlock(RenderObject* ruby)
{
    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(ruby->style(), INLINE_BLOCK);
    RenderBlockFlow* newBlock = RenderBlockFlow::createAnonymous(&ruby->document());
    newBlock->setStyle(newStyle.release());
    return newBlock;
}
コード例 #9
0
ファイル: ShapeOutsideInfo.cpp プロジェクト: caiolima/webkit
ShapeOutsideDeltas ShapeOutsideInfo::computeDeltasForContainingBlockLine(const RenderBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight)
{
    ASSERT(lineHeight >= 0);
    LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(floatingObject) + containingBlock.marginBeforeForChild(m_renderer);
    LayoutUnit borderBoxLineTop = lineTop - borderBoxTop;

    if (isShapeDirty() || !m_shapeOutsideDeltas.isForLine(borderBoxLineTop, lineHeight)) {
        LayoutUnit referenceBoxLineTop = borderBoxLineTop - logicalTopOffset();
        LayoutUnit floatMarginBoxWidth = std::max<LayoutUnit>(LayoutUnit(), containingBlock.logicalWidthForFloat(floatingObject));

        if (computedShape().lineOverlapsShapeMarginBounds(referenceBoxLineTop, lineHeight)) {
            LineSegment segment = computedShape().getExcludedInterval((borderBoxLineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - borderBoxLineTop));
            if (segment.isValid) {
                LayoutUnit logicalLeftMargin = containingBlock.style().isLeftToRightDirection() ? containingBlock.marginStartForChild(m_renderer) : containingBlock.marginEndForChild(m_renderer);
                LayoutUnit rawLeftMarginBoxDelta = segment.logicalLeft + logicalLeftOffset() + logicalLeftMargin;
                LayoutUnit leftMarginBoxDelta = clampTo<LayoutUnit>(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth);

                LayoutUnit logicalRightMargin = containingBlock.style().isLeftToRightDirection() ? containingBlock.marginEndForChild(m_renderer) : containingBlock.marginStartForChild(m_renderer);
                LayoutUnit rawRightMarginBoxDelta = segment.logicalRight + logicalLeftOffset() - containingBlock.logicalWidthForChild(m_renderer) - logicalRightMargin;
                LayoutUnit rightMarginBoxDelta = clampTo<LayoutUnit>(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());

                m_shapeOutsideDeltas = ShapeOutsideDeltas(leftMarginBoxDelta, rightMarginBoxDelta, true, borderBoxLineTop, lineHeight);
                return m_shapeOutsideDeltas;
            }
        }

        // Lines that do not overlap the shape should act as if the float
        // wasn't there for layout purposes. So we set the deltas to remove the
        // entire width of the float
        m_shapeOutsideDeltas = ShapeOutsideDeltas(floatMarginBoxWidth, -floatMarginBoxWidth, false, borderBoxLineTop, lineHeight);
    }

    return m_shapeOutsideDeltas;
}
コード例 #10
0
void RenderMultiColumnFlowThread::evacuateAndDestroy()
{
    RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
    m_beingEvacuated = true;

    // Delete the line box tree.
    deleteLines();

    LayoutStateDisabler layoutStateDisabler(&view());

    // First promote all children of the flow thread. Before we move them to the flow thread's
    // container, we need to unregister the flow thread, so that they aren't just re-added again to
    // the flow thread that we're trying to empty.
    multicolContainer->setMultiColumnFlowThread(nullptr);
    moveAllChildrenTo(multicolContainer, true);

    // Move spanners back to their original DOM position in the tree, and destroy the placeholders.
    SpannerMap::iterator it;
    while ((it = m_spannerMap.begin()) != m_spannerMap.end()) {
        RenderBox* spanner = it->key;
        RenderMultiColumnSpannerPlaceholder* placeholder = it->value;
        RenderBlockFlow* originalContainer = toRenderBlockFlow(placeholder->parent());
        multicolContainer->removeChild(*spanner);
        originalContainer->addChild(spanner, placeholder);
        placeholder->destroy();
        m_spannerMap.remove(it);
    }

    // Remove all sets.
    while (RenderMultiColumnSet* columnSet = firstMultiColumnSet())
        columnSet->destroy();

    destroy();
}
コード例 #11
0
LayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const
{
    RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
    LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderBefore() - multicolBlock->paddingBefore();

    height -= contentLogicalTop;
    return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created.
}
コード例 #12
0
ファイル: RenderMultiColumnSet.cpp プロジェクト: boska/webkit
LayoutUnit RenderMultiColumnSet::columnGap() const
{
    // FIXME: Eventually we will cache the column gap when the widths of columns start varying, but for now we just
    // go to the parent block to get the gap.
    RenderBlockFlow* parentBlock = toRenderBlockFlow(parent());
    if (parentBlock->style().hasNormalColumnGap())
        return parentBlock->style().fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
    return parentBlock->style().columnGap();
}
コード例 #13
0
ファイル: RenderMultiColumnSet.cpp プロジェクト: boska/webkit
void RenderMultiColumnSet::updateLogicalWidth()
{
    RenderBlockFlow* parentBlock = toRenderBlockFlow(parent());
    setComputedColumnWidthAndCount(parentBlock->multiColumnFlowThread()->columnWidth(), parentBlock->multiColumnFlowThread()->columnCount()); // FIXME: This will eventually vary if we are contained inside regions.
    
    // FIXME: When we add regions support, we'll start it off at the width of the multi-column
    // block in that particular region.
    setLogicalWidth(parentBox()->contentLogicalWidth());
}
コード例 #14
0
void collectFlowOverflow(RenderBlockFlow& flow, const Layout& layout)
{
    auto resolver = lineResolver(flow, layout);
    for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) {
        auto rect = *it;
        flow.addLayoutOverflow(rect);
        flow.addVisualOverflow(rect);
    }
}
コード例 #15
0
ファイル: InlineBox.cpp プロジェクト: Igalia/blink
FloatPoint InlineBox::locationIncludingFlipping()
{
    if (!renderer()->style()->isFlippedBlocksWritingMode())
        return FloatPoint(x(), y());
    RenderBlockFlow* block = root()->block();
    if (block->style()->isHorizontalWritingMode())
        return FloatPoint(x(), block->height() - height() - y());
    else
        return FloatPoint(block->width() - width() - x(), y());
}
コード例 #16
0
void collectFlowOverflow(RenderBlockFlow& flow, const Layout& layout)
{
    float strokeOverflow = std::ceil(flow.style().textStrokeWidth());
    for (FloatRect lineRect : lineResolver(flow, layout)) {
        LayoutRect inflatedLineRect(lineRect);
        inflatedLineRect.inflate(strokeOverflow);
        flow.addLayoutOverflow(inflatedLineRect);
        flow.addVisualOverflow(inflatedLineRect);
    }
}
コード例 #17
0
void RenderMultiColumnFlowThread::populate()
{
    RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
    ASSERT(!nextSibling());
    // Reparent children preceding the flow thread into the flow thread. It's multicol content
    // now. At this point there's obviously nothing after the flow thread, but renderers (column
    // sets and spanners) will be inserted there as we insert elements into the flow thread.
    LayoutStateDisabler layoutStateDisabler(&view());
    multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this, true);
}
コード例 #18
0
void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (paintInfo.phase != PaintPhaseForeground)
        return;

    RenderStyle& style = flow.style();
    if (style.visibility() != VISIBLE)
        return;

    bool debugBordersEnabled = flow.frame().settings().simpleLineLayoutDebugBordersEnabled();

    TextPainter textPainter(paintInfo.context());
    textPainter.setFont(style.fontCascade());
    textPainter.setTextPaintStyle(computeTextPaintStyle(flow.frame(), style, paintInfo));

    Optional<TextDecorationPainter> textDecorationPainter;
    if (style.textDecorationsInEffect() != TextDecorationNone) {
        const RenderText* textRenderer = childrenOfType<RenderText>(flow).first();
        if (textRenderer) {
            textDecorationPainter = TextDecorationPainter(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false);
            textDecorationPainter->setFont(style.fontCascade());
            textDecorationPainter->setBaseline(style.fontMetrics().ascent());
        }
    }

    LayoutRect paintRect = paintInfo.rect;
    paintRect.moveBy(-paintOffset);

    auto resolver = runResolver(flow, layout);
    float strokeOverflow = std::ceil(flow.style().textStrokeWidth());
    float deviceScaleFactor = flow.document().deviceScaleFactor();
    for (auto run : resolver.rangeForRect(paintRect)) {
        if (run.start() == run.end())
            continue;

        FloatRect rect = run.rect();
        FloatRect visualOverflowRect = rect;
        visualOverflowRect.inflate(strokeOverflow);
        if (paintRect.y() > visualOverflowRect.maxY() || paintRect.maxY() < visualOverflowRect.y())
            continue;

        TextRun textRun(run.text());
        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
        // x position indicates the line offset from the rootbox. It's always 0 in case of simple line layout.
        textRun.setXPos(0);
        FloatPoint textOrigin = FloatPoint(rect.x() + paintOffset.x(), roundToDevicePixel(run.baselinePosition() + paintOffset.y(), deviceScaleFactor));
        textPainter.paintText(textRun, textRun.length(), rect, textOrigin);
        if (textDecorationPainter) {
            textDecorationPainter->setWidth(rect.width());
            textDecorationPainter->paintTextDecoration(textRun, textOrigin, rect.location() + paintOffset);
        }
        if (debugBordersEnabled)
            paintDebugBorders(paintInfo.context(), LayoutRect(run.rect()), paintOffset);
    }
}
コード例 #19
0
void collectFlowOverflow(RenderBlockFlow& flow, const Layout& layout)
{
    auto resolver = lineResolver(flow, layout);
    float strokeOverflow = ceilf(flow.style().textStrokeWidth());
    for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) {
        auto rect = LayoutRect(*it);
        rect.inflate(strokeOverflow);
        flow.addLayoutOverflow(rect);
        flow.addVisualOverflow(rect);
    }
}
コード例 #20
0
static bool newFloatShrinksLine(const FloatingObject& newFloat, const RenderBlockFlow& block, bool isFirstLine)
{
    LayoutUnit blockOffset = block.logicalHeight();
    if (blockOffset >= block.logicalTopForFloat(newFloat) && blockOffset < block.logicalBottomForFloat(newFloat))
        return true;

    // initial-letter float always shrinks the first line.
    const auto& style = newFloat.renderer().style();
    if (isFirstLine && style.styleType() == FIRST_LETTER && !style.initialLetter().isEmpty())
        return true;
    return false;
}
コード例 #21
0
RunResolver::RunResolver(const RenderBlockFlow& flow, const Layout& layout)
    : m_flowRenderer(flow)
    , m_layout(layout)
    , m_flowContents(flow)
    , m_lineHeight(lineHeightFromFlow(flow))
    , m_baseline(baselineFromFlow(flow))
    , m_borderAndPaddingBefore(flow.borderAndPaddingBefore())
    , m_ascent(flow.style().fontCascade().fontMetrics().ascent())
    , m_descent(flow.style().fontCascade().fontMetrics().descent())
    , m_visualOverflowOffset(visualOverflowForDecorations(flow.style(), nullptr).bottom)
    , m_inQuirksMode(flow.document().inQuirksMode())
{
}
コード例 #22
0
LayoutUnit RenderMultiColumnSet::calculateMaxColumnHeight() const
{
    RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
    RenderStyle* multicolStyle = multicolBlock->style();
    LayoutUnit availableHeight = multiColumnFlowThread()->columnHeightAvailable();
    LayoutUnit maxColumnHeight = availableHeight ? availableHeight : RenderFlowThread::maxLogicalHeight();
    if (!multicolStyle->logicalMaxHeight().isUndefined()) {
        LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalMaxHeight(), -1);
        if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight)
            maxColumnHeight = logicalMaxHeight;
    }
    return heightAdjustedForSetOffset(maxColumnHeight);
}
コード例 #23
0
ファイル: RenderMultiColumnSet.cpp プロジェクト: boska/webkit
LayoutUnit RenderMultiColumnSet::initialBlockOffsetForPainting() const
{
    RenderBlockFlow* parentFlow = toRenderBlockFlow(parent());
    bool progressionReversed = parentFlow->multiColumnFlowThread()->progressionIsReversed();
    bool progressionIsInline = parentFlow->multiColumnFlowThread()->progressionIsInline();
    
    LayoutUnit result = 0;
    if (!progressionIsInline && progressionReversed) {
        LayoutRect colRect = columnRectAt(0);
        result = isHorizontalWritingMode() ? colRect.y() : colRect.x();
        if (style().isFlippedBlocksWritingMode())
            result = -result;
    }
    return result;
}
コード例 #24
0
ファイル: RootInlineBox.cpp プロジェクト: qfish/webkit
RootInlineBox::RootInlineBox(RenderBlockFlow& block)
    : InlineFlowBox(block)
    , m_lineBreakPos(0)
    , m_lineBreakObj(nullptr)
{
    setIsHorizontal(block.isHorizontalWritingMode());
}
コード例 #25
0
ファイル: FloatingObjects.cpp プロジェクト: eocanha/webkit
FloatingObjects::FloatingObjects(const RenderBlockFlow& renderer)
    : m_leftObjectsCount(0)
    , m_rightObjectsCount(0)
    , m_horizontalWritingMode(renderer.isHorizontalWritingMode())
    , m_renderer(renderer)
{
}
コード例 #26
0
static AvoidanceReasonFlags canUseForFontAndText(const RenderBlockFlow& flow, FallThrough fallthrough)
{
    AvoidanceReasonFlags reasons = NoReason;
    // We assume that all lines have metrics based purely on the primary font.
    const auto& style = flow.style();
    auto& primaryFont = style.fontCascade().primaryFont();
    if (primaryFont.isLoading())
        SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowIsMissingPrimaryFont, fallthrough);
    if (primaryFont.isSVGFont())
        SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowHasSVGFont, fallthrough);

    for (const auto& textRenderer : childrenOfType<RenderText>(flow)) {
        if (textRenderer.isCombineText())
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowTextIsCombineText, fallthrough);
        if (textRenderer.isCounter())
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowTextIsRenderCounter, fallthrough);
        if (textRenderer.isQuote())
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowTextIsRenderQuote, fallthrough);
        if (textRenderer.isTextFragment())
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowTextIsTextFragment, fallthrough);
        if (textRenderer.isSVGInlineText())
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowTextIsSVGInlineText, fallthrough);
        if (style.fontCascade().codePath(TextRun(textRenderer.text())) != FontCascade::Simple)
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, FlowFontIsNotSimple, fallthrough);

        auto textReasons = canUseForText(textRenderer, primaryFont, fallthrough);
        if (textReasons != NoReason)
            SET_REASON_AND_RETURN_IF_NEEDED(reasons, textReasons, fallthrough);
    }
    return reasons;
}
コード例 #27
0
static void createTextRuns(Layout::RunVector& runs, RenderBlockFlow& flow, unsigned& lineCount)
{
    LayoutUnit borderAndPaddingBefore = flow.borderAndPaddingBefore();
    LayoutUnit lineHeight = lineHeightFromFlow(flow);
    LineState line;
    bool isEndOfContent = false;
    TextFragmentIterator textFragmentIterator = TextFragmentIterator(flow);
    do {
        flow.setLogicalHeight(lineHeight * lineCount + borderAndPaddingBefore);
        LineState previousLine = line;
        unsigned previousRunCount = runs.size();
        line = LineState();
        updateLineConstrains(flow, line, !lineCount);
        isEndOfContent = createLineRuns(line, previousLine, runs, textFragmentIterator);
        closeLineEndingAndAdjustRuns(line, runs, previousRunCount, lineCount, textFragmentIterator);
    } while (!isEndOfContent);
}
コード例 #28
0
LayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const
{
    // Adjust for the top offset within the content box of the multicol container (containing
    // block), unless this is the first set. We know that the top offset for the first set will be
    // zero, but if the multicol container has non-zero top border or padding, the set's top offset
    // (initially being 0 and relative to the border box) will be negative until it has been laid
    // out. Had we used this bogus offset, we would calculate the wrong height, and risk performing
    // a wasted layout iteration. Of course all other sets (if any) have this problem in the first
    // layout pass too, but there's really nothing we can do there until the flow thread has been
    // laid out anyway.
    if (previousSiblingMultiColumnSet()) {
        RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
        LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderAndPaddingBefore();
        height -= contentLogicalTop;
    }
    return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created.
}
コード例 #29
0
ファイル: RenderMultiColumnSet.cpp プロジェクト: boska/webkit
void RenderMultiColumnSet::prepareForLayout()
{
    RenderBlockFlow* multicolBlock = toRenderBlockFlow(parent());
    const RenderStyle& multicolStyle = multicolBlock->style();

    // Set box logical top.
    ASSERT(!previousSiblingBox() || !previousSiblingBox()->isRenderMultiColumnSet()); // FIXME: multiple set not implemented; need to examine previous set to calculate the correct logical top.
    setLogicalTop(multicolBlock->borderAndPaddingBefore());

    // Set box width.
    updateLogicalWidth();

    if (multicolBlock->multiColumnFlowThread()->requiresBalancing()) {
        // Set maximum column height. We will not stretch beyond this.
        m_maxColumnHeight = RenderFlowThread::maxLogicalHeight();
        if (!multicolStyle.logicalHeight().isAuto()) {
            m_maxColumnHeight = multicolBlock->computeContentLogicalHeight(multicolStyle.logicalHeight());
            if (m_maxColumnHeight == -1)
                m_maxColumnHeight = RenderFlowThread::maxLogicalHeight();
        }
        if (!multicolStyle.logicalMaxHeight().isUndefined()) {
            LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle.logicalMaxHeight());
            if (logicalMaxHeight != -1 && m_maxColumnHeight > logicalMaxHeight)
                m_maxColumnHeight = logicalMaxHeight;
        }
        m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight);
        m_computedColumnHeight = 0; // Restart balancing.
    } else
        setAndConstrainColumnHeight(heightAdjustedForSetOffset(multicolBlock->multiColumnFlowThread()->columnHeightAvailable()));

    clearForcedBreaks();

    // Nuke previously stored minimum column height. Contents may have changed for all we know.
    m_minimumColumnHeight = 0;
}
コード例 #30
0
ファイル: RenderMultiColumnSet.cpp プロジェクト: boska/webkit
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));
}