📄 render_text.cpp
字号:
int sPos = QMAX( startPos - offset, 0 ); int ePos = QMIN( endPos - offset, s->m_len ); if (paintSelectedTextSeparately) { if (sPos >= ePos)#if APPLE_CHANGES font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered());#else font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR);#endif else { if (sPos-1 >= 0)#if APPLE_CHANGES font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), 0, sPos);#else font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, 0, sPos);#endif if (ePos < s->m_start+s->m_len)#if APPLE_CHANGES font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), ePos, -1);#else font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, ePos, -1);#endif } } if ( sPos < ePos ) { if (selectionColor != p->pen().color()) p->setPen(selectionColor);#if APPLE_CHANGES if (selectionTextShadow) p->setShadow(selectionTextShadow->x, selectionTextShadow->y, selectionTextShadow->blur, selectionTextShadow->color);#endif #if APPLE_CHANGES font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered(), sPos, ePos);#else font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline, str->s, str->l, s->m_start, s->m_len, s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, sPos, ePos);#endif#if APPLE_CHANGES if (selectionTextShadow) p->clearShadow();#endif } } } if (d != TDNONE && i.phase == PaintActionForeground && style()->htmlHacks()) { p->setPen(_style->color()); s->paintDecoration(p, tx, ty, d); }#if APPLE_CHANGES if (setShadow) p->clearShadow(); } // drawText#endif#if APPLE_CHANGES if (drawSelectionBackground)#endif if (!isPrinting && (selectionState() != SelectionNone)) s->paintSelection(font, this, p, _style, tx, ty, startPos, endPos, selectionState() == SelectionInside);#ifdef BIDI_DEBUG { int h = lineHeight( false ) + paddingTop() + paddingBottom() + borderTop() + borderBottom(); QColor c2 = QColor("#0000ff"); drawBorder(p, tx, ty, tx+1, ty + h, RenderObject::BSLeft, c2, c2, SOLID, 1, 1); drawBorder(p, tx + s->m_width, ty, tx + s->m_width + 1, ty + h, RenderObject::BSRight, c2, c2, SOLID, 1, 1); }#endif } while (((s = s->nextTextBox()) != 0) && s->checkVerticalPoint(i.r.y(), ty, i.r.height()));#if APPLE_CHANGES } // end of for loop#endif}#ifdef APPLE_CHANGESbool RenderText::allAscii() const{ if (m_allAsciiChecked) return m_allAscii; m_allAsciiChecked = true; unsigned int i; for (i = 0; i < str->l; i++){ if (str->s[i].unicode() >= 0x7f){ m_allAscii = false; return m_allAscii; } } m_allAscii = true; return m_allAscii;}bool RenderText::shouldUseMonospaceCache(const Font *f) const{ return (f && f->isFixedPitch() && allAscii() && !style()->htmlFont().isSmallCaps());}// We cache the width of the ' ' character for <pre> text. We could go futher// and cache a widths array for all styles, at the expense of increasing the size of the// RenderText.void RenderText::cacheWidths(){ const Font *f = htmlFont( false ); if (shouldUseMonospaceCache(f)){ float fw; QChar c(' '); f->floatCharacterWidths( &c, 1, 0, 1, 0, &fw); m_monospaceCharacterWidth = (int)fw; } else m_monospaceCharacterWidth = 0;}inline int RenderText::widthFromCache(const Font *f, int start, int len) const{ if (m_monospaceCharacterWidth != 0){ int i, w = 0; for (i = start; i < start+len; i++){ int dir = str->s[i].direction(); if (dir != QChar::DirNSM && dir != QChar::DirBN) w += m_monospaceCharacterWidth; } return w; } return f->width(str->s, str->l, start, len);}#ifdef XXXinline int RenderText::widthFromCache(const Font *f, int start, int len) const{ if (m_monospaceCharacterWidth != 0){ return len * m_monospaceCharacterWidth; } return f->width(str->s, str->l, start, len);}#endif#endifvoid RenderText::trimmedMinMaxWidth(int& beginMinW, bool& beginWS, int& endMinW, bool& endWS, bool& hasBreakableChar, bool& hasBreak, int& beginMaxW, int& endMaxW, int& minW, int& maxW, bool& stripFrontSpaces){ bool isPre = style()->whiteSpace() == PRE; if (isPre) stripFrontSpaces = false; int len = str->l; if (len == 0 || (stripFrontSpaces && str->containsOnlyWhitespace())) { maxW = 0; hasBreak = false; return; } minW = m_minWidth; maxW = m_maxWidth; beginWS = stripFrontSpaces ? false : m_hasBeginWS; endWS = m_hasEndWS; beginMinW = m_beginMinWidth; endMinW = m_endMinWidth; hasBreakableChar = m_hasBreakableChar; hasBreak = m_hasBreak; if (stripFrontSpaces && (str->s[0] == ' ' || (!isPre && str->s[0] == '\n'))) { const Font *f = htmlFont( false ); QChar space[1]; space[0] = ' '; int spaceWidth = f->width(space, 1, 0); maxW -= spaceWidth; } stripFrontSpaces = !isPre && m_hasEndWS; if (style()->whiteSpace() == NOWRAP) minW = maxW; else if (minW > maxW) minW = maxW; // Compute our max widths by scanning the string for newlines. if (hasBreak) { const Font *f = htmlFont( false ); bool firstLine = true; beginMaxW = endMaxW = maxW; for (int i = 0; i < len; i++) { int linelen = 0; while (i+linelen < len && str->s[i+linelen] != '\n') linelen++; if (linelen) {#if !APPLE_CHANGES endMaxW = f->width(str->s, str->l, i, linelen);#else endMaxW = widthFromCache(f, i, linelen);#endif if (firstLine) { firstLine = false; beginMaxW = endMaxW; } i += linelen; } else if (firstLine) { beginMaxW = 0; firstLine = false; } if (i == len-1) // A <pre> run that ends with a newline, as in, e.g., // <pre>Some text\n\n<span>More text</pre> endMaxW = 0; } }}void RenderText::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() ); // ### calc Min and Max width... m_minWidth = m_beginMinWidth = m_endMinWidth = 0; m_maxWidth = 0; if (isBR()) return; int currMinWidth = 0; int currMaxWidth = 0; m_hasBreakableChar = m_hasBreak = m_hasBeginWS = m_hasEndWS = false; // ### not 100% correct for first-line const Font *f = htmlFont( false ); int wordSpacing = style()->wordSpacing(); int len = str->l; bool ignoringSpaces = false; bool isSpace = false; bool isPre = style()->whiteSpace() == PRE; bool firstWord = true; bool firstLine = true; for(int i = 0; i < len; i++) { const QChar c = str->s[i]; bool previousCharacterIsSpace = isSpace; bool isNewline = false; if (c == '\n') { if (isPre) { m_hasBreak = true; isNewline = true; isSpace = false; } else isSpace = true; } else { isSpace = c == ' '; } if ((isSpace || isNewline) && i == 0) m_hasBeginWS = true; if ((isSpace || isNewline) && i == len-1) m_hasEndWS = true; if (!ignoringSpaces && !isPre && previousCharacterIsSpace && isSpace) ignoringSpaces = true; if (ignoringSpaces && !isSpace) ignoringSpaces = false; if (ignoringSpaces || (i > 0 && c.unicode() == SOFT_HYPHEN)) // Ignore spaces and soft hyphens continue; int wordlen = 0; while (i+wordlen < len && str->s[i+wordlen] != '\n' && str->s[i+wordlen] != ' ' && (i+wordlen == 0 || str->s[i+wordlen].unicode() != SOFT_HYPHEN) && // Skip soft hyphens (wordlen == 0 || !isBreakable( str->s, i+wordlen, str->l))) wordlen++; if (wordlen) {#if !APPLE_CHANGES int w = f->width(str->s, str->l, i, wordlen);#else int w = widthFromCache(f, i, wordlen);#endif currMinWidth += w; currMaxWidth += w; bool isBreakableCharSpace = (i+wordlen < len) ? ((!isPre && str->s[i+wordlen] == '\n') || str->s[i+wordlen] == ' ') : false; if (i+wordlen < len && style()->whiteSpace() == NORMAL) m_hasBreakableChar = true; // Add in wordspacing to our maxwidth, but not if this is the last word on a line or the // last word in the run. if (wordSpacing && isBreakableCharSpace && !containsOnlyWhitespace(i+wordlen, len-(i+wordlen))) currMaxWidth += wordSpacing; if (firstWord) { firstWord = false; // If the first character in the run is breakable, then we consider ourselves to have a beginning // minimum width of 0, since a break could occur right before our run starts, preventing us from ever // being appended to a previous text run when considering the total minimum width of the containing block. bool hasBreak = isBreakable(str->s, i, str->l); if (hasBreak) m_hasBreakableChar = true; m_beginMinWidth = hasBreak ? 0 : w; } m_endMinWidth = w; if (currMinWidth > m_minWidth) m_minWidth = currMinWidth; currMinWidth = 0; i += wordlen-1; } else { // Nowrap can never be broken, so don't bother setting the // breakable character boolean. Pre can only be broken if we encounter a newline. if (style()->whiteSpace() == NORMAL || isNewline) m_hasBreakableChar = true; if (currMinWidth > m_minWidth) m_minWidth = currMinWidth; currMinWidth = 0; if (isNewline) // Only set if isPre was true and we saw a newline. { if (firstLine) { firstLine = false; m_beginMinWidth = currMaxWidth; } if (currMaxWidth > m_maxWidth) m_maxWidth = currMaxWidth; currMaxWidth = 0; } else { currMaxWidth += f->width( str->s, str->l, i + wordlen ); } } } if(currMinWidth > m_minWidth) m_minWidth = currMinWidth; if(currMaxWidth > m_maxWidth) m_maxWidth = currMaxWidth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -