📄 render_text.cpp
字号:
int RenderText::inlineXPos() const{ return minXPos();}int RenderText::inlineYPos() const{ return m_lines.isEmpty() ? 0 : m_lines[0]->yPos();}const QFont &RenderText::font(){ return style()->font();}void RenderText::setText(DOMStringImpl *text, bool force){ if( !force && str == text ) return; DOMStringImpl *oldstr = str; if(text && style()) str = text->collapseWhiteSpace(style()->preserveLF(), style()->preserveWS()); else str = text; if(str) str->ref(); if(oldstr) oldstr->deref(); if ( str && style() ) { oldstr = str; switch(style()->textTransform()) { case CAPITALIZE: str = str->capitalize(); break; case UPPERCASE: str = str->upper(); break; case LOWERCASE: str = str->lower(); break; case NONE: default:; } str->ref(); oldstr->deref(); } // ### what should happen if we change the text of a // RenderBR object ? KHTMLAssert(!isBR() || (str->l == 1 && (*str->s) == '\n')); KHTMLAssert(!str->l || str->s); setNeedsLayoutAndMinMaxRecalc();#ifdef BIDI_DEBUG QConstString cstr(str->s, str->l); kdDebug( 6040 ) << "RenderText::setText( " << cstr.string().length() << " ) '" << cstr.string() << "'" << endl;#endif}int RenderText::height() const{ int retval; if ( m_lines.count() ) retval = m_lines[m_lines.count()-1]->m_y + m_lineHeight - m_lines[0]->m_y; else retval = metrics( false ).height(); return retval;}short RenderText::lineHeight( bool firstLine ) const{ if ( firstLine ) return RenderObject::lineHeight( firstLine ); return m_lineHeight;}short RenderText::baselinePosition( bool firstLine ) const{ const QFontMetrics &fm = metrics( firstLine ); return fm.ascent() + ( lineHeight( firstLine ) - fm.height() ) / 2;}InlineBox* RenderText::createInlineBox(bool, bool isRootLineBox){ KHTMLAssert( !isRootLineBox ); return new (renderArena()) InlineTextBox(this);}void RenderText::position(InlineBox* box, int from, int len, bool reverse){//kdDebug(6040) << "position: from="<<from<<" len="<<len<<endl; // ### should not be needed!!! // asserts sometimes with pre (that unibw-hamburg testcase). ### find out why //KHTMLAssert(!(len == 0 || (str->l && len == 1 && *(str->s+from) == '\n') )); // It is now needed. BRs need text boxes too otherwise caret navigation // gets stuck (LS) // if (len == 0 || (str->l && len == 1 && *(str->s+from) == '\n') ) return; reverse = reverse && !style()->visuallyOrdered();#ifdef DEBUG_LAYOUT QChar *ch = str->s+from; QConstString cstr(ch, len);#endif KHTMLAssert(box->isInlineTextBox()); InlineTextBox *s = static_cast<InlineTextBox *>(box); s->m_start = from; s->m_len = len; s->m_reversed = reverse; //kdDebug(6040) << "m_start: " << s->m_start << " m_len: " << s->m_len << endl; if(m_lines.count() == m_lines.size()) m_lines.resize(m_lines.size()*2+1); m_lines.insert(m_lines.count(), s); //kdDebug(6040) << this << " " << renderName() << "::position inserted" << endl;}unsigned int RenderText::width(unsigned int from, unsigned int len, bool firstLine) const{ if(!str->s || from > str->l ) return 0; if ( from + len > str->l ) len = str->l - from; const Font *f = htmlFont( firstLine ); return width( from, len, f );}unsigned int RenderText::width(unsigned int from, unsigned int len, const Font *f) const{ if(!str->s || from > str->l ) return 0; if ( from + len > str->l ) len = str->l - from; if ( f == &style()->htmlFont() && from == 0 && len == str->l ) return m_maxWidth; int w = f->width(str->s, str->l, from, len ); //kdDebug( 6040 ) << "RenderText::width(" << from << ", " << len << ") = " << w << endl; return w;}short RenderText::width() const{ int w; int minx = 100000000; int maxx = 0; // slooow for(unsigned int si = 0; si < m_lines.count(); si++) { InlineTextBox* s = m_lines[si]; if(s->m_x < minx) minx = s->m_x; if(s->m_x + s->m_width > maxx) maxx = s->m_x + s->m_width; } w = kMax(0, maxx-minx); return w;}void RenderText::repaint(bool immediate){ RenderObject *cb = containingBlock(); if(cb) cb->repaint(immediate);}bool RenderText::isFixedWidthFont() const{ return QFontInfo(style()->font()).fixedPitch();}short RenderText::verticalPositionHint( bool firstLine ) const{ return parent()->verticalPositionHint( firstLine );}const QFontMetrics &RenderText::metrics(bool firstLine) const{ if( firstLine && hasFirstLine() ) { RenderStyle *pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LINE); if ( pseudoStyle ) return pseudoStyle->fontMetrics(); } return style()->fontMetrics();}const Font *RenderText::htmlFont(bool firstLine) const{ const Font *f = 0; if( firstLine && hasFirstLine() ) { RenderStyle *pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LINE); if ( pseudoStyle ) f = &pseudoStyle->htmlFont(); } else { f = &style()->htmlFont(); } return f;}bool RenderText::containsOnlyWhitespace(unsigned int from, unsigned int len) const{ unsigned int currPos; for (currPos = from; currPos < from+len && (str->s[currPos] == '\n' || str->s[currPos].direction() == QChar::DirWS); currPos++); return currPos >= (from+len);}void RenderText::trimmedMinMaxWidth(short& beginMinW, bool& beginWS, short& endMinW, bool& endWS, bool& hasBreakableChar, bool& hasBreak, short& beginMaxW, short& endMaxW, short& minW, short& maxW, bool& stripFrontSpaces){ bool preserveWS = style()->preserveWS(); bool preserveLF = style()->preserveLF(); bool autoWrap = style()->autoWrap(); if (preserveWS) 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].direction() == QChar::DirWS || (!preserveLF && str->s[0] == '\n'))) { const Font *f = htmlFont( false ); QChar space[1]; space[0] = ' '; int spaceWidth = f->width(space, 1, 0); maxW -= spaceWidth; } stripFrontSpaces = !preserveWS && m_hasEndWS; if (!autoWrap) 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) {#ifndef 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; } }}#ifdef ENABLE_DUMPstatic QString quoteAndEscapeNonPrintables(const QString &s){ QString result; result += '"'; for (uint i = 0; i != s.length(); ++i) { QChar c = s.at(i); if (c == '\\') { result += "\\\\"; } else if (c == '"') { result += "\\\""; } else { ushort u = c.unicode(); if (u >= 0x20 && u < 0x7F) { result += c; } else { QString hex; hex.sprintf("\\x{%X}", u); result += hex; } } } result += '"'; return result;}static void writeTextRun(QTextStream &ts, const RenderText &o, const InlineTextBox &run){ ts << "text run at (" << run.m_x << "," << run.m_y << ") width " << run.m_width << ": " << quoteAndEscapeNonPrintables(o.data().string().mid(run.m_start, run.m_len));}void RenderText::dump(QTextStream &stream, const QString &ind) const{ RenderObject::dump( stream, ind ); for (unsigned int i = 0; i < m_lines.count(); i++) { stream << endl << ind << " "; writeTextRun(stream, *this, *m_lines[i]); }}#endifRenderTextFragment::RenderTextFragment(DOM::NodeImpl* _node, DOM::DOMStringImpl* _str, int startOffset, int endOffset):RenderText(_node, _str->substring(startOffset, endOffset)),m_start(startOffset), m_end(endOffset), m_generatedContentStr(0){}RenderTextFragment::RenderTextFragment(DOM::NodeImpl* _node, DOM::DOMStringImpl* _str):RenderText(_node, _str), m_start(0){ m_generatedContentStr = _str; if (_str) { _str->ref(); m_end = _str->l; } else m_end = 0;}RenderTextFragment::~RenderTextFragment(){ if (m_generatedContentStr) m_generatedContentStr->deref();}bool RenderTextFragment::isTextFragment() const{ return true;}DOM::DOMStringImpl* RenderTextFragment::originalString() const{ DOM::DOMStringImpl* result = 0; if (element()) result = element()->string(); else result = contentString(); if (result && (start() > 0 || start() < result->l)) result = result->substring(start(), end()); return result;}#undef BIDI_DEBUG#undef DEBUG_LAYOUT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -