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

📄 renderlistmarker.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    TextRun textRun(m_text);    // Text is not arbitrary. We can judge whether it's RTL from the first character,    // and we only need to handle the direction RightToLeft for now.    bool textNeedsReversing = direction(m_text[0]) == RightToLeft;    Vector<UChar> reversedText;    if (textNeedsReversing) {        int length = m_text.length();        reversedText.grow(length);        for (int i = 0; i < length; ++i)            reversedText[length - i - 1] = m_text[i];        textRun = TextRun(reversedText.data(), length);    }    const Font& font = style()->font();    if (style()->direction() == LTR) {        int width = font.width(textRun);        context->drawText(style()->font(), textRun, marker.location());        const UChar periodSpace[2] = { '.', ' ' };        context->drawText(style()->font(), TextRun(periodSpace, 2), marker.location() + IntSize(width, 0));    } else {        const UChar spacePeriod[2] = { ' ', '.' };        TextRun spacePeriodRun(spacePeriod, 2);        int width = font.width(spacePeriodRun);        context->drawText(style()->font(), spacePeriodRun, marker.location());        context->drawText(style()->font(), textRun, marker.location() + IntSize(width, 0));    }}void RenderListMarker::layout(){    ASSERT(needsLayout());    ASSERT(!prefWidthsDirty());    if (isImage()) {        setWidth(m_image->imageSize(this, style()->effectiveZoom()).width());        setHeight(m_image->imageSize(this, style()->effectiveZoom()).height());    } else {        setWidth(minPrefWidth());        setHeight(style()->font().height());    }    m_marginLeft = m_marginRight = 0;    Length leftMargin = style()->marginLeft();    Length rightMargin = style()->marginRight();    if (leftMargin.isFixed())        m_marginLeft = leftMargin.value();    if (rightMargin.isFixed())        m_marginRight = rightMargin.value();    setNeedsLayout(false);}void RenderListMarker::imageChanged(WrappedImagePtr o, const IntRect*){    // A list marker can't have a background or border image, so no need to call the base class method.    if (o != m_image->data())        return;    if (width() != m_image->imageSize(this, style()->effectiveZoom()).width() || height() != m_image->imageSize(this, style()->effectiveZoom()).height() || m_image->errorOccurred())        setNeedsLayoutAndPrefWidthsRecalc();    else        repaint();}void RenderListMarker::calcPrefWidths(){    ASSERT(prefWidthsDirty());    m_text = "";    const Font& font = style()->font();    if (isImage()) {        // FIXME: This is a somewhat arbitrary width.  Generated images for markers really won't become particularly useful        // until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box.        int bulletWidth = font.ascent() / 2;        m_image->setImageContainerSize(IntSize(bulletWidth, bulletWidth));        m_minPrefWidth = m_maxPrefWidth = m_image->imageSize(this, style()->effectiveZoom()).width();        setPrefWidthsDirty(false);        updateMargins();        return;    }    int width = 0;    EListStyleType type = style()->listStyleType();    switch (type) {        case LNONE:            break;        case CIRCLE:        case DISC:        case SQUARE:            m_text = listMarkerText(type, 0); // value is ignored for these types            width = (font.ascent() * 2 / 3 + 1) / 2 + 2;            break;        case ARMENIAN:        case CJK_IDEOGRAPHIC:        case DECIMAL_LEADING_ZERO:        case GEORGIAN:        case HEBREW:        case HIRAGANA:        case HIRAGANA_IROHA:        case KATAKANA:        case KATAKANA_IROHA:        case LDECIMAL:        case LOWER_ALPHA:        case LOWER_GREEK:        case LOWER_LATIN:        case LOWER_ROMAN:        case UPPER_ALPHA:        case UPPER_LATIN:        case UPPER_ROMAN:            m_text = listMarkerText(type, m_listItem->value());            if (m_text.isEmpty())                width = 0;            else {                int itemWidth = font.width(m_text);                const UChar periodSpace[2] = { '.', ' ' };                int periodSpaceWidth = font.width(TextRun(periodSpace, 2));                width = itemWidth + periodSpaceWidth;            }            break;    }    m_minPrefWidth = width;    m_maxPrefWidth = width;    setPrefWidthsDirty(false);        updateMargins();}void RenderListMarker::updateMargins(){    const Font& font = style()->font();    int marginLeft = 0;    int marginRight = 0;    if (isInside()) {        if (isImage()) {            if (style()->direction() == LTR)                marginRight = cMarkerPadding;            else                marginLeft = cMarkerPadding;        } else switch (style()->listStyleType()) {            case DISC:            case CIRCLE:            case SQUARE:                if (style()->direction() == LTR) {                    marginLeft = -1;                    marginRight = font.ascent() - minPrefWidth() + 1;                } else {                    marginLeft = font.ascent() - minPrefWidth() + 1;                    marginRight = -1;                }                break;            default:                break;        }    } else {        if (style()->direction() == LTR) {            if (isImage())                marginLeft = -minPrefWidth() - cMarkerPadding;            else {                int offset = font.ascent() * 2 / 3;                switch (style()->listStyleType()) {                    case DISC:                    case CIRCLE:                    case SQUARE:                        marginLeft = -offset - cMarkerPadding - 1;                        break;                    case LNONE:                        break;                    default:                        marginLeft = m_text.isEmpty() ? 0 : -minPrefWidth() - offset / 2;                }            }        } else {            if (isImage())                marginLeft = cMarkerPadding;            else {                int offset = font.ascent() * 2 / 3;                switch (style()->listStyleType()) {                    case DISC:                    case CIRCLE:                    case SQUARE:                        marginLeft = offset + cMarkerPadding + 1 - minPrefWidth();                        break;                    case LNONE:                        break;                    default:                        marginLeft = m_text.isEmpty() ? 0 : offset / 2;                }            }        }        marginRight = -marginLeft - minPrefWidth();    }    style()->setMarginLeft(Length(marginLeft, Fixed));    style()->setMarginRight(Length(marginRight, Fixed));}int RenderListMarker::lineHeight(bool, bool) const{    if (!isImage())        return m_listItem->lineHeight(false, true);    return height();}int RenderListMarker::baselinePosition(bool, bool) const{    if (!isImage()) {        const Font& font = style()->font();        return font.ascent() + (lineHeight(false) - font.height())/2;    }    return height();}bool RenderListMarker::isInside() const{    return m_listItem->notInList() || style()->listStylePosition() == INSIDE;}IntRect RenderListMarker::getRelativeMarkerRect(){    if (isImage())        return IntRect(x(), y(), m_image->imageSize(this, style()->effectiveZoom()).width(), m_image->imageSize(this, style()->effectiveZoom()).height());    switch (style()->listStyleType()) {        case DISC:        case CIRCLE:        case SQUARE: {            // FIXME: Are these particular rounding rules necessary?            const Font& font = style()->font();            int ascent = font.ascent();            int bulletWidth = (ascent * 2 / 3 + 1) / 2;            return IntRect(x() + 1, y() + 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);        }        case LNONE:            return IntRect();        case ARMENIAN:        case CJK_IDEOGRAPHIC:        case DECIMAL_LEADING_ZERO:        case GEORGIAN:        case HEBREW:        case HIRAGANA:        case HIRAGANA_IROHA:        case KATAKANA:        case KATAKANA_IROHA:        case LDECIMAL:        case LOWER_ALPHA:        case LOWER_GREEK:        case LOWER_LATIN:        case LOWER_ROMAN:        case UPPER_ALPHA:        case UPPER_LATIN:        case UPPER_ROMAN:            if (m_text.isEmpty())                return IntRect();            const Font& font = style()->font();            int itemWidth = font.width(m_text);            const UChar periodSpace[2] = { '.', ' ' };            int periodSpaceWidth = font.width(TextRun(periodSpace, 2));            return IntRect(x(), y() + font.ascent(), itemWidth + periodSpaceWidth, font.height());    }    return IntRect();}void RenderListMarker::setSelectionState(SelectionState state){    RenderBox::setSelectionState(state);    if (InlineBox* box = inlineBoxWrapper())        if (RootInlineBox* root = box->root())            root->setHasSelectedChildren(state != SelectionNone);    containingBlock()->setSelectionState(state);}IntRect RenderListMarker::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent){    ASSERT(!needsLayout());    if (selectionState() == SelectionNone || !inlineBoxWrapper())        return IntRect();    RootInlineBox* root = inlineBoxWrapper()->root();    IntRect rect(0, root->selectionTop() - y(), width(), root->selectionHeight());                if (clipToVisibleContent)        computeRectForRepaint(repaintContainer, rect);    else        rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();        return rect;}} // namespace WebCore

⌨️ 快捷键说明

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