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

📄 inlinetextbox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        if (shadow) {            if (!shadow->next) {                // The last set of lines paints normally inside the clip.                ty -= extraOffset;                extraOffset = 0;            }            context->setShadow(IntSize(shadow->x, shadow->y - extraOffset), shadow->blur, shadow->color);            setShadow = true;            shadow = shadow->next;        }        if (deco & UNDERLINE) {            context->setStrokeColor(underline);            context->setStrokeStyle(SolidStroke);            // Leave one pixel of white between the baseline and the underline.            context->drawLineForText(IntPoint(tx, ty + baseline + 1), width, isPrinting);        }        if (deco & OVERLINE) {            context->setStrokeColor(overline);            context->setStrokeStyle(SolidStroke);            context->drawLineForText(IntPoint(tx, ty), width, isPrinting);        }        if (deco & LINE_THROUGH) {            context->setStrokeColor(linethrough);            context->setStrokeStyle(SolidStroke);            context->drawLineForText(IntPoint(tx, ty + 2 * baseline / 3), width, isPrinting);        }    } while (shadow);    if (setClip)        context->restore();    else if (setShadow)        context->clearShadow();}void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font, bool grammar){    // Never print spelling/grammar markers (5327887)    if (textRenderer()->document()->printing())        return;    if (m_truncation == cFullTruncation)        return;    int start = 0;                  // start of line to draw, relative to tx    int width = m_width;            // how much line to draw    // Determine whether we need to measure text    bool markerSpansWholeBox = true;    if (m_start <= (int)marker.startOffset)        markerSpansWholeBox = false;    if ((end() + 1) != marker.endOffset)      // end points at the last char, not past it        markerSpansWholeBox = false;    if (m_truncation != cNoTruncation)        markerSpansWholeBox = false;    if (!markerSpansWholeBox || grammar) {        int startPosition = max<int>(marker.startOffset - m_start, 0);        int endPosition = min<int>(marker.endOffset - m_start, m_len);                if (m_truncation != cNoTruncation)            endPosition = min<int>(endPosition, m_truncation);        // Calculate start & width        IntPoint startPoint(tx + m_x, ty + selectionTop());        TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());        int h = selectionHeight();                IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, startPosition, endPosition));        start = markerRect.x() - startPoint.x();        width = markerRect.width();                // Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to        // display a toolTip. We don't do this for misspelling markers.        if (grammar)            renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);    }        // IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to    // make sure to fit within those bounds.  This means the top pixel(s) of the underline will overlap the    // bottom pixel(s) of the glyphs in smaller font sizes.  The alternatives are to increase the line spacing (bad!!)    // or decrease the underline thickness.  The overlap is actually the most useful, and matches what AppKit does.    // So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so    // we pin to two pixels under the baseline.    int lineThickness = cMisspellingLineThickness;    int baseline = renderer()->style(m_firstLine)->font().ascent();    int descent = height() - baseline;    int underlineOffset;    if (descent <= (2 + lineThickness)) {        // Place the underline at the very bottom of the text in small/medium fonts.        underlineOffset = height() - lineThickness;    } else {        // In larger fonts, though, place the underline up near the baseline to prevent a big gap.        underlineOffset = baseline + 2;    }    pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar);}void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font){   // Use same y positioning and height as for selection, so that when the selection and this highlight are on   // the same word there are no pieces sticking out.    int y = selectionTop();    int h = selectionHeight();        int sPos = max(marker.startOffset - m_start, (unsigned)0);    int ePos = min(marker.endOffset - m_start, (unsigned)m_len);        TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());    IntPoint startPoint = IntPoint(m_x + tx, y + ty);        // Always compute and store the rect associated with this marker    IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));    renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);         // Optionally highlight the text    if (renderer()->document()->frame()->markedTextMatchesAreHighlighted()) {        Color color = theme()->platformTextSearchHighlightColor();        pt->save();        updateGraphicsContext(pt, color, color, 0);  // Don't draw text at all!        pt->clip(IntRect(tx + m_x, ty + y, m_width, h));        pt->drawHighlightForText(font, run, startPoint, h, color, sPos, ePos);        pt->restore();    }}void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, RenderStyle* style, const Font& font, bool background){    if (!renderer()->node())        return;    Vector<DocumentMarker> markers = renderer()->document()->markersForNode(renderer()->node());    Vector<DocumentMarker>::iterator markerIt = markers.begin();    // Give any document markers that touch this run a chance to draw before the text has been drawn.    // Note end() points at the last char, not one past it like endOffset and ranges do.    for ( ; markerIt != markers.end(); markerIt++) {        DocumentMarker marker = *markerIt;                // Paint either the background markers or the foreground markers, but not both        switch (marker.type) {            case DocumentMarker::Grammar:            case DocumentMarker::Spelling:                if (background)                    continue;                break;                            case DocumentMarker::TextMatch:                if (!background)                    continue;                break;                        default:                ASSERT_NOT_REACHED();        }        if (marker.endOffset <= start())            // marker is completely before this run.  This might be a marker that sits before the            // first run we draw, or markers that were within runs we skipped due to truncation.            continue;                if (marker.startOffset > end())            // marker is completely after this run, bail.  A later run will paint it.            break;                // marker intersects this run.  Paint it.        switch (marker.type) {            case DocumentMarker::Spelling:                paintSpellingOrGrammarMarker(pt, tx, ty, marker, style, font, false);                break;            case DocumentMarker::Grammar:                paintSpellingOrGrammarMarker(pt, tx, ty, marker, style, font, true);                break;            case DocumentMarker::TextMatch:                paintTextMatchMarker(pt, tx, ty, marker, style, font);                break;            default:                ASSERT_NOT_REACHED();        }    }}void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int ty, const CompositionUnderline& underline){    tx += m_x;    ty += m_y;    if (m_truncation == cFullTruncation)        return;        int start = 0;                 // start of line to draw, relative to tx    int width = m_width;           // how much line to draw    bool useWholeWidth = true;    unsigned paintStart = m_start;    unsigned paintEnd = end() + 1; // end points at the last char, not past it    if (paintStart <= underline.startOffset) {        paintStart = underline.startOffset;        useWholeWidth = false;        start = toRenderText(renderer())->width(m_start, paintStart - m_start, textPos(), m_firstLine);    }    if (paintEnd != underline.endOffset) {      // end points at the last char, not past it        paintEnd = min(paintEnd, (unsigned)underline.endOffset);        useWholeWidth = false;    }    if (m_truncation != cNoTruncation) {        paintEnd = min(paintEnd, (unsigned)m_start + m_truncation);        useWholeWidth = false;    }    if (!useWholeWidth) {        width = toRenderText(renderer())->width(paintStart, paintEnd - paintStart, textPos() + start, m_firstLine);    }    // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.    // All other marked text underlines are 1px thick.    // If there's not enough space the underline will touch or overlap characters.    int lineThickness = 1;    int baseline = renderer()->style(m_firstLine)->font().ascent();    if (underline.thick && height() - baseline >= 2)        lineThickness = 2;    // We need to have some space between underlines of subsequent clauses, because some input methods do not use different underline styles for those.    // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too.    start += 1;    width -= 2;    ctx->setStrokeColor(underline.color);    ctx->setStrokeThickness(lineThickness);    ctx->drawLineForText(IntPoint(tx + start, ty + height() - lineThickness), width, textRenderer()->document()->printing());}int InlineTextBox::caretMinOffset() const{    return m_start;}int InlineTextBox::caretMaxOffset() const{    return m_start + m_len;}unsigned InlineTextBox::caretMaxRenderedOffset() const{    return m_start + m_len;}int InlineTextBox::textPos() const{    if (x() == 0)        return 0;            RenderBlock *blockElement = renderer()->containingBlock();    return direction() == RTL ? x() - blockElement->borderRight() - blockElement->paddingRight()                      : x() - blockElement->borderLeft() - blockElement->paddingLeft();}int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const{    if (isLineBreak())        return 0;    RenderText* text = toRenderText(renderer());    RenderStyle *style = text->style(m_firstLine);    const Font* f = &style->font();    return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()),                                _x - m_x, includePartialGlyphs);}int InlineTextBox::positionForOffset(int offset) const{    ASSERT(offset >= m_start);    ASSERT(offset <= m_start + m_len);    if (isLineBreak())        return m_x;    RenderText* text = toRenderText(renderer());    const Font& f = text->style(m_firstLine)->font();    int from = direction() == RTL ? offset - m_start : 0;    int to = direction() == RTL ? m_len : offset - m_start;    // FIXME: Do we need to add rightBearing here?    return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride),                                                   IntPoint(m_x, 0), 0, from, to)).right();}bool InlineTextBox::containsCaretOffset(int offset) const{    // Offsets before the box are never "in".    if (offset < m_start)        return false;    int pastEnd = m_start + m_len;    // Offsets inside the box (not at either edge) are always "in".    if (offset < pastEnd)        return true;    // Offsets outside the box are always "out".    if (offset > pastEnd)        return false;    // Offsets at the end are "out" for line breaks (they are on the next line).    if (isLineBreak())        return false;    // Offsets at the end are "in" for normal boxes (but the caller has to check affinity).    return true;}} // namespace WebCore

⌨️ 快捷键说明

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