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

📄 bidi.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            else if (!last)                last = curr;        }    }    if (!last)        return 0;    RootInlineBox* prev = last->prevRootBox();    cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakPos());    cleanLineBidiStatus = prev->lineBreakBidiStatus();    yPos = prev->blockHeight();    for (RootInlineBox* line = last; line; line = line->nextRootBox())        line->extractLine(); // Disconnect all line boxes from their render objects while preserving                             // their connections to one another.    return last;}bool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop){    if (resolver.position() == endLineStart) {        if (resolver.status() != endLineStatus)            return false;        int delta = height() - endYPos;        if (!delta || !m_floatingObjects)            return true;        // See if any floats end in the range along which we want to shift the lines vertically.        int top = min(height(), endYPos);        RootInlineBox* lastLine = endLine;        while (RootInlineBox* nextLine = lastLine->nextRootBox())            lastLine = nextLine;        int bottom = lastLine->blockHeight() + abs(delta);        for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {            if (f->m_bottom >= top && f->m_bottom < bottom)                return false;        }        return true;    }    // The first clean line doesn't match, but we can check a handful of following lines to try    // to match back up.    static int numLines = 8; // The # of lines we're willing to match against.    RootInlineBox* line = endLine;    for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {        if (line->lineBreakObj() == resolver.position().obj && line->lineBreakPos() == resolver.position().pos) {            // We have a match.            if (line->lineBreakBidiStatus() != resolver.status())                return false; // ...but the bidi state doesn't match.            RootInlineBox* result = line->nextRootBox();            // Set our yPos to be the block height of endLine.            if (result)                endYPos = line->blockHeight();            int delta = height() - endYPos;            if (delta && m_floatingObjects) {                // See if any floats end in the range along which we want to shift the lines vertically.                int top = min(height(), endYPos);                RootInlineBox* lastLine = endLine;                while (RootInlineBox* nextLine = lastLine->nextRootBox())                    lastLine = nextLine;                int bottom = lastLine->blockHeight() + abs(delta);                for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {                    if (f->m_bottom >= top && f->m_bottom < bottom)                        return false;                }            }            // Now delete the lines that we failed to sync.            RootInlineBox* boxToDelete = endLine;            RenderArena* arena = renderArena();            while (boxToDelete && boxToDelete != result) {                repaintTop = min(repaintTop, boxToDelete->topOverflow());                repaintBottom = max(repaintBottom, boxToDelete->bottomOverflow());                RootInlineBox* next = boxToDelete->nextRootBox();                boxToDelete->deleteLine(arena);                boxToDelete = next;            }            endLine = result;            return result;        }    }    return false;}static inline bool skipNonBreakingSpace(const InlineIterator& it){    if (it.obj->style()->nbspMode() != SPACE || it.current() != noBreakSpace)        return false;    // FIXME: This is bad.  It makes nbsp inconsistent with space and won't work correctly    // with m_minWidth/m_maxWidth.    // Do not skip a non-breaking space if it is the first character    // on a line after a clean line break (or on the first line, since previousLineBrokeCleanly starts off    // |true|).    if (isLineEmpty && previousLineBrokeCleanly)        return false;    return true;}static inline bool shouldCollapseWhiteSpace(const RenderStyle* style){    return style->collapseWhiteSpace() || (style->whiteSpace() == PRE_WRAP && (!isLineEmpty || !previousLineBrokeCleanly));}static inline bool shouldPreserveNewline(RenderObject* object){#if ENABLE(SVG)    if (object->isSVGText())        return false;#endif    return object->style()->preserveNewline();}static bool inlineFlowRequiresLineBox(RenderInline* flow){    // FIXME: Right now, we only allow line boxes for inlines that are truly empty.    // We need to fix this, though, because at the very least, inlines containing only    // ignorable whitespace should should also have line boxes.     return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();}static inline bool requiresLineBox(const InlineIterator& it){    if (it.obj->isFloatingOrPositioned())        return false;    if (it.obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(it.obj)))        return false;    if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR())        return true;    UChar current = it.current();    return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || shouldPreserveNewline(it.obj)) && !skipNonBreakingSpace(it);}bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj){    ASSERT(inlineObj->parent() == this);    InlineIterator it(this, inlineObj, 0);    while (!it.atEnd() && !requiresLineBox(it))        it.increment();    return !it.atEnd();}// FIXME: The entire concept of the skipTrailingWhitespace function is flawed, since we really need to be building// line boxes even for containers that may ultimately collapse away.  Otherwise we'll never get positioned// elements quite right.  In other words, we need to build this function's work into the normal line// object iteration process.// NB. this function will insert any floating elements that would otherwise// be skipped but it will not position them.void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator){    while (!iterator.atEnd() && !requiresLineBox(iterator)) {        RenderObject* object = iterator.obj;        if (object->isFloating()) {            insertFloatingObject(toRenderBox(object));        } else if (object->isPositioned()) {            // FIXME: The math here is actually not really right.  It's a best-guess approximation that            // will work for the common cases            RenderObject* c = object->container();            if (c->isRenderInline()) {                // A relative positioned inline encloses us.  In this case, we also have to determine our                // position as though we were an inline.  Set |staticX| and |staticY| on the relative positioned                // inline so that we can obtain the value later.                toRenderInline(c)->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), false) : rightOffset(height(), false));                toRenderInline(c)->layer()->setStaticY(height());            }                RenderBox* box = toRenderBox(object);            if (box->style()->hasStaticX()) {                if (box->style()->isOriginalDisplayInlineType())                    box->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), false) : width() - rightOffset(height(), false));                else                    box->layer()->setStaticX(style()->direction() == LTR ? borderLeft() + paddingLeft() : borderRight() + paddingRight());            }                if (box->style()->hasStaticY())                box->layer()->setStaticY(height());        }        iterator.increment();    }}int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine){    int availableWidth = lineWidth(height(), firstLine);    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position())) {        RenderObject* object = resolver.position().obj;        if (object->isFloating()) {            insertFloatingObject(toRenderBox(object));            positionNewFloats();            availableWidth = lineWidth(height(), firstLine);        } else if (object->isPositioned()) {            // FIXME: The math here is actually not really right.  It's a best-guess approximation that            // will work for the common cases            RenderObject* c = object->container();            if (c->isRenderInline()) {                // A relative positioned inline encloses us.  In this case, we also have to determine our                // position as though we were an inline.  Set |staticX| and |staticY| on the relative positioned                // inline so that we can obtain the value later.                toRenderInline(c)->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), firstLine) : rightOffset(height(), firstLine));                toRenderInline(c)->layer()->setStaticY(height());            }                RenderBox* box = toRenderBox(object);            if (box->style()->hasStaticX()) {                if (box->style()->isOriginalDisplayInlineType())                    box->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), firstLine) : width() - rightOffset(height(), firstLine));                else                    box->layer()->setStaticX(style()->direction() == LTR ? borderLeft() + paddingLeft() : borderRight() + paddingRight());            }                if (box->style()->hasStaticY())                box->layer()->setStaticY(height());        }        resolver.increment();    }    resolver.commitExplicitEmbedding();    return availableWidth;}// This is currently just used for list markers and inline flows that have line boxes. Neither should // have an effect on whitespace at the start of the line. static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o){    RenderObject* next = bidiNext(block, o);    if (next && !next->isBR() && next->isText() && toRenderText(next)->textLength() > 0) {        RenderText* nextText = toRenderText(next);        UChar nextChar = nextText->characters()[0];        if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) {            addMidpoint(InlineIterator(0, o, 0));            return true;        }    }    return false;}void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth){    ASSERT(widthToFit > availableWidth);    int floatBottom;    int lastFloatBottom = height();    int newLineWidth = availableWidth;    while (true) {        floatBottom = nextFloatBottomBelow(lastFloatBottom);        if (!floatBottom)            break;        newLineWidth = lineWidth(floatBottom, firstLine);        lastFloatBottom = floatBottom;        if (newLineWidth >= widthToFit)            break;    }    if (newLineWidth > availableWidth) {        setHeight(lastFloatBottom);        availableWidth = newLineWidth;    }}static inline unsigned textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, int xPos, bool isFixedPitch, bool collapseWhiteSpace){    if (isFixedPitch || !from && len == text->textLength())        return text->width(from, len, font, xPos);    return font.width(TextRun(text->characters() + from, len, !collapseWhiteSpace, xPos));}InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, EClear* clear){    ASSERT(resolver.position().block == this);    bool appliedStartWidth = resolver.position().pos > 0;    int width = skipLeadingWhitespace(resolver, firstLine);    int w = 0;    int tmpW = 0;    if (resolver.position().atEnd())        return resolver.position();    // This variable is used only if whitespace isn't set to PRE, and it tells us whether    // or not we are currently ignoring whitespace.    bool ignoringSpaces = false;    InlineIterator ignoreStart;        // This variable tracks whether the very last character we saw was a space.  We use    // this to detect when we encounter a second space so we know we have to terminate    // a run.    bool currentCharacterIsSpace = false;    bool currentCharacterIsWS = false;    RenderObject* trailingSpaceObject = 0;    InlineIterator lBreak = resolver.position();    RenderObject *o = 

⌨️ 快捷键说明

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