void InlineFlowBox::paintBackground(QPainter* p, const QColor& c, const BackgroundLayer* bgLayer, int my, int mh, int _tx, int _ty, int w, int h) { CachedImage* bg = bgLayer->backgroundImage(); bool hasBackgroundImage = bg && (bg->pixmap_size() == bg->valid_rect().size()) && !bg->isTransparent() && !bg->isErrorImage(); if (!hasBackgroundImage || (!prevLineBox() && !nextLineBox()) || !parent()) object()->paintBackgroundExtended(p, c, bgLayer, my, mh, _tx, _ty, w, h, borderLeft(), borderRight(), paddingLeft(), paddingRight()); else { // We have a background image that spans multiple lines. // We need to adjust _tx and _ty by the width of all previous lines. // Think of background painting on inlines as though you had one long line, a single continuous // strip. Even though that strip has been broken up across multiple lines, you still paint it // as though you had one single line. This means each line has to pick up the background where // the previous line left off. // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right, // but it isn't even clear how this should work at all. int xOffsetOnLine = 0; for (InlineRunBox* curr = prevLineBox(); curr; curr = curr->prevLineBox()) xOffsetOnLine += curr->width(); int startX = _tx - xOffsetOnLine; int totalWidth = xOffsetOnLine; for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox()) totalWidth += curr->width(); p->save(); p->setClipRect(QRect(_tx, _ty, width(), height()), QPainter::CoordPainter); object()->paintBackgroundExtended(p, c, bgLayer, my, mh, startX, _ty, totalWidth, h, borderLeft(), borderRight(), paddingLeft(), paddingRight()); p->restore(); } }
void RenderImage::paint(PaintInfo& paintInfo, int _tx, int _ty) { if (paintInfo.phase == PaintActionOutline && style()->outlineWidth() && style()->visibility() == VISIBLE) paintOutline(paintInfo.p, _tx + m_x, _ty + m_y, width(), height(), style()); if (paintInfo.phase != PaintActionForeground && paintInfo.phase != PaintActionSelection) return; // not visible or not even once layouted? if (style()->visibility() != VISIBLE || m_y <= -500000) return; _tx += m_x; _ty += m_y; if((_ty > paintInfo.r.bottom()) || (_ty + m_height <= paintInfo.r.top())) return; if(shouldPaintBackgroundOrBorder()) paintBoxDecorations(paintInfo, _tx, _ty); if (!canvas()->printImages()) return; int cWidth = contentWidth(); int cHeight = contentHeight(); int leftBorder = borderLeft(); int topBorder = borderTop(); int leftPad = paddingLeft(); int topPad = paddingTop(); // paint frame around image and loading icon as long as it is not completely loaded from web. if (bUnfinishedImageFrame && paintInfo.phase == PaintActionForeground && cWidth > 2 && cHeight > 2 && !complete()) { static QPixmap *loadingIcon; QColor bg = khtml::retrieveBackgroundColor(this); QColor fg = khtml::hasSufficientContrast(Qt::gray, bg) ? Qt::gray : (hasSufficientContrast(Qt::white, bg) ? Qt::white : Qt::black); paintInfo.p->setPen(QPen(fg, 1)); paintInfo.p->setBrush( Qt::NoBrush ); const int offsetX = _tx + leftBorder + leftPad; const int offsetY = _ty + topBorder + topPad; paintInfo.p->drawRect(offsetX, offsetY, cWidth - 1, cHeight - 1); if (!(m_width <= 5 || m_height <= 5)) { if (!loadingIcon) { loadingIcon = new QPixmap(); loadingIcon->loadFromData(loading_icon_data, loading_icon_len); } paintInfo.p->drawPixmap(offsetX + 4, offsetY + 4, *loadingIcon, 0, 0, cWidth - 5, cHeight - 5); } } CachedImage* i = m_cachedImage; //kDebug( 6040 ) << " contents (" << contentWidth << "/" << contentHeight << ") border=" << borderLeft() << " padding=" << paddingLeft(); if ( !i || berrorPic) { if(cWidth > 2 && cHeight > 2) { if ( !berrorPic ) { //qDebug("qDrawShadePanel %d/%d/%d/%d", _tx + leftBorder, _ty + topBorder, cWidth, cHeight); qDrawShadePanel( paintInfo.p, _tx + leftBorder + leftPad, _ty + topBorder + topPad, cWidth, cHeight, QApplication::palette(), true, 1 ); } QPixmap pix = *Cache::brokenPixmap; if(berrorPic && (cWidth >= pix.width()+4) && (cHeight >= pix.height()+4) ) { QRect r(pix.rect()); r = r.intersect(QRect(0, 0, cWidth-4, cHeight-4)); paintInfo.p->drawPixmap( QPoint( _tx + leftBorder + leftPad+2, _ty + topBorder + topPad+2), pix, r ); } if(!alt.isEmpty()) { QString text = alt.string(); paintInfo.p->setFont(style()->font()); paintInfo.p->setPen( style()->color() ); int ax = _tx + leftBorder + leftPad + 2; int ay = _ty + topBorder + topPad + 2; const QFontMetrics &fm = style()->fontMetrics(); //BEGIN HACK #ifdef __GNUC__ #warning "KDE4: hack for testregression, remove when main branch" #endif ax += qMax(-fm.minLeftBearing(), 0); cWidth -= qMax(-fm.minLeftBearing(), 0); //END HACK if (cWidth>5 && cHeight>=fm.height()) paintInfo.p->drawText(ax, ay+1, cWidth - 4, cHeight - 4, Qt::TextWordWrap, text ); } } } else if (i && !i->isTransparent() && i->image()->size().width() && i->image()->size().height()) { paintInfo.p->setPen( Qt::black ); // used for bitmaps //const QPixmap& pix = i->pixmap(); if (!m_imagePainter) m_imagePainter = new ImagePainter(i->image()); // If we have a scaled painter we want to handle the resizing ourselves, so figure out the scaled size, QTransform painterTransform = paintInfo.p->transform(); bool scaled = painterTransform.isScaling() && !painterTransform.isRotating(); QRect scaledRect; // bounding box of the whole thing, transformed, so we also know where the origin goes. if (scaled) { scaledRect = painterTransform.mapRect(QRect(0, 0, contentWidth(), contentHeight())); m_imagePainter->setSize(QSize(scaledRect.width(), scaledRect.height())); } else { m_imagePainter->setSize(QSize(contentWidth(), contentHeight())); } // Now, figure out the rectangle to paint (in painter coordinates), by interesting us with the painting clip rectangle. int x = _tx + leftBorder + leftPad; int y = _ty + topBorder + topPad; QRect imageGeom = QRect(0, 0, contentWidth(), contentHeight()); QRect clipPortion = paintInfo.r.translated(-x, -y); imageGeom &= clipPortion; QPoint destPos = QPoint(x + imageGeom.x(), y + imageGeom.y()); // If we're scaling, reset the painters transform, and apply it ourselves; though // being careful not apply the translation to the source rect. if (scaled) { paintInfo.p->resetTransform(); destPos = painterTransform.map(destPos); imageGeom = painterTransform.mapRect(imageGeom).translated(-scaledRect.topLeft()); } m_imagePainter->paint(destPos.x(), destPos.y(), paintInfo.p, imageGeom.x(), imageGeom.y(), imageGeom.width(), imageGeom.height()); if (scaled) paintInfo.p->setTransform(painterTransform); } if (m_selectionState != SelectionNone) { // kDebug(6040) << "_tx " << _tx << " _ty " << _ty << " _x " << _x << " _y " << _y; // Draw in any case if inside selection. For selection borders, the // offset will decide whether to draw selection or not bool draw = true; if (m_selectionState != SelectionInside) { int startPos, endPos; selectionStartEnd(startPos, endPos); if(selectionState() == SelectionStart) endPos = 1; else if(selectionState() == SelectionEnd) startPos = 0; draw = endPos - startPos > 0; } if (draw) { // setting the brush origin is important for compatibility, // don't touch it unless you know what you're doing paintInfo.p->setBrushOrigin(_tx, _ty - paintInfo.r.y()); paintInfo.p->fillRect(_tx, _ty, width(), height(), QBrush(style()->palette().color( QPalette::Active, QPalette::Highlight ), Qt::Dense4Pattern)); } } }