📄 render_list.cpp
字号:
// -----------------------------------------------------------RenderListMarker::RenderListMarker(DocumentImpl* document) : RenderBox(document), m_listImage(0), m_value(-1){ // init RenderObject attributes setInline(true); // our object is Inline setReplaced(true); // pretend to be replaced // val = -1; // m_listImage = 0;}RenderListMarker::~RenderListMarker(){ if(m_listImage) m_listImage->deref(this);}void RenderListMarker::setStyle(RenderStyle *s){ if ( s && style() && s->listStylePosition() != style()->listStylePosition() ) setNeedsLayoutAndMinMaxRecalc(); RenderBox::setStyle(s); if ( m_listImage != style()->listStyleImage() ) { if(m_listImage) m_listImage->deref(this); m_listImage = style()->listStyleImage(); if(m_listImage) m_listImage->ref(this); }}void RenderListMarker::paint(PaintInfo& i, int _tx, int _ty){ if (i.phase != PaintActionForeground) return; if (style()->visibility() != VISIBLE) return; _tx += m_x; _ty += m_y; if ((_ty > i.r.y() + i.r.height()) || (_ty + m_height < i.r.y())) return; if (shouldPaintBackgroundOrBorder()) paintBoxDecorations(i, _tx, _ty);#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << nodeName().string() << "(ListMarker)::paintObject(" << _tx << ", " << _ty << ")" << endl;#endif QPainter* p = i.p; p->setFont(style()->font()); const QFontMetrics fm = p->fontMetrics(); int offset = fm.ascent()*2/3; // The marker needs to adjust its tx, for the case where it's an outside marker. RenderObject* listItem = 0; int leftLineOffset = 0; int rightLineOffset = 0; if (!isInside()) { listItem = this; int yOffset = 0; int xOffset = 0; while (listItem && listItem != m_listItem) { yOffset += listItem->yPos(); xOffset += listItem->xPos(); listItem = listItem->parent(); } // Now that we have our xoffset within the listbox, we need to adjust ourselves by the delta // between our current xoffset and our desired position (which is just outside the border box // of the list item). if (style()->direction() == LTR) { leftLineOffset = m_listItem->leftRelOffset(yOffset, m_listItem->leftOffset(yOffset)); _tx -= (xOffset - leftLineOffset) + m_listItem->paddingLeft() + m_listItem->borderLeft(); } else { rightLineOffset = m_listItem->rightRelOffset(yOffset, m_listItem->rightOffset(yOffset)); _tx += (rightLineOffset-xOffset) + m_listItem->paddingRight() + m_listItem->borderRight(); } } bool isPrinting = (p->device()->devType() == QInternal::Printer); if (isPrinting) { if (_ty < i.r.y()) { // This has been printed already we suppose. return; } if (_ty + m_height + paddingBottom() + borderBottom() >= i.r.y() + i.r.height()) { RenderCanvas *rootObj = canvas(); if (_ty < rootObj->truncatedAt())#if APPLE_CHANGES && !KWIQ // besttruncated not in atm rootObj->setBestTruncatedAt(_ty, this);#else rootObj->setTruncatedAt(_ty);#endif // Let's print this on the next page. return; } } int xoff = 0; int yoff = fm.ascent() - offset; if (!isInside()) if (listItem->style()->direction() == LTR) xoff = -7 - offset; else xoff = offset; if ( m_listImage && !m_listImage->isErrorImage()) { // For OUTSIDE bullets shrink back to only a 0.3em margin. 0.67 em is too // much. This brings the margin back to MacIE/Gecko/WinIE levels. // For LTR don't forget to add in the width of the image to the offset as // well (you are moving the image left, so you have to also add in the width // of the image's border box as well). -dwh if (!isInside()) { if (style()->direction() == LTR) xoff -= m_listImage->pixmap().width() - fm.ascent()*1/3; else xoff -= fm.ascent()*1/3; } p->drawPixmap( QPoint( _tx + xoff, _ty ), m_listImage->pixmap()); return; }#ifdef BOX_DEBUG p->setPen( Qt::red ); p->drawRect( _tx + xoff, _ty + yoff, offset, offset );#endif const QColor color( style()->color() ); p->setPen( color ); switch(style()->listStyleType()) { case DISC: p->setBrush( color ); p->drawEllipse( _tx + xoff, _ty + (3 * yoff)/2, (offset>>1)+1, (offset>>1)+1 ); return; case CIRCLE: p->setBrush( Qt::NoBrush ); p->drawEllipse( _tx + xoff, _ty + (3 * yoff)/2, (offset>>1)+1, (offset>>1)+1 ); return; case SQUARE: p->setBrush( color ); p->drawRect( _tx + xoff, _ty + (3 * yoff)/2, (offset>>1)+1, (offset>>1)+1 ); return; case LNONE: return; default: if (!m_item.isEmpty()) {#if APPLE_CHANGES // Text should be drawn on the baseline, so we add in the ascent of the font. // For some inexplicable reason, this works in Konqueror. I'm not sure why. // - dwh _ty += fm.ascent();#else //_ty += fm.ascent() - fm.height()/2 + 1;#endif if (isInside()) { if( style()->direction() == LTR) p->drawText(_tx, _ty, 0, 0, Qt::AlignLeft|Qt::DontClip, m_item); else p->drawText(_tx, _ty, 0, 0, Qt::AlignRight|Qt::DontClip, m_item); } else { if(style()->direction() == LTR) p->drawText(_tx-offset/2, _ty, 0, 0, Qt::AlignRight|Qt::DontClip, m_item); else p->drawText(_tx+offset/2, _ty, 0, 0, Qt::AlignLeft|Qt::DontClip, m_item); } } }}void RenderListMarker::layout(){ KHTMLAssert( needsLayout() ); // ### KHTMLAssert( minMaxKnown() ); if ( !minMaxKnown() ) calcMinMaxWidth(); setNeedsLayout(false);}void RenderListMarker::setPixmap( const QPixmap &p, const QRect& r, CachedImage *o){ if(o != m_listImage) { RenderBox::setPixmap(p, r, o); return; } if (m_width != m_listImage->pixmap_size().width() || m_height != m_listImage->pixmap_size().height()) setNeedsLayoutAndMinMaxRecalc(); else repaint();}void RenderListMarker::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() ); m_width = 0; if(m_listImage) { if (isInside()) m_width = m_listImage->pixmap().width() + 5; m_height = m_listImage->pixmap().height(); m_minWidth = m_maxWidth = m_width; setMinMaxKnown(); return; } if (m_value < 0) // not yet calculated m_listItem->calcListValue(); const QFontMetrics &fm = style()->fontMetrics(); m_height = fm.ascent(); switch(style()->listStyleType()) { case DISC: case CIRCLE: case SQUARE: if (isInside()) { m_width = m_height; //fm.ascent(); } goto end; case ARMENIAN: case GEORGIAN: case CJK_IDEOGRAPHIC: case HIRAGANA: case KATAKANA: case HIRAGANA_IROHA: case KATAKANA_IROHA: case DECIMAL_LEADING_ZERO: // ### unsupported, we use decimal instead case LDECIMAL: m_item.sprintf( "%ld", m_value ); break; case LOWER_ROMAN: m_item = toRoman( m_value, false ); break; case UPPER_ROMAN: m_item = toRoman( m_value, true ); break; case LOWER_GREEK: { int number = m_value - 1; int l = (number % 24); if (l>16) {l++;} // Skip GREEK SMALL LETTER FINAL SIGMA m_item = QChar(945 + l); for (int i = 0; i < (number / 24); i++) { m_item += QString::fromLatin1("'"); } break; } case HEBREW: m_item = toHebrew( m_value ); break; case LOWER_ALPHA: case LOWER_LATIN: m_item = toLetter( m_value, 'a' ); break; case UPPER_ALPHA: case UPPER_LATIN: m_item = toLetter( m_value, 'A' ); break; case LNONE: break; } m_item += QString::fromLatin1(". "); if (isInside()) m_width = fm.width(m_item);end: m_minWidth = m_width; m_maxWidth = m_width; setMinMaxKnown();}void RenderListMarker::calcWidth(){ RenderBox::calcWidth();}short RenderListMarker::lineHeight(bool, bool) const{ return height();}short RenderListMarker::baselinePosition(bool, bool) const{ return height();}bool RenderListMarker::isInside() const{ return m_listItem->notInList() || style()->listStylePosition() == INSIDE;}#undef BOX_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -