📄 render_image.cpp
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: render_image.cpp,v 1.2 2002/01/28 04:31:02 leon Exp $ *///#define DEBUG_LAYOUT#include "render_interface.h"#include "mgcolor.h"#include "mgcolorgroup.h"#include "mgpen.h"#include "mgbrush.h"#include "mgsize.h"#include "mgrect.h"#include "mgpixmap.h"#include "mgfontmetrics.h"#include "mgfontinfo.h"#include "mgpainter.h"#include "mghtml_part.h"#include "render_image.h"#include "render_style.h"#include "render_interface.h"#include "render_cacheimage.h"#define DEBUG_BY_XHTANG 0//for InvalidateRect#include <minigui/window.h>#include "kdebug.h"using namespace DOM;using namespace khtml;// -------------------------------------------------------------------------RenderImage::RenderImage() : RenderReplaced(){ bComplete = true; setLayouted(false); setParsing(false); image = 0;}RenderImage::~RenderImage(){ image->deref();}void RenderImage::setStyle(RenderStyle* style){ RenderReplaced::setStyle(style); if (m_style->width().isFixed()) pixSize.setWidth(m_style->width().value); else pixSize.setWidth(16); if(m_style->height().isFixed()) pixSize.setHeight(m_style->height().value); else pixSize.setHeight(16); // init RenderObject attributes m_inline = ( m_style->display()==INLINE );}void RenderImage::setPixmap( const MGPixmap &p, const MGRect& r, MGCachedImage *o, bool *manualUpdate ){#if 0 if(o != image) { RenderReplaced::setPixmap(p, r, o); return; } if (manualUpdate && *manualUpdate) { updateSize(); return; } // Image dimensions have been changed, recalculate layout if(o->pixmap_size() != pixSize) { o->pixmap_size().width(), o->pixmap_size().height()); pix = p; pixSize = o->pixmap_size(); setLayouted(false); setMinMaxKnown(false); // the updateSize() call should trigger a repaint too if (manualUpdate) { *manualUpdate = true; } else { updateSize(); } } else { pix = p; bool completeRepaint = !resizeCache.isNull(); // HACK int cHeight = contentHeight(); int scaledHeight = pixSize.height() ? ((o->valid_rect().height()*cHeight)/pixSize.height()) : 0; // don't bog down X server doing xforms if(completeRepaint && cHeight >= 5 && o->valid_rect().height() < pixSize.height() && (scaledHeight / (cHeight/5) == resizeCache.height() / (cHeight/5))) return; resizeCache = MGPixmap(); // 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()); } }#endif}void RenderImage::printReplaced(MGPainter *p, int _tx, int _ty){ // add offset for relative positioning if(isRelPositioned()) relativePositionOffset(_tx, _ty); int cWidth = contentWidth(); int cHeight = contentHeight(); int leftBorder = borderLeft(); int topBorder = borderTop(); int leftPad = paddingLeft(); int topPad = paddingTop(); if (image && !(image->p->loadOk) && !image->m_bIsRequested) { if (cWidth > 0 && cHeight > 0) { MGColorGroup colorGrp( MG::black, MG::lightGray, MG::white, MG::darkGray, MG::gray, MG::black, MG::white ); MGDrawShadePanel( p, _tx + leftBorder + leftPad, _ty + topBorder + topPad, cWidth, cHeight, colorGrp, true, 1 ); if(!alt.isEmpty()) { QString text = alt.string(); p->setFont(style()->font()); p->setPen( style()->color() ); int ax = _tx + leftBorder + QMAX(5, leftPad); int ay = _ty + topBorder + QMAX(5, topPad); int ah = cHeight - QMAX(10, leftPad + paddingRight()); int aw = cWidth - QMAX(10, topPad + paddingBottom()); MGFontMetrics fm(style()->font(), m_part); if (aw>15 && ah>fm.height()) p->drawText(ax, ay, aw, ah , MG::WordBreak, text ); } } } else if (image) { p->drawPixmap( _tx + leftBorder + leftPad, _ty + topBorder + topPad, *image->p, 0, 0, cWidth, cHeight);//fprintf(stderr,"x:%d y:%d w:%d h:%d\n", _tx + leftBorder + leftPad, _ty + topBorder + topPad, cWidth, cHeight);#if 0 if ( (cWidth != pixSize.width() || cHeight != pixSize.height() ) && pix.width() > 0 && pix.height() > 0 && image->valid_rect().isValid()) { if (resizeCache.isNull()) { MGRect scaledrect(image->valid_rect()); // ### Qt bug, it doesn't like width/height of 1 if(scaledrect.width() == 1) scaledrect.setWidth(2); if(scaledrect.height() == 1) scaledrect.setHeight(2); MGWMatrix matrix; matrix.scale( (float)(cWidth)/pixSize.width(), (float)(cHeight)/pixSize.height() ); resizeCache = pix.xForm( matrix ); scaledrect = matrix.map(scaledrect); // 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 MGSize s(scaledrect.size()); if(image->valid_rect().size() == pixSize) // fully loaded s = MGSize(cWidth, cHeight); if(QABS(s.width() - cWidth) < 2) // rounding errors s.setWidth(cWidth); if(resizeCache.size() != s) resizeCache.resize(s); p->drawPixmap(MGPoint( _tx + leftBorder + leftPad, _ty + topBorder + topPad), resizeCache, scaledrect ); } else p->drawPixmap( MGPoint( _tx + leftBorder + leftPad, _ty + topBorder + topPad), resizeCache ); } 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 pixSize instead. // ### maybe no progressive loading for the second image ? MGRect rect(image->valid_rect().isValid() ? image->valid_rect() : MGRect(0, 0, pixSize.width(), pixSize.height())) ; }#endif } if (hasKeyboardFocus!=DOM::ActivationOff) { p->setRasterOp(MG::XorROP); if (hasKeyboardFocus==DOM::ActivationPassive) p->setPen(MGColor("white")); else p->setPen(MGColor("blue")); p->drawRect( _tx + leftBorder, _ty + topBorder-1, cWidth, cHeight+2); p->drawRect( _tx + leftBorder-1, _ty + topBorder, cWidth+2, cHeight); p->setRasterOp(MG::CopyROP); }}void RenderImage::calcMinMaxWidth(){ if(minMaxKnown()) return; short oldwidth = m_width; calcWidth(); if(m_width != oldwidth) resizeCache = MGPixmap(); m_maxWidth = m_minWidth = m_width; setMinMaxKnown();}void RenderImage::layout(){ if(layouted()) return; if(!minMaxKnown()) calcMinMaxWidth(); int oldheight = m_height; calcHeight(); if(oldheight != m_height) resizeCache = MGPixmap(); setLayouted(); }void RenderImage::setImageUrl(DOMString url, DOMString baseUrl, MGDocLoader *docLoader){ if(image) image->deref(); //following added for cache unsigned char u[256]; uncharURL(url,baseUrl,u); image = docLoader->requestImage(this,u); if (image && (!image->p->loadOk))return; if (image && image->p->loadOk ) { if(!(m_style->width().isFixed())) pixSize.setWidth(image->pixmap_size().width()); if(!(m_style->height().isFixed())) pixSize.setHeight(image->pixmap_size().height()); } else{ pixSize.setWidth(0); pixSize.setHeight(0); }// if( image ) pixSize = image->pixmap_size(); if(!image)return; setLayouted(false); setMinMaxKnown(false);}void RenderImage::setAlt(DOM::DOMString text){ alt = text;}short RenderImage::baselineOffset() const{ switch(m_style->verticalAlign()) { case BASELINE: case SUB: case SUPER: case BOTTOM: return contentHeight(); case TOP: return 0; case TEXT_TOP: return MGFontMetrics(m_style->font(), m_part).ascent(); case MIDDLE: return contentHeight()/2; case TEXT_BOTTOM: return contentHeight()-MGFontMetrics(m_style->font(), m_part).descent(); } return 0;}int RenderImage::bidiHeight() const{ if (image && image->p->loadOk) return pixSize.height(); else return 16;}short RenderImage::intrinsicWidth() const{ if (image && image->p->loadOk) return pixSize.width(); else return 16;}int RenderImage::intrinsicHeight() const{ if (image && image->p->loadOk) return pixSize.height(); else return 16;}////following are added for cachevoid RenderImage::AfterDataLoaded (){ if (image && image->p->loadOk) { if (pixSize == image->pixmap_size()) { repaintRectangle(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); } else { pixSize = image->pixmap_size(); if (pixSize.width () == 0 || pixSize.height () == 0) { pixSize.setWidth(16); pixSize.setHeight(16); } setLayouted (false); setMinMaxKnown (false); calcWidth (); calcHeight (); updateSize (); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -