⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bidi.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    switch(textAlign) {        case LEFT:        case WEBKIT_LEFT:            // The direction of the block should determine what happens with wide lines.  In            // particular with RTL blocks, wide lines should still spill out to the left.            if (style()->direction() == LTR) {                if (totWidth > availableWidth && trailingSpaceRun)                    trailingSpaceRun->m_box->setWidth(trailingSpaceRun->m_box->width() - totWidth + availableWidth);            } else {                if (trailingSpaceRun)                    trailingSpaceRun->m_box->setWidth(0);                else if (totWidth > availableWidth)                    x -= (totWidth - availableWidth);            }            break;        case JUSTIFY:            if (numSpaces && !reachedEnd && !lineBox->endsWithBreak()) {                if (trailingSpaceRun) {                    totWidth -= trailingSpaceRun->m_box->width();                    trailingSpaceRun->m_box->setWidth(0);                }                break;            }            // fall through        case TAAUTO:            numSpaces = 0;            // for right to left fall through to right aligned            if (style()->direction() == LTR) {                if (totWidth > availableWidth && trailingSpaceRun)                    trailingSpaceRun->m_box->setWidth(trailingSpaceRun->m_box->width() - totWidth + availableWidth);                break;            }        case RIGHT:        case WEBKIT_RIGHT:            // Wide lines spill out of the block based off direction.            // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right            // side of the block.            if (style()->direction() == LTR) {                if (trailingSpaceRun) {                    totWidth -= trailingSpaceRun->m_box->width();                    trailingSpaceRun->m_box->setWidth(0);                }                if (totWidth < availableWidth)                    x += availableWidth - totWidth;            } else {                if (totWidth > availableWidth && trailingSpaceRun) {                    trailingSpaceRun->m_box->setWidth(trailingSpaceRun->m_box->width() - totWidth + availableWidth);                    totWidth -= trailingSpaceRun->m_box->width();                } else                    x += availableWidth - totWidth;            }            break;        case CENTER:        case WEBKIT_CENTER:            int trailingSpaceWidth = 0;            if (trailingSpaceRun) {                totWidth -= trailingSpaceRun->m_box->width();                trailingSpaceWidth = min(trailingSpaceRun->m_box->width(), (availableWidth - totWidth + 1) / 2);                trailingSpaceRun->m_box->setWidth(trailingSpaceWidth);            }            if (style()->direction() == LTR)                x += max((availableWidth - totWidth) / 2, 0);            else                x += totWidth > availableWidth ? (availableWidth - totWidth) : (availableWidth - totWidth) / 2 - trailingSpaceWidth;            break;    }    if (numSpaces) {        for (BidiRun* r = firstRun; r; r = r->next()) {            if (!r->m_box || r == trailingSpaceRun)                continue;            int spaceAdd = 0;            if (r->m_object->isText()) {                unsigned spaces = 0;                const UChar* characters = toRenderText(r->m_object)->characters();                for (int i = r->m_start; i < r->m_stop; i++) {                    UChar c = characters[i];                    if (c == ' ' || c == '\n' || c == '\t')                        spaces++;                }                ASSERT(spaces <= numSpaces);                // Only justify text if whitespace is collapsed.                if (r->m_object->style()->collapseWhiteSpace()) {                    spaceAdd = (availableWidth - totWidth) * spaces / numSpaces;                    static_cast<InlineTextBox*>(r->m_box)->setSpaceAdd(spaceAdd);                    totWidth += spaceAdd;                }                numSpaces -= spaces;                if (!numSpaces)                    break;            }        }    }    // The widths of all runs are now known.  We can now place every inline box (and    // compute accurate widths for the inline flow boxes).    int leftPosition = x;    int rightPosition = x;    needsWordSpacing = false;    lineBox->placeBoxesHorizontally(x, leftPosition, rightPosition, needsWordSpacing);    lineBox->setHorizontalOverflowPositions(leftPosition, rightPosition);}void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun){    setHeight(lineBox->verticallyAlignBoxes(height()));    lineBox->setBlockHeight(height());    // See if the line spilled out.  If so set overflow height accordingly.    int bottomOfLine = lineBox->bottomOverflow();    if (bottomOfLine > height() && bottomOfLine > m_overflowHeight)        m_overflowHeight = bottomOfLine;    // Now make sure we place replaced render objects correctly.    for (BidiRun* r = firstRun; r; r = r->next()) {        if (!r->m_box)            continue; // Skip runs with no line boxes.        // Align positioned boxes with the top of the line box.  This is        // a reasonable approximation of an appropriate y position.        if (r->m_object->isPositioned())            r->m_box->setY(height());        // Position is used to properly position both replaced elements and        // to update the static normal flow x/y of positioned elements.        if (r->m_object->isText())            toRenderText(r->m_object)->positionLineBox(r->m_box);        else if (r->m_object->isBox())            toRenderBox(r->m_object)->positionLineBox(r->m_box);    }    // Positioned objects and zero-length text nodes destroy their boxes in    // position(), which unnecessarily dirties the line.    lineBox->markDirty(false);}// collects one line of the paragraph and transforms it to visual ordervoid RenderBlock::bidiReorderLine(InlineBidiResolver& resolver, const InlineIterator& end){    resolver.createBidiRunsForLine(end, style()->visuallyOrdered(), previousLineBrokeCleanly);}static inline bool isCollapsibleSpace(UChar character, RenderText* renderer){    if (character == ' ' || character == '\t' || character == softHyphen)        return true;    if (character == '\n')        return !renderer->style()->preserveNewline();    if (character == noBreakSpace)        return renderer->style()->nbspMode() == SPACE;    return false;}void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom){    bool useRepaintBounds = false;        m_overflowHeight = 0;            setHeight(borderTop() + paddingTop());    int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();    // Figure out if we should clear out our line boxes.    // FIXME: Handle resize eventually!    // FIXME: Do something better when floats are present.    bool fullLayout = !firstLineBox() || !firstChild() || selfNeedsLayout() || relayoutChildren;    if (fullLayout)        lineBoxes()->deleteLineBoxes(renderArena());    // Text truncation only kicks in if your overflow isn't visible and your text-overflow-mode isn't    // clip.    // FIXME: CSS3 says that descendants that are clipped must also know how to truncate.  This is insanely    // difficult to figure out (especially in the middle of doing layout), and is really an esoteric pile of nonsense    // anyway, so we won't worry about following the draft here.    bool hasTextOverflow = style()->textOverflow() && hasOverflowClip();    // Walk all the lines and delete our ellipsis line boxes if they exist.    if (hasTextOverflow)         deleteEllipsisLineBoxes();    if (firstChild()) {        // layout replaced elements        bool endOfInline = false;        RenderObject* o = bidiFirst(this, 0, false);        Vector<FloatWithRect> floats;        while (o) {            if (o->isReplaced() || o->isFloating() || o->isPositioned()) {                RenderBox* box = toRenderBox(o);                                if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent())                    o->setChildNeedsLayout(true, false);                                    // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.                if (relayoutChildren && (o->style()->paddingLeft().isPercent() || o->style()->paddingRight().isPercent()))                    o->setPrefWidthsDirty(true, false);                            if (o->isPositioned())                    o->containingBlock()->insertPositionedObject(box);                else {                    if (o->isFloating())                        floats.append(FloatWithRect(box));                    else if (fullLayout || o->needsLayout()) // Replaced elements                        toRenderBox(o)->dirtyLineBoxes(fullLayout);                    o->layoutIfNeeded();                }            } else if (o->isText() || (o->isRenderInline() && !endOfInline)) {                if (fullLayout || o->selfNeedsLayout())                    dirtyLineBoxesForRenderer(o, fullLayout);                o->setNeedsLayout(false);                if (!o->isText())                    toRenderInline(o)->invalidateVerticalPosition(); // FIXME: Should do better here and not always invalidate everything.            }            o = bidiNext(this, o, 0, false, &endOfInline);        }        // We want to skip ahead to the first dirty line        InlineBidiResolver resolver;        unsigned floatIndex;        bool firstLine = true;        RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, resolver, floats, floatIndex);        if (fullLayout && !selfNeedsLayout()) {            setNeedsLayout(true, false);  // Mark ourselves as needing a full layout. This way we'll repaint like                                          // we're supposed to.            RenderView* v = view();            if (v && !v->doingFullRepaint() && hasLayer()) {                // Because we waited until we were already inside layout to discover                // that the block really needed a full layout, we missed our chance to repaint the layer                // before layout started.  Luckily the layer has cached the repaint rect for its original                // position and size, and so we can use that to make a repaint happen now.                repaintUsingContainer(containerForRepaint(), layer()->repaintRect());            }        }        FloatingObject* lastFloat = m_floatingObjects ? m_floatingObjects->last() : 0;        if (!smidpoints)            smidpoints = new Vector<InlineIterator>();        sNumMidpoints = 0;        sCurrMidpoint = 0;        // We also find the first clean line and extract these lines.  We will add them back        // if we determine that we're able to synchronize after handling all our dirty lines.        InlineIterator cleanLineStart;        BidiStatus cleanLineBidiStatus;        int endLineYPos = 0;        RootInlineBox* endLine = (fullLayout || !startLine) ?                                  0 : determineEndPosition(startLine, cleanLineStart, cleanLineBidiStatus, endLineYPos);        if (startLine) {            useRepaintBounds = true;            repaintTop = height();            repaintBottom = height();            RenderArena* arena = renderArena();            RootInlineBox* box = startLine;            while (box) {                repaintTop = min(repaintTop, box->topOverflow());                repaintBottom = max(repaintBottom, box->bottomOverflow());                RootInlineBox* next = box->nextRootBox();                box->deleteLine(arena);                box = next;            }        }        InlineIterator end = resolver.position();        if (!fullLayout && lastRootBox() && lastRootBox()->endsWithBreak()) {            // If the last line before the start line ends with a line break that clear floats,            // adjust the height accordingly.            // A line break can be either the first or the last object on a line, depending on its direction.            if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {                RenderObject* lastObject = lastLeafChild->renderer();                if (!lastObject->isBR())                    lastObject = lastRootBox()->firstLeafChild()->renderer();                if (lastObject->isBR()) {                    EClear clear = lastObject->style()->clear();                    if (clear != CNONE)                        newLine(clear);                }            }        }        bool endLineMatched = false;        bool checkForEndLineMatch = endLine;        bool checkForFloatsFromLastLine = false;        int lastHeight = height();        while (!end.atEnd()) {            // FIXME: Is this check necessary before the first iteration or can it be moved to the end?            if (checkForEndLineMatch && (endLineMatched = matchedEndLine(resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineYPos, repaintBottom, repaintTop)))                break;            betweenMidpoints = false;            isLineEmpty = true;                        EClear clear = CNONE;            end = findNextLineBreak(resolver, firstLine, &clear);            if (resolver.position().atEnd()) {                resolver.deleteRuns();                checkForFloatsFromLastLine = true;                break;            }            ASSERT(end != resolver.position());            if (!isLineEmpty) {                bidiReorderLine(resolver, end);                ASSERT(resolver.position() == end);                BidiRun* trailingSpaceRun = 0;                if (!previousLineBrokeCleanly && resolver.runCount() && resolver.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()) {                    trailingSpaceRun = resolver.logicallyLastRun();                    RenderObject* lastObject = trailingSpaceRun->m_object;                    if (lastObject->isText()) {                        RenderText* lastText = toRenderText(lastObject);                        const UChar* characters = lastText->characters();                        int firstSpace = trailingSpaceRun->stop();                        while (firstSpace > trailingSpaceRun->start()) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -