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

📄 render_text.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if (ax > _x) end = offset;    else if (ax < _x) start = offset;    else break;  }  return m_start + offset;}int InlineTextBox::widthFromStart(int pos) const{  // gasp! sometimes pos is i < 0 which crashes Font::width  pos = kMax(pos, 0);  const RenderText *t = renderText();  Q_ASSERT(t->isText());  const Font *f = t->htmlFont(m_firstLine);  const QFontMetrics &fm = t->fontMetrics(m_firstLine);  int numSpaces = 0;  // consider spacing for justified text  bool justified = t->style()->textAlign() == JUSTIFY;  //kdDebug(6000) << "InlineTextBox::width(int)" << endl;  if (justified && m_toAdd > 0) do {    //kdDebug(6000) << "justify" << endl;//    QConstString cstr = QConstString(t->str->s + m_start, m_len);    for( int i = 0; i < m_len; i++ )      if ( t->str->s[m_start+i].category() == QChar::Separator_Space )	numSpaces++;    if (numSpaces == 0) break;    int toAdd = m_toAdd;    int w = 0;		// accumulated width    int start = 0;	// start of non-space sequence    int current = 0;	// current position    while (current < pos) {      // add spacing      while (current < pos && t->str->s[m_start + current].category() == QChar::Separator_Space) {	w += f->getWordSpacing();	w += f->getLetterSpacing();	w += justifyWidth(numSpaces, toAdd);        w += fm.width(' ');	// ### valid assumption? (LS)        current++; start++;      }/*wend*/      if (current >= pos) break;      // seek next space      while (current < pos && t->str->s[m_start + current].category() != QChar::Separator_Space)        current++;      // check run without spaces      if ( current > start ) {          w += f->width(t->str->s + m_start, m_len, start, current - start);          start = current;      }    }    return w;  } while(false);/*end if*/  //kdDebug(6000) << "default" << endl;  // else use existing width function  return f->width(t->str->s + m_start, m_len, 0, pos);}long InlineTextBox::minOffset() const{  return m_start;}long InlineTextBox::maxOffset() const{  return m_start + m_len;}// -----------------------------------------------------------------------------InlineTextBoxArray::InlineTextBoxArray(){    setAutoDelete(false);}int InlineTextBoxArray::compareItems( Item d1, Item d2 ){    assert(d1);    assert(d2);    return static_cast<InlineTextBox*>(d1)->m_y - static_cast<InlineTextBox*>(d2)->m_y;}// remove this once QVector::bsearch is fixedint InlineTextBoxArray::findFirstMatching(Item d) const{    int len = count();    if ( !len )	return -1;    if ( !d )	return -1;    int n1 = 0;    int n2 = len - 1;    int mid = 0;    bool found = false;    while ( n1 <= n2 ) {	int  res;	mid = (n1 + n2)/2;	if ( (*this)[mid] == 0 )			// null item greater	    res = -1;	else	    res = ((QGVector*)this)->compareItems( d, (*this)[mid] );	if ( res < 0 )	    n2 = mid - 1;	else if ( res > 0 )	    n1 = mid + 1;	else {					// found it	    found = true;	    break;	}    }    /* if ( !found )	return -1; */    // search to first one equal or bigger    while ( found && (mid > 0) && !((QGVector*)this)->compareItems(d, (*this)[mid-1]) )	mid--;    return mid;}// -------------------------------------------------------------------------------------RenderText::RenderText(DOM::NodeImpl* node, DOMStringImpl *_str)    : RenderObject(node){    // init RenderObject attributes    setRenderText();   // our object inherits from RenderText    m_minWidth = -1;    m_maxWidth = -1;    str = _str;    if(str) str->ref();    KHTMLAssert(!str || !str->l || str->s);    m_selectionState = SelectionNone;    m_hasReturn = true;#ifdef DEBUG_LAYOUT    QConstString cstr(str->s, str->l);    kdDebug( 6040 ) << "RenderText ctr( "<< cstr.string().length() << " )  '" << cstr.string() << "'" << endl;#endif}void RenderText::setStyle(RenderStyle *_style){    if ( style() != _style ) {        bool changedText = ((!style() && ( _style->textTransform() != TTNONE ||                                           !_style->preserveLF() || !_style->preserveWS() )) ||                            (style() && (style()->textTransform() != _style->textTransform() ||                                         style()->whiteSpace() != _style->whiteSpace())));        RenderObject::setStyle( _style );        m_lineHeight = RenderObject::lineHeight(false);        if (changedText) {            DOM::DOMStringImpl* textToTransform = originalString();            if (textToTransform)                setText(textToTransform, true);        }    }}RenderText::~RenderText(){    KHTMLAssert(m_lines.count() == 0);    if(str) str->deref();}void RenderText::deleteInlineBoxes(RenderArena* arena){    // this is a slight variant of QArray::clear().    // We don't delete the array itself here because its    // likely to be used in the same size later again, saves    // us resize() calls    unsigned int len = m_lines.size();    if (len) {        if (!arena)            arena = renderArena();        for(unsigned int i=0; i < len; i++) {            InlineTextBox* s = m_lines.at(i);            if (s)                s->detach(arena);            m_lines.remove(i);        }    }    KHTMLAssert(m_lines.count() == 0);}bool RenderText::isTextFragment() const{    return false;}DOM::DOMStringImpl* RenderText::originalString() const{    return element() ? element()->string() : 0;}InlineTextBox * RenderText::findInlineTextBox( int offset, int &pos, bool checkFirstLetter ){    // The text boxes point to parts of the rendertext's str string    // (they don't include '\n')    // Find the text box that includes the character at @p offset    // and return pos, which is the position of the char in the run.    // FIXME: make this use binary search? Dirk says it won't work :-( (LS)#if 0    if (checkFirstLetter && forcedMinOffset()) {//        kdDebug(6040) << "checkFirstLetter: forcedMinOffset: " << forcedMinOffset() << endl;        RenderFlow *firstLetter = static_cast<RenderFlow *>(previousSibling());        if (firstLetter && firstLetter->isFlow() && firstLetter->isFirstLetter()) {            RenderText *letterText = static_cast<RenderText *>(firstLetter->firstChild());            //kdDebug(6040) << "lettertext: " << letterText << " minOfs: " << letterText->minOffset() << " maxOfs: " << letterText->maxOffset() << endl;	    if (offset >= letterText->minOffset() && offset <= letterText->maxOffset()) {	        InlineTextBox *result = letterText->findInlineTextBox(offset, pos, false);            //kdDebug(6040) << "result: " << result << endl;		if (result) return result;	    }        }    }#endif    if ( m_lines.isEmpty() )        return 0L;    // The text boxes don't resemble a contiguous coverage of the text, there    // may be holes. Therefore, we snap to the nearest previous text box if    // the given offset happens to point to such a hole.    InlineTextBox* s = m_lines[0];    uint count = m_lines.count();    uint si = 0;    uint nearest_idx = 0;		// index of nearest text box    int nearest = INT_MAX;		// nearest distance//kdDebug(6040) << "s[" << si << "] m_start " << s->m_start << " m_end " << (s->m_start + s->m_len) << endl;    while(!(offset >= s->m_start && offset <= s->m_start + s->m_len)    		&& ++si < count)    {        int dist = offset - (s->m_start + s->m_len);//kdDebug(6040) << "dist " << dist << " nearest " << nearest << endl;	if (dist >= 0 && dist <= nearest) {	    nearest = dist;	    nearest_idx = si - 1;	}/*end if*/        s = m_lines[si];//kdDebug(6040) << "s[" << si << "] m_start " << s->m_start << " m_end " << (s->m_start + s->m_len) << endl;    }//kdDebug(6040) << "nearest_idx " << nearest_idx << " count " << count << endl;    if (si >= count) s = m_lines[nearest_idx];    // we are now in the correct text box    pos = kMin(offset - s->m_start, int( s->m_len ));    //kdDebug(6040) << "offset=" << offset << " s->m_start=" << s->m_start << endl;    return s;}bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction /*hitTestAction*/, bool inBox){    assert(parent());    bool inside = false;    if (style()->visibility() != HIDDEN) {        InlineTextBox *s = m_lines.count() ? m_lines[0] : 0;        int si = 0;        while(s) {            if((_y >=_ty + s->m_y) && (_y < _ty + s->m_y + s->m_height) &&               (_x >= _tx + s->m_x) && (_x <_tx + s->m_x + s->m_width) ) {                inside = true;                break;            }            s = si < (int) m_lines.count()-1 ? m_lines[++si] : 0;        }    }    // #### ported over from Safari. Can this happen at all? (lars)    if (inside && element()) {        if (info.innerNode() && info.innerNode()->renderer() &&            !info.innerNode()->renderer()->isInline()) {            // Within the same layer, inlines are ALWAYS fully above blocks.  Change inner node.            info.setInnerNode(element());            // Clear everything else.            info.setInnerNonSharedNode(0);            info.setURLElement(0);        }        if (!info.innerNode())            info.setInnerNode(element());        if(!info.innerNonSharedNode())            info.setInnerNonSharedNode(element());    }    return inside;}FindSelectionResult RenderText::checkSelectionPoint(int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int &offset, SelPointState &){//        kdDebug(6040) << "RenderText::checkSelectionPoint " << this << " _x=" << _x << " _y=" << _y//                     << " _tx=" << _tx << " _ty=" << _ty << endl;//kdDebug(6040) << renderName() << "::checkSelectionPoint x=" << xPos() << " y=" << yPos() << " w=" << width() << " h=" << height() << " m_lines.count=" << m_lines.count() << endl;    NodeImpl *lastNode = 0;    int lastOffset = 0;    FindSelectionResult lastResult = SelectionPointAfter;    for(unsigned int si = 0; si < m_lines.count(); si++)    {        InlineTextBox* s = m_lines[si];        FindSelectionResult result;        const Font *f = htmlFont( si==0 );        result = s->checkSelectionPoint(_x, _y, _tx, _ty, f, this, offset, m_lineHeight);//         kdDebug(6040) << "RenderText::checkSelectionPoint " << this << " line " << si << " result=" << result << " offset=" << offset << endl;        if ( result == SelectionPointInside ) // x,y is inside the textrun        {            offset += s->m_start; // add the offset from the previous lines//             kdDebug(6040) << "RenderText::checkSelectionPoint inside -> " << offset << endl;            node = element();            return SelectionPointInside;        } else if ( result == SelectionPointBefore ) {	    if (!lastNode) {                // x,y is before the textrun -> stop here               offset = 0;//                kdDebug(6040) << "RenderText::checkSelectionPoint " << this << "before us -> returning Before" << endl;               node = element();               return SelectionPointBefore;	    }        } else if ( result == SelectionPointBeforeInLine ) {	    offset = s->m_start;	    node = element();	    return SelectionPointInside;        } else if ( result == SelectionPointAfterInLine ) {	    lastOffset = s->m_start + s->m_len;	    lastNode = element();	    lastResult = result;	    // no return here	}    }    if (lastNode) {        offset = lastOffset;	node = lastNode;//         kdDebug(6040) << "RenderText::checkSelectionPoint: lastNode " << lastNode << " lastOffset " << lastOffset << endl;	return lastResult;    }    // set offset to max    offset = str->l;    //qDebug("setting node to %p", element());    node = element();//     kdDebug(6040) << "RenderText::checkSelectionPoint: node " << node << " offset " << offset << endl;    return SelectionPointAfter;}void RenderText::caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height){  if (!m_lines.count()) {    _x = _y = height = -1;    width = 1;    return;  }  int pos;  InlineTextBox * s = findInlineTextBox( offset, pos, true );  RenderText *t = s->renderText();

⌨️ 快捷键说明

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