📄 render_image.cpp
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000-2003 Dirk Mueller (mueller@kde.org) * (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * *///#define DEBUG_LAYOUT#include "render_image.h"#include "render_canvas.h"#include <qdrawutil.h>#include <qpainter.h>#include <kapplication.h>#include <kdebug.h>#include <kglobalsettings.h>#include "css/csshelper.h"#include "misc/helper.h"#include "misc/htmlattrs.h"#include "misc/loader.h"#include "misc/htmltags.h"#include "html/html_formimpl.h"#include "html/html_imageimpl.h"#include "html/dtd.h"#include "xml/dom2_eventsimpl.h"#include "html/html_documentimpl.h"#include "html/html_objectimpl.h"#include "khtmlview.h"#include "khtml_part.h"#include <math.h>#include "loading_icon.cpp"using namespace DOM;using namespace khtml;// -------------------------------------------------------------------------RenderImage::RenderImage(NodeImpl *_element) : RenderReplaced(_element){ oimage = image = 0; m_selectionState = SelectionNone; berrorPic = false; const KHTMLSettings *settings = _element->getDocument()->view()->part()->settings(); bUnfinishedImageFrame = settings->unfinishedImageFrame(); setIntrinsicWidth( 0 ); setIntrinsicHeight( 0 );}RenderImage::~RenderImage(){ if(image) image->deref(this); if (oimage) oimage->deref( this );}QPixmap RenderImage::pixmap() const{ return image ? image->pixmap() : QPixmap();}void RenderImage::setStyle(RenderStyle* _style){ RenderReplaced::setStyle(_style); // init RenderObject attributes //setOverhangingContents(style()->height().isPercent()); setShouldPaintBackgroundOrBorder(true);}void RenderImage::setContentObject(CachedObject* co ){ if (co && image != co) updateImage( static_cast<CachedImage*>( co ) );}void RenderImage::setPixmap( const QPixmap &p, const QRect& r, CachedImage *o){ if ( o == oimage ) return; if(o != image) { RenderReplaced::setPixmap(p, r, o); return; } bool iwchanged = false; if(o->isErrorImage()) { int iw = p.width() + 8; int ih = p.height() + 8; // we have an alt and the user meant it (its not a text we invented) if ( element() && !alt.isEmpty() && !element()->getAttribute( ATTR_ALT ).isNull()) { const QFontMetrics &fm = style()->fontMetrics(); QRect br = fm.boundingRect ( 0, 0, 1024, 256, Qt::AlignAuto|Qt::WordBreak, alt.string() ); if ( br.width() > iw ) iw = br.width(); if ( br.height() > ih ) ih = br.height(); } if ( iw != intrinsicWidth() ) { setIntrinsicWidth( iw ); iwchanged = true; } if ( ih != intrinsicHeight() ) { setIntrinsicHeight( ih ); iwchanged = true; } if ( element() && element()->id() == ID_OBJECT ) { static_cast<HTMLObjectElementImpl*>( element() )->renderAlternative(); return; } } berrorPic = o->isErrorImage(); bool needlayout = false; // Image dimensions have been changed, see what needs to be done if( o->pixmap_size().width() != intrinsicWidth() || o->pixmap_size().height() != intrinsicHeight() || iwchanged ) {// qDebug("image dimensions have been changed, old: %d/%d new: %d/%d",// intrinsicWidth(), intrinsicHeight(),// o->pixmap_size().width(), o->pixmap_size().height()); if(!o->isErrorImage()) { setIntrinsicWidth( o->pixmap_size().width() ); setIntrinsicHeight( o->pixmap_size().height() ); } // lets see if we need to relayout at all.. int oldwidth = m_width; int oldheight = m_height; int oldminwidth = m_minWidth; m_minWidth = 0; if ( parent() ) { calcWidth(); calcHeight(); } if(iwchanged || m_width != oldwidth || m_height != oldheight) needlayout = true; m_minWidth = oldminwidth; m_width = oldwidth; m_height = oldheight; } // we're not fully integrated in the tree yet.. we'll come back. if ( !parent() ) return; if(needlayout) { if (!selfNeedsLayout()) setNeedsLayout(true); if (minMaxKnown()) setMinMaxKnown(false); } else { bool completeRepaint = !resizeCache.isNull(); int cHeight = contentHeight(); int scaledHeight = intrinsicHeight() ? ((o->valid_rect().height()*cHeight)/intrinsicHeight()) : 0; // don't bog down X server doing xforms if(completeRepaint && cHeight >= 5 && o->valid_rect().height() < intrinsicHeight() && (scaledHeight / (cHeight/5) == resizeCache.height() / (cHeight/5))) return; resizeCache = QPixmap(); // for resized animations if(completeRepaint) repaintRectangle(borderLeft()+paddingLeft(), borderTop()+paddingTop(), contentWidth(), contentHeight()); else { repaintRectangle(r.x() + borderLeft() + paddingLeft(), r.y() + borderTop() + paddingTop(), r.width(), r.height()); } }}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); int cWidth = contentWidth(); int cHeight = contentHeight(); int leftBorder = borderLeft(); int topBorder = borderTop(); int leftPad = paddingLeft(); int topPad = paddingTop(); if (!canvas()->printImages()) return; CachedImage* i = oimage && oimage->valid_rect().size() == oimage->pixmap_size() && oimage->pixmap_size().width() == intrinsicWidth() && oimage->pixmap_size().height() == intrinsicHeight() ? oimage : image; // paint frame around image 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 ); paintInfo.p->drawRect(_tx, _ty, m_width, m_height); if (!(m_width <= 5 || m_height <= 5)) { if (!loadingIcon) { loadingIcon = new QPixmap(); loadingIcon->loadFromData(loading_icon_data, loading_icon_len); } paintInfo.p->drawPixmap(_tx + 4, _ty + 4, *loadingIcon, 0, 0, m_width - 5, m_height - 5); } } //kdDebug( 6040 ) << " contents (" << contentWidth << "/" << contentHeight << ") border=" << borderLeft() << " padding=" << paddingLeft() << endl; 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, KApplication::palette().inactive(), true, 1 ); } QPixmap const* pix = i ? &i->pixmap() : 0; if(berrorPic && pix && (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(); if (cWidth>5 && cHeight>=fm.height()) paintInfo.p->drawText(ax, ay+1, cWidth - 4, cHeight - 4, Qt::WordBreak, text ); } } } else if (i && !i->isTransparent()) { paintInfo.p->setPen( Qt::black ); // used for bitmaps const QPixmap& pix = i->pixmap(); if ( (cWidth != intrinsicWidth() || cHeight != intrinsicHeight()) && pix.width() > 0 && pix.height() > 0 && i->valid_rect().isValid()) { if (resizeCache.isNull() && cWidth && cHeight && intrinsicWidth() && intrinsicHeight()) { QRect scaledrect(i->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(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -