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

📄 inlinetextbox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    bool useCustomUnderlines = containsComposition && renderer()->document()->frame()->editor()->compositionUsesCustomUnderlines();    // Set our font.    RenderStyle* styleToUse = renderer()->style(m_firstLine);    int d = styleToUse->textDecorationsInEffect();    const Font& font = styleToUse->font();    // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection    // and composition underlines.    if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && !isPrinting) {#if PLATFORM(MAC)        // Custom highlighters go behind everything else.        if (styleToUse->highlight() != nullAtom && !context->paintingDisabled())            paintCustomHighlight(tx, ty, styleToUse->highlight());#endif        if (containsComposition && !useCustomUnderlines)            paintCompositionBackground(context, tx, ty, styleToUse, font,                renderer()->document()->frame()->editor()->compositionStart(),                renderer()->document()->frame()->editor()->compositionEnd());        paintDocumentMarkers(context, tx, ty, styleToUse, font, true);        if (haveSelection && !useCustomUnderlines)            paintSelection(context, tx, ty, styleToUse, font);    }    // 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only).    if (m_len <= 0)        return;    Color textFillColor;    Color textStrokeColor;    float textStrokeWidth = styleToUse->textStrokeWidth();    ShadowData* textShadow = paintInfo.forceBlackText ? 0 : styleToUse->textShadow();    if (paintInfo.forceBlackText) {        textFillColor = Color::black;        textStrokeColor = Color::black;    } else {        textFillColor = styleToUse->textFillColor();        if (!textFillColor.isValid())            textFillColor = styleToUse->color();        // Make the text fill color legible against a white background        if (styleToUse->forceBackgroundsToWhite())            textFillColor = correctedTextColor(textFillColor, Color::white);        textStrokeColor = styleToUse->textStrokeColor();        if (!textStrokeColor.isValid())            textStrokeColor = styleToUse->color();        // Make the text stroke color legible against a white background        if (styleToUse->forceBackgroundsToWhite())            textStrokeColor = correctedTextColor(textStrokeColor, Color::white);    }    bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection);    bool paintSelectedTextSeparately = false;    Color selectionFillColor = textFillColor;    Color selectionStrokeColor = textStrokeColor;    float selectionStrokeWidth = textStrokeWidth;    ShadowData* selectionShadow = textShadow;    if (haveSelection) {        // Check foreground color first.        Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor();        if (foreground.isValid() && foreground != selectionFillColor) {            if (!paintSelectedTextOnly)                paintSelectedTextSeparately = true;            selectionFillColor = foreground;        }        if (RenderStyle* pseudoStyle = renderer()->getCachedPseudoStyle(SELECTION)) {            ShadowData* shadow = paintInfo.forceBlackText ? 0 : pseudoStyle->textShadow();            if (shadow != selectionShadow) {                if (!paintSelectedTextOnly)                    paintSelectedTextSeparately = true;                selectionShadow = shadow;            }            float strokeWidth = pseudoStyle->textStrokeWidth();            if (strokeWidth != selectionStrokeWidth) {                if (!paintSelectedTextOnly)                    paintSelectedTextSeparately = true;                selectionStrokeWidth = strokeWidth;            }            Color stroke = paintInfo.forceBlackText ? Color::black : pseudoStyle->textStrokeColor();            if (!stroke.isValid())                stroke = pseudoStyle->color();            if (stroke != selectionStrokeColor) {                if (!paintSelectedTextOnly)                    paintSelectedTextSeparately = true;                selectionStrokeColor = stroke;            }        }    }    int baseline = renderer()->style(m_firstLine)->font().ascent();    IntPoint textOrigin(m_x + tx, m_y + ty + baseline);    TextRun textRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered());    int sPos = 0;    int ePos = 0;    if (paintSelectedTextOnly || paintSelectedTextSeparately)        selectionStartEnd(sPos, ePos);    if (!paintSelectedTextOnly) {        // For stroked painting, we have to change the text drawing mode.  It's probably dangerous to leave that mutated as a side        // effect, so only when we know we're stroking, do a save/restore.        if (textStrokeWidth > 0)            context->save();        updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth);        if (!paintSelectedTextSeparately || ePos <= sPos) {            // FIXME: Truncate right-to-left text correctly.            paintTextWithShadows(context, font, textRun, 0, m_truncation == cNoTruncation ? m_len : m_truncation, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);        } else            paintTextWithShadows(context, font, textRun, ePos, sPos, textOrigin, m_x + tx, m_y + ty, width(), height(), textShadow, textStrokeWidth > 0);        if (textStrokeWidth > 0)            context->restore();    }    if ((paintSelectedTextOnly || paintSelectedTextSeparately) && sPos < ePos) {        // paint only the text that is selected        if (selectionStrokeWidth > 0)            context->save();        updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth);        paintTextWithShadows(context, font, textRun, sPos, ePos, textOrigin, m_x + tx, m_y + ty, width(), height(), selectionShadow, selectionStrokeWidth > 0);        if (selectionStrokeWidth > 0)            context->restore();    }    // Paint decorations    if (d != TDNONE && paintInfo.phase != PaintPhaseSelection && styleToUse->htmlHacks()) {        context->setStrokeColor(styleToUse->color());        paintDecoration(context, tx, ty, d, textShadow);    }    if (paintInfo.phase == PaintPhaseForeground) {        paintDocumentMarkers(context, tx, ty, styleToUse, font, false);        if (useCustomUnderlines) {            const Vector<CompositionUnderline>& underlines = renderer()->document()->frame()->editor()->customCompositionUnderlines();            size_t numUnderlines = underlines.size();            for (size_t index = 0; index < numUnderlines; ++index) {                const CompositionUnderline& underline = underlines[index];                if (underline.endOffset <= start())                    // underline is completely before this run.  This might be an underline that sits                    // before the first run we draw, or underlines that were within runs we skipped                     // due to truncation.                    continue;                                if (underline.startOffset <= end()) {                    // underline intersects this run.  Paint it.                    paintCompositionUnderline(context, tx, ty, underline);                    if (underline.endOffset > end() + 1)                        // underline also runs into the next run. Bail now, no more marker advancement.                        break;                } else                    // underline is completely after this run, bail.  A later run will paint it.                    break;            }        }    }}void InlineTextBox::selectionStartEnd(int& sPos, int& ePos){    int startPos, endPos;    if (renderer()->selectionState() == RenderObject::SelectionInside) {        startPos = 0;        endPos = textRenderer()->textLength();    } else {        textRenderer()->selectionStartEnd(startPos, endPos);        if (renderer()->selectionState() == RenderObject::SelectionStart)            endPos = textRenderer()->textLength();        else if (renderer()->selectionState() == RenderObject::SelectionEnd)            startPos = 0;    }    sPos = max(startPos - m_start, 0);    ePos = min(endPos - m_start, (int)m_len);}void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font){    // See if we have a selection to paint at all.    int sPos, ePos;    selectionStartEnd(sPos, ePos);    if (sPos >= ePos)        return;    Color textColor = style->color();    Color c = renderer()->selectionBackgroundColor();    if (!c.isValid() || c.alpha() == 0)        return;    // If the text color ends up being the same as the selection background, invert the selection    // background.  This should basically never happen, since the selection has transparency.    if (textColor == c)        c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());    context->save();    updateGraphicsContext(context, c, c, 0);  // Don't draw text at all!    int y = selectionTop();    int h = selectionHeight();    context->clip(IntRect(m_x + tx, y + ty, m_width, h));    context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,                                   direction() == RTL, m_dirOverride || style->visuallyOrdered()),                                  IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);    context->restore();}void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font, int startPos, int endPos){    int offset = m_start;    int sPos = max(startPos - offset, 0);    int ePos = min(endPos - offset, (int)m_len);    if (sPos >= ePos)        return;    context->save();    Color c = Color(225, 221, 85);        updateGraphicsContext(context, c, c, 0); // Don't draw text at all!    int y = selectionTop();    int h = selectionHeight();    context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,                                  direction() == RTL, m_dirOverride || style->visuallyOrdered()),                                  IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);    context->restore();}#if PLATFORM(MAC)void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& type){    Frame* frame = renderer()->document()->frame();    if (!frame)        return;    Page* page = frame->page();    if (!page)        return;    RootInlineBox* r = root();    FloatRect rootRect(tx + r->x(), ty + selectionTop(), r->width(), selectionHeight());    FloatRect textRect(tx + x(), rootRect.y(), width(), rootRect.height());    page->chrome()->client()->paintCustomHighlight(renderer()->node(), type, textRect, rootRect, true, false);}#endifvoid InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, int deco, ShadowData* shadow){    tx += m_x;    ty += m_y;    if (m_truncation == cFullTruncation)        return;    int width = m_width;    if (m_truncation != cNoTruncation) {        width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), m_firstLine);        if (direction() == RTL)            tx += (m_width - width);    }        // Get the text decoration colors.    Color underline, overline, linethrough;    renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true);        // Use a special function for underlines to get the positioning exactly right.    bool isPrinting = textRenderer()->document()->printing();    context->setStrokeThickness(1.0f); // FIXME: We should improve this rule and not always just assume 1.    bool linesAreOpaque = !isPrinting && (!(deco & UNDERLINE) || underline.alpha() == 255) && (!(deco & OVERLINE) || overline.alpha() == 255) && (!(deco & LINE_THROUGH) || linethrough.alpha() == 255);    int baseline = renderer()->style(m_firstLine)->font().ascent();    bool setClip = false;    int extraOffset = 0;    if (!linesAreOpaque && shadow && shadow->next) {        context->save();        IntRect clipRect(tx, ty, width, baseline + 2);        for (ShadowData* s = shadow; s; s = s->next) {            IntRect shadowRect(tx, ty, width, baseline + 2);            shadowRect.inflate(s->blur);            shadowRect.move(s->x, s->y);            clipRect.unite(shadowRect);            extraOffset = max(extraOffset, max(0, s->y) + s->blur);        }        context->save();        context->clip(clipRect);        extraOffset += baseline + 2;        ty += extraOffset;        setClip = true;    }    bool setShadow = false;        do {

⌨️ 快捷键说明

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