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

📄 bidi.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                            UChar current = characters[firstSpace - 1];                            if (!isCollapsibleSpace(current, lastText))                                break;                            firstSpace--;                        }                        if (firstSpace == trailingSpaceRun->stop())                            trailingSpaceRun = 0;                        else {                            TextDirection direction = style()->direction();                            bool shouldReorder = trailingSpaceRun != (direction == LTR ? resolver.lastRun() : resolver.firstRun());                            if (firstSpace != trailingSpaceRun->start()) {                                ETextAlign textAlign = style()->textAlign();                                // If the trailing white space is at the right hand side of a left-aligned line, then computeHorizontalPositionsForLine()                                // does not care if trailingSpaceRun includes non-spaces at the beginning. In all other cases, trailingSpaceRun has to                                // contain only the spaces, either because we re-order them or because computeHorizontalPositionsForLine() needs to know                                // their width.                                bool shouldSeparateSpaces = textAlign != LEFT && textAlign != WEBKIT_LEFT && textAlign != TAAUTO || trailingSpaceRun->m_level % 2 || direction == RTL || shouldReorder;                                if (shouldSeparateSpaces) {                                    BidiContext* baseContext = resolver.context();                                    while (BidiContext* parent = baseContext->parent())                                        baseContext = parent;                                    BidiRun* newTrailingRun = new (renderArena()) BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);                                    trailingSpaceRun->m_stop = firstSpace;                                    if (direction == LTR)                                        resolver.addRun(newTrailingRun);                                    else                                        resolver.prependRun(newTrailingRun);                                    trailingSpaceRun = newTrailingRun;                                    shouldReorder = false;                                }                            }                            if (shouldReorder) {                                if (direction == LTR) {                                    resolver.moveRunToEnd(trailingSpaceRun);                                    trailingSpaceRun->m_level = 0;                                } else {                                    resolver.moveRunToBeginning(trailingSpaceRun);                                    trailingSpaceRun->m_level = 1;                                }                            }                        }                    } else                        trailingSpaceRun = 0;                }                // Now that the runs have been ordered, we create the line boxes.                // At the same time we figure out where border/padding/margin should be applied for                // inline flow boxes.                RootInlineBox* lineBox = 0;                if (resolver.runCount()) {                    lineBox = constructLine(resolver.runCount(), resolver.firstRun(), resolver.lastRun(), firstLine, !end.obj, end.obj && !end.pos ? end.obj : 0);                    if (lineBox) {                        lineBox->setEndsWithBreak(previousLineBrokeCleanly);                        // Now we position all of our text runs horizontally.                        computeHorizontalPositionsForLine(lineBox, firstLine, resolver.firstRun(), trailingSpaceRun, end.atEnd());                        // Now position our text runs vertically.                        computeVerticalPositionsForLine(lineBox, resolver.firstRun());#if ENABLE(SVG)                        // Special SVG text layout code                        lineBox->computePerCharacterLayoutInformation();#endif#if PLATFORM(MAC)                        // Highlight acts as an overflow inflation.                        if (style()->highlight() != nullAtom)                            lineBox->addHighlightOverflow();#endif                    }                }                resolver.deleteRuns();                if (lineBox) {                    lineBox->setLineBreakInfo(end.obj, end.pos, resolver.status());                    if (useRepaintBounds) {                        repaintTop = min(repaintTop, lineBox->topOverflow());                        repaintBottom = max(repaintBottom, lineBox->bottomOverflow());                    }                }                firstLine = false;                newLine(clear);            }            if (m_floatingObjects && lastRootBox()) {                if (lastFloat) {                    for (FloatingObject* f = m_floatingObjects->last(); f != lastFloat; f = m_floatingObjects->prev()) {                    }                    m_floatingObjects->next();                } else                    m_floatingObjects->first();                for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {                    if (f->m_bottom > lastHeight)                        lastRootBox()->floats().append(f->m_renderer);                    ASSERT(f->m_renderer == floats[floatIndex].object);                    // If a float's geometry has changed, give up on syncing with clean lines.                    if (floats[floatIndex].rect != IntRect(f->m_left, f->m_top, f->m_width, f->m_bottom - f->m_top))                        checkForEndLineMatch = false;                    floatIndex++;                }                lastFloat = m_floatingObjects->last();            }            lastHeight = height();            sNumMidpoints = 0;            sCurrMidpoint = 0;            resolver.setPosition(end);        }        if (endLine) {            if (endLineMatched) {                // Attach all the remaining lines, and then adjust their y-positions as needed.                int delta = height() - endLineYPos;                for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {                    line->attachLine();                    if (delta) {                        repaintTop = min(repaintTop, line->topOverflow() + min(delta, 0));                        repaintBottom = max(repaintBottom, line->bottomOverflow() + max(delta, 0));                        line->adjustPosition(0, delta);                    }                    if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {                        Vector<RenderBox*>::iterator end = cleanLineFloats->end();                        for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {                            int floatTop = (*f)->y() - (*f)->marginTop();                            insertFloatingObject(*f);                            setHeight(floatTop + delta);                            positionNewFloats();                        }                    }                }                setHeight(lastRootBox()->blockHeight());            } else {                // Delete all the remaining lines.                InlineRunBox* line = endLine;                RenderArena* arena = renderArena();                while (line) {                    repaintTop = min(repaintTop, line->topOverflow());                    repaintBottom = max(repaintBottom, line->bottomOverflow());                    InlineRunBox* next = line->nextLineBox();                    line->deleteLine(arena);                    line = next;                }            }        }        if (m_floatingObjects && (checkForFloatsFromLastLine || positionNewFloats()) && lastRootBox()) {            // In case we have a float on the last line, it might not be positioned up to now.            // This has to be done before adding in the bottom border/padding, or the float will            // include the padding incorrectly. -dwh            if (lastFloat) {                for (FloatingObject* f = m_floatingObjects->last(); f != lastFloat; f = m_floatingObjects->prev()) {                }                m_floatingObjects->next();            } else                m_floatingObjects->first();            for (FloatingObject* f = m_floatingObjects->current(); f; f = m_floatingObjects->next()) {                if (f->m_bottom > lastHeight)                    lastRootBox()->floats().append(f->m_renderer);            }            lastFloat = m_floatingObjects->last();        }    }    sNumMidpoints = 0;    sCurrMidpoint = 0;    // Now add in the bottom border/padding.    setHeight(height() + toAdd);    // Always make sure this is at least our height.    m_overflowHeight = max(height(), m_overflowHeight);    // See if any lines spill out of the block.  If so, we need to update our overflow width.    checkLinesForOverflow();    if (!firstLineBox() && hasLineIfEmpty())        setHeight(height() + lineHeight(true, true));    // See if we have any lines that spill out of our block.  If we do, then we will possibly need to    // truncate text.    if (hasTextOverflow)        checkLinesForTextOverflow();}RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats){    RootInlineBox* curr = 0;    RootInlineBox* last = 0;    bool dirtiedByFloat = false;    if (!fullLayout) {        size_t floatIndex = 0;        for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {            if (Vector<RenderBox*>* cleanLineFloats = curr->floatsPtr()) {                Vector<RenderBox*>::iterator end = cleanLineFloats->end();                for (Vector<RenderBox*>::iterator o = cleanLineFloats->begin(); o != end; ++o) {                    RenderBox* f = *o;                    IntSize newSize(f->width() + f->marginLeft() +f->marginRight(), f->height() + f->marginTop() + f->marginBottom());                    ASSERT(floatIndex < floats.size());                    if (floats[floatIndex].object != f) {                        // A new float has been inserted before this line or before its last known float.                        // Just do a full layout.                        fullLayout = true;                        break;                    }                    if (floats[floatIndex].rect.size() != newSize) {                        int floatTop = floats[floatIndex].rect.y();                        curr->markDirty();                        markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()));                        floats[floatIndex].rect.setSize(newSize);                        dirtiedByFloat = true;                    }                    floatIndex++;                }            }            if (dirtiedByFloat || fullLayout)                break;        }        // Check if a new float has been inserted after the last known float.        if (!curr && floatIndex < floats.size())            fullLayout = true;    }    if (fullLayout) {        // Nuke all our lines.        if (firstRootBox()) {            RenderArena* arena = renderArena();            curr = firstRootBox();             while (curr) {                RootInlineBox* next = curr->nextRootBox();                curr->deleteLine(arena);                curr = next;            }            ASSERT(!firstLineBox() && !lastLineBox());        }    } else {        if (curr) {            // We have a dirty line.            if (RootInlineBox* prevRootBox = curr->prevRootBox()) {                // We have a previous line.                if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))                    // The previous line didn't break cleanly or broke at a newline                    // that has been deleted, so treat it as dirty too.                    curr = prevRootBox;            }        } else {            // No dirty lines were found.            // If the last line didn't break cleanly, treat it as dirty.            if (lastRootBox() && !lastRootBox()->endsWithBreak())                curr = lastRootBox();        }        // If we have no dirty lines, then last is just the last root box.        last = curr ? curr->prevRootBox() : lastRootBox();    }    numCleanFloats = 0;    if (!floats.isEmpty()) {        int savedHeight = height();        // Restore floats from clean lines.        RootInlineBox* line = firstRootBox();        while (line != curr) {            if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {                Vector<RenderBox*>::iterator end = cleanLineFloats->end();                for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {                    insertFloatingObject(*f);                    setHeight((*f)->y() - (*f)->marginTop());                    positionNewFloats();                    ASSERT(floats[numCleanFloats].object == *f);                    numCleanFloats++;                }            }            line = line->nextRootBox();        }        setHeight(savedHeight);    }    firstLine = !last;    previousLineBrokeCleanly = !last || last->endsWithBreak();    RenderObject* startObj;    int pos = 0;    if (last) {        setHeight(last->blockHeight());        startObj = last->lineBreakObj();        pos = last->lineBreakPos();        resolver.setStatus(last->lineBreakBidiStatus());    } else {        bool ltr = style()->direction() == LTR    #if ENABLE(SVG)               || (style()->unicodeBidi() == UBNormal && isSVGText())    #endif            ;        BidiContext* context = new BidiContext(ltr ? 0 : 1, ltr ? LeftToRight : RightToLeft, style()->unicodeBidi() == Override);        resolver.setLastStrongDir(context->dir());        resolver.setLastDir(context->dir());        resolver.setEorDir(context->dir());        resolver.setContext(context);        startObj = bidiFirst(this, &resolver);    }    resolver.setPosition(InlineIterator(this, startObj, pos));    return curr;}RootInlineBox* RenderBlock::determineEndPosition(RootInlineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus, int& yPos){    RootInlineBox* last = 0;    if (!startLine)        last = 0;    else {        for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->nextRootBox()) {            if (curr->isDirty())                last = 0;

⌨️ 快捷键说明

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