bool RenderImage::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inside) { inside |= RenderReplaced::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inside); if (inside && element()) { int tx = _tx + m_x; int ty = _ty + m_y; HTMLImageElementImpl* i = element()->id() == ID_IMG ? static_cast<HTMLImageElementImpl*>(element()) : 0; HTMLMapElementImpl* map; if (i && i->document()->isHTMLDocument() && (map = static_cast<HTMLDocumentImpl*>(i->document())->getMap(i->imageMap()))) { // we're a client side image map inside = map->mapMouseEvent(_x - tx, _y - ty, contentWidth(), contentHeight(), info); info.setInnerNonSharedNode(element()); } } return inside; }
HTMLMapElementImpl* RenderImage::imageMap() { HTMLImageElementImpl* i = element()->id() == ID_IMG ? static_cast<HTMLImageElementImpl*>(element()) : 0; return i ? i->getDocument()->getImageMap(i->imageMap()) : 0; }
void RenderImage::paint(PaintInfo& i, int _tx, int _ty) { if (!shouldPaint(i, _tx, _ty)) return; _tx += m_x; _ty += m_y; if (shouldPaintBackgroundOrBorder() && i.phase != PaintActionOutline) paintBoxDecorations(i, _tx, _ty); QPainter* p = i.p; if (i.phase == PaintActionOutline && style()->outlineWidth() && style()->visibility() == VISIBLE) paintOutline(p, _tx, _ty, width(), height(), style()); if (i.phase != PaintActionForeground && i.phase != PaintActionSelection) return; if (!shouldPaintWithinRoot(i)) return; #if APPLE_CHANGES bool drawSelectionTint = selectionState() != SelectionNone; if (i.phase == PaintActionSelection) { if (selectionState() == SelectionNone) { return; } drawSelectionTint = false; } #endif int cWidth = contentWidth(); int cHeight = contentHeight(); int leftBorder = borderLeft(); int topBorder = borderTop(); int leftPad = paddingLeft(); int topPad = paddingTop(); if (khtml::printpainter && !canvas()->printImages()) return; //kdDebug( 6040 ) << " contents (" << contentWidth << "/" << contentHeight << ") border=" << borderLeft() << " padding=" << paddingLeft() << endl; if ( pix.isNull() || berrorPic) { if (i.phase == PaintActionSelection) return; if(cWidth > 2 && cHeight > 2) { #if APPLE_CHANGES if ( !berrorPic ) { p->setPen (Qt::lightGray); p->setBrush (Qt::NoBrush); p->drawRect (_tx + leftBorder + leftPad, _ty + topBorder + topPad, cWidth, cHeight); } bool errorPictureDrawn = false; int imageX = 0, imageY = 0; int usableWidth = cWidth - leftBorder - borderRight() - leftPad - paddingRight(); int usableHeight = cHeight - topBorder - borderBottom() - topPad - paddingBottom(); if(berrorPic && !pix.isNull() && (usableWidth >= pix.width()) && (usableHeight >= pix.height()) ) { // Center the error image, accounting for border and padding. int centerX = (usableWidth - pix.width())/2; if (centerX < 0) centerX = 0; int centerY = (usableHeight - pix.height())/2; if (centerY < 0) centerY = 0; imageX = leftBorder + leftPad + centerX; imageY = topBorder + topPad + centerY; p->drawPixmap( QPoint(_tx + imageX, _ty + imageY), pix, pix.rect() ); errorPictureDrawn = true; } if(!alt.isEmpty()) { QString text = alt.string(); text.replace('\\', backslashAsCurrencySymbol()); p->setFont (style()->font()); p->setPen (style()->color()); int ax = _tx + leftBorder + leftPad; int ay = _ty + topBorder + topPad; const QFontMetrics &fm = style()->fontMetrics(); int ascent = fm.ascent(); // Only draw the alt text if it'll fit within the content box, // and only if it fits above the error image. int textWidth = fm.width (text, text.length()); if (errorPictureDrawn){ if (usableWidth > textWidth && fm.height() <= imageY) p->drawText(ax, ay+ascent, 0 /* ignored */, 0 /* ignored */, Qt::WordBreak /* not supported */, text ); } else if (usableWidth >= textWidth && cHeight>=fm.height()) p->drawText(ax, ay+ascent, 0 /* ignored */, 0 /* ignored */, Qt::WordBreak /* not supported */, text ); } #else /* not APPLE_CHANGES */ if ( !berrorPic ) { //qDebug("qDrawShadePanel %d/%d/%d/%d", _tx + leftBorder, _ty + topBorder, cWidth, cHeight); qDrawShadePanel( p, _tx + leftBorder + leftPad, _ty + topBorder + topPad, cWidth, cHeight, KApplication::palette().inactive(), true, 1 ); } if(berrorPic && !pix.isNull() && (cWidth >= pix.width()+4) && (cHeight >= pix.height()+4) ) { QRect r(pix.rect()); r = r.intersect(QRect(0, 0, cWidth-4, cHeight-4)); p->drawPixmap( QPoint( _tx + leftBorder + leftPad+2, _ty + topBorder + topPad+2), pix, r ); } if(!alt.isEmpty()) { QString text = alt.string(); text.replace('\\', backslashAsCurrencySymbol()); p->setFont(style()->font()); p->setPen( style()->color() ); int ax = _tx + leftBorder + leftPad + 2; int ay = _ty + topBorder + topPad + 2; const QFontMetrics &fm = style()->fontMetrics(); if (cWidth>5 && cHeight>=fm.height()) p->drawText(ax, ay+1, cWidth - 4, cHeight - 4, Qt::WordBreak, text ); } #endif /* APPLE_CHANGES not defined */ } } else if (image && !image->isTransparent()) { #if APPLE_CHANGES // Do the calculations to draw selections as tall as the line. // Ignore the passed-in value for _ty. // Use the bottom of the line above as the y position (if there is one, // otherwise use the top of this renderer's line) and the height of the line as the height. // This mimics Cocoa. int selectionTop = -1; int selectionHeight = -1; int selectionLeft = -1; int selectionRight = -1; bool extendSelectionToLeft = false; bool extendSelectionToRight = false; if (drawSelectionTint) { InlineBox *box = inlineBox(); if (box) { // Get a value for selectionTop that is relative to the containing block. // This value is used for determining left and right offset for the selection, if necessary, // and for calculating the selection height. if (box->root()->prevRootBox()) selectionTop = box->root()->prevRootBox()->bottomOverflow(); else selectionTop = box->root()->topOverflow(); selectionHeight = box->root()->bottomOverflow() - selectionTop; int absx, absy; containingBlock()->absolutePosition(absx, absy); if (selectionState() == SelectionInside && box->root()->firstLeafChild() == box) { extendSelectionToLeft = true; selectionLeft = absx + containingBlock()->leftOffset(selectionTop); } if (selectionState() == SelectionInside && box->root()->lastLeafChild() == box) { extendSelectionToRight = true; selectionRight = absx + containingBlock()->rightOffset(selectionTop); } // Now make the selectionTop an absolute coordinate. selectionTop += absy; } } #endif if ( (cWidth != intrinsicWidth() || cHeight != intrinsicHeight()) && pix.width() > 0 && pix.height() > 0 && image->valid_rect().isValid()) { #if APPLE_CHANGES QSize tintSize; #endif if (resizeCache.isNull() && cWidth && cHeight) { QRect scaledrect(image->valid_rect()); // kdDebug(6040) << "time elapsed: " << dt->elapsed() << endl; // kdDebug( 6040 ) << "have to scale: " << endl; // qDebug("cw=%d ch=%d pw=%d ph=%d rcw=%d, rch=%d", // cWidth, cHeight, intrinsicWidth(), intrinsicHeight(), resizeCache.width(), resizeCache.height()); QWMatrix matrix; matrix.scale( (float)(cWidth)/intrinsicWidth(), (float)(cHeight)/intrinsicHeight() ); resizeCache = pix.xForm( matrix ); scaledrect.setWidth( ( cWidth*scaledrect.width() ) / intrinsicWidth() ); scaledrect.setHeight( ( cHeight*scaledrect.height() ) / intrinsicHeight() ); // qDebug("resizeCache size: %d/%d", resizeCache.width(), resizeCache.height()); // qDebug("valid: %d/%d, scaled: %d/%d", // image->valid_rect().width(), image->valid_rect().height(), // scaledrect.width(), scaledrect.height()); // sometimes scaledrect.width/height are off by one because // of rounding errors. if the image is fully loaded, we // make sure that we don't do unnecessary resizes during painting QSize s(scaledrect.size()); if(QSize::equals(image->valid_rect().size(),QSize( intrinsicWidth(), intrinsicHeight() ))) // fully loaded s = QSize(cWidth, cHeight); if(QABS(s.width() - cWidth) < 2) // rounding errors s.setWidth(cWidth); if(resizeCache.size() != s) resizeCache.resize(s); p->drawPixmap( QPoint( _tx + leftBorder + leftPad, _ty + topBorder + topPad), resizeCache, scaledrect ); #if APPLE_CHANGES tintSize = s; #endif } else { p->drawPixmap( QPoint( _tx + leftBorder + leftPad, _ty + topBorder + topPad), resizeCache ); #if APPLE_CHANGES tintSize = resizeCache.rect().size(); #endif } #if APPLE_CHANGES if (drawSelectionTint) { int left = _tx + leftBorder + leftPad; int width = tintSize.width(); int top = selectionTop >= 0 ? selectionTop : _ty + topBorder + topPad; int height = selectionHeight >= 0 ? selectionHeight : tintSize.height(); QBrush brush(selectionTintColor(p)); p->fillRect(left, top, width, height, brush); if (extendSelectionToLeft) p->fillRect(selectionLeft, selectionTop, left - selectionLeft, selectionHeight, brush); if (extendSelectionToRight) p->fillRect(left + width, selectionTop, selectionRight - (left + width), selectionHeight, brush); } #endif } else { // we might be just about switching images // so pix contains the old one (we want to paint), but image->valid_rect is still invalid // so use intrinsic Size instead. // ### maybe no progressive loading for the second image ? QRect rect(image->valid_rect().isValid() ? image->valid_rect() : QRect(0, 0, intrinsicWidth(), intrinsicHeight())); QPoint offs( _tx + leftBorder + leftPad, _ty + topBorder + topPad); // qDebug("normal paint rect %d/%d/%d/%d", rect.x(), rect.y(), rect.width(), rect.height()); // rect = rect & QRect( 0 , y - offs.y() - 10, w, 10 + y + h - offs.y()); // qDebug("normal paint rect after %d/%d/%d/%d", rect.x(), rect.y(), rect.width(), rect.height()); // qDebug("normal paint: offs.y(): %d, y: %d, diff: %d", offs.y(), y, y - offs.y()); // qDebug(""); // p->setClipRect(QRect(x,y,w,h)); // p->drawPixmap( offs.x(), y, pix, rect.x(), rect.y(), rect.width(), rect.height() ); #if APPLE_CHANGES && !KWIQ HTMLImageElementImpl* i = (element() && element()->id() == ID_IMG) ? static_cast<HTMLImageElementImpl*>(element()) : 0; if (i && !i->compositeOperator().isNull()){ p->drawPixmap (offs, pix, rect, i->compositeOperator()); } else { #endif p->drawPixmap(offs, pix, rect); #if APPLE_CHANGES && !KWIQ } #endif #if APPLE_CHANGES if (drawSelectionTint) { p->fillRect(offs.x() + rect.x(), offs.y() + rect.y(), rect.width(), rect.height(), QBrush(selectionTintColor(p))); int left = offs.x() + rect.x(); int width = rect.width(); int top = selectionTop >= 0 ? selectionTop : offs.y() + rect.y(); int height = selectionHeight >= 0 ? selectionHeight : rect.height(); QBrush brush(selectionTintColor(p)); p->fillRect(left, top, width, height, brush); if (extendSelectionToLeft) p->fillRect(selectionLeft, selectionTop, left - selectionLeft, selectionHeight, brush); if (extendSelectionToRight) p->fillRect(left + width, selectionTop, selectionRight - (left + width), selectionHeight, brush); } #endif } } }
void HTMLAnchorElementImpl::defaultEventHandler(EventImpl *evt) { bool keydown = evt->id() == EventImpl::KHTML_KEYPRESS_EVENT || evt->id() == EventImpl::KHTML_KEYDOWN_EVENT; // React on clicks and on keypresses. // Don't make this KEYUP_EVENT again, it makes khtml follow links // it shouldn't, when pressing Enter in the combo. if ( ( (evt->id() == EventImpl::CLICK_EVENT && static_cast<MouseEventImpl*>(evt)->detail() == 1) || ( keydown && m_focused)) && m_hasAnchor) { MouseEventImpl *e = 0; if ( evt->id() == EventImpl::CLICK_EVENT ) e = static_cast<MouseEventImpl*>( evt ); TextEventImpl *k = 0; if (keydown) k = static_cast<TextEventImpl *>( evt ); QString utarget; QString url; if ( e && e->button() == 2 ) { HTMLElementImpl::defaultEventHandler(evt); return; } if ( k ) { if (k->virtKeyVal() != TextEventImpl::DOM_VK_ENTER) { if (k->qKeyEvent) k->qKeyEvent->ignore(); HTMLElementImpl::defaultEventHandler(evt); return; } if (k->qKeyEvent) k->qKeyEvent->accept(); } url = khtml::parseURL(getAttribute(ATTR_HREF)).string(); utarget = getAttribute(ATTR_TARGET).string(); if ( e && e->button() == 1 ) utarget = "_blank"; if ( evt->target()->id() == ID_IMG ) { HTMLImageElementImpl* img = static_cast<HTMLImageElementImpl*>( evt->target() ); if ( img && img->isServerMap() ) { khtml::RenderImage *r = static_cast<khtml::RenderImage *>(img->renderer()); if(r && e) { int absx, absy; r->absolutePosition(absx, absy); int x(e->clientX() - absx), y(e->clientY() - absy); url += QString("?%1,%2").arg( x ).arg( y ); } else { evt->setDefaultHandled(); HTMLElementImpl::defaultEventHandler(evt); return; } } } if ( !evt->defaultPrevented() ) { int state = 0; int button = 0; if ( e ) { if ( e->ctrlKey() ) state |= Qt::ControlButton; if ( e->shiftKey() ) state |= Qt::ShiftButton; if ( e->altKey() ) state |= Qt::AltButton; if ( e->metaKey() ) state |= Qt::MetaButton; if ( e->button() == 0 ) button = Qt::LeftButton; else if ( e->button() == 1 ) button = Qt::MidButton; else if ( e->button() == 2 ) button = Qt::RightButton; } else if ( k ) { if ( k->checkModifier(Qt::ShiftButton) ) state |= Qt::ShiftButton; if ( k->checkModifier(Qt::AltButton) ) state |= Qt::AltButton; if ( k->checkModifier(Qt::ControlButton) ) state |= Qt::ControlButton; } getDocument()->view()->part()-> urlSelected( url, button, state, utarget ); } evt->setDefaultHandled(); } HTMLElementImpl::defaultEventHandler(evt); }
void HTMLAnchorElementImpl::defaultEventHandler(EventImpl *evt) { bool keydown = evt->id() == EventImpl::KEYDOWN_EVENT && evt->isKeyRelatedEvent(); // React on clicks and on keypresses. // Don't make this KEYUP_EVENT again, it makes khtml follow links // it shouldn't, when pressing Enter in the combo. if ( ( (evt->id() == EventImpl::CLICK_EVENT && !static_cast<MouseEventImpl*>(evt)->isDoubleClick()) || ( keydown && m_focused)) && m_hasAnchor) { MouseEventImpl *e = 0; if ( evt->id() == EventImpl::CLICK_EVENT ) e = static_cast<MouseEventImpl*>( evt ); KeyEventBaseImpl *k = 0; if (keydown) k = static_cast<KeyEventBaseImpl *>( evt ); QString utarget; QString url; if ( e && e->button() == 2 ) { HTMLElementImpl::defaultEventHandler(evt); return; } if ( k ) { if (k->virtKeyVal() != KeyEventBaseImpl::DOM_VK_ENTER) { if (k->qKeyEvent()) k->qKeyEvent()->ignore(); HTMLElementImpl::defaultEventHandler(evt); return; } if (k->qKeyEvent()) k->qKeyEvent()->accept(); } url = khtml::parseURL(getAttribute(ATTR_HREF)).string(); utarget = getAttribute(ATTR_TARGET).string(); if ( e && e->button() == 1 ) utarget = "_blank"; if ( evt->target()->id() == ID_IMG ) { HTMLImageElementImpl* img = static_cast<HTMLImageElementImpl*>( evt->target() ); if ( img && img->isServerMap() ) { khtml::RenderImage *r = static_cast<khtml::RenderImage *>(img->renderer()); if(r && e) { KHTMLView* v = getDocument()->view(); int x = e->clientX(); int y = e->clientY(); int absx = 0; int absy = 0; if ( v ) { x += v->contentsX(); y += v->contentsY(); } r->absolutePosition(absx, absy); url += QString("?%1,%2").arg( x - absx ).arg( y - absy ); } else { evt->setDefaultHandled(); HTMLElementImpl::defaultEventHandler(evt); return; } } } if ( !evt->defaultPrevented() ) { int state = 0; int button = 0; if ( e ) { if ( e->ctrlKey() ) state |= Qt::ControlButton; if ( e->shiftKey() ) state |= Qt::ShiftButton; if ( e->altKey() ) state |= Qt::AltButton; if ( e->metaKey() ) state |= Qt::MetaButton; if ( e->button() == 0 ) button = Qt::LeftButton; else if ( e->button() == 1 ) button = Qt::MidButton; else if ( e->button() == 2 ) button = Qt::RightButton; } else if ( k ) { if ( k->checkModifier(Qt::ShiftButton) ) state |= Qt::ShiftButton; if ( k->checkModifier(Qt::AltButton) ) state |= Qt::AltButton; if ( k->checkModifier(Qt::ControlButton) ) state |= Qt::ControlButton; } // ### also check if focused node is editable if not in designmode, // and prevent link loading then (LS) if (getDocument()->view() && !getDocument()->designMode()) { if (k) click(); else getDocument()->view()->part()-> urlSelected( url, button, state, utarget ); } } evt->setDefaultHandled(); } HTMLElementImpl::defaultEventHandler(evt); }