-rw-r--r-- | noncore/graphics/opie-eye/gui/imagescrollview.cpp | 185 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/gui/imagescrollview.h | 23 |
2 files changed, 199 insertions, 9 deletions
diff --git a/noncore/graphics/opie-eye/gui/imagescrollview.cpp b/noncore/graphics/opie-eye/gui/imagescrollview.cpp index 019f376..0d35354 100644 --- a/noncore/graphics/opie-eye/gui/imagescrollview.cpp +++ b/noncore/graphics/opie-eye/gui/imagescrollview.cpp @@ -9,4 +9,5 @@ using namespace Opie::Core; -ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f) - :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(img) +ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit) + :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale), + rotate_to_fit(rfit),first_resize_done(false) { @@ -15,4 +16,5 @@ ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char -ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f) - :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(img) +ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit) + :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale), + rotate_to_fit(rfit),first_resize_done(false) { @@ -23,3 +25,5 @@ void ImageScrollView::setImage(const QImage&img) { - _image_data = img; + _image_data = QImage(); + _original_data=img; + first_resize_done = false; init(); @@ -31,3 +35,6 @@ void ImageScrollView::init() viewport()->setBackgroundColor(white); - resizeContents(_image_data.width(),_image_data.height()); + if (_original_data.size().isValid()) { + resizeContents(_original_data.width(),_original_data.height()); + } + last_rot = Rotate0; } @@ -38,2 +45,161 @@ ImageScrollView::~ImageScrollView() +void ImageScrollView::rescaleImage(int w, int h) +{ + if (_image_data.width()==w && _image_data.height()==h) { + return; + } + double hs = (double)h / (double)_image_data.height() ; + double ws = (double)w / (double)_image_data.width() ; + double scaleFactor = (hs > ws) ? ws : hs; + int smoothW = (int)(scaleFactor * _image_data.width()); + int smoothH = (int)(scaleFactor * _image_data.height()); + _image_data = _image_data.smoothScale(smoothW,smoothH); +} + +void ImageScrollView::rotate_into_data(Rotation r) +{ + /* realy - we must do this that way, 'cause when acting direct on _image_data the app will + segfault :( */ + QImage dest; + int x, y; + if ( _original_data.depth() > 8 ) + { + unsigned int *srcData, *destData; + switch ( r ) + { + case Rotate90: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned int *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned int *)dest.scanLine(x); + destData[_original_data.height()-y-1] = srcData[x]; + } + } + break; + case Rotate180: + dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned int *)_original_data.scanLine(y); + destData = (unsigned int *)dest.scanLine(_original_data.height()-y-1); + for ( x=0; x < _original_data.width(); ++x ) + destData[_original_data.width()-x-1] = srcData[x]; + } + break; + case Rotate270: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned int *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned int *)dest.scanLine(_original_data.width()-x-1); + destData[y] = srcData[x]; + } + } + break; + default: + dest = _original_data; + break; + } + } + else + { + unsigned char *srcData, *destData; + unsigned int *srcTable, *destTable; + switch ( r ) + { + case Rotate90: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + dest.setNumColors(_original_data.numColors()); + srcTable = (unsigned int *)_original_data.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < _original_data.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned char *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned char *)dest.scanLine(x); + destData[_original_data.height()-y-1] = srcData[x]; + } + } + break; + case Rotate180: + dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); + dest.setNumColors(_original_data.numColors()); + srcTable = (unsigned int *)_original_data.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < _original_data.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned char *)_original_data.scanLine(y); + destData = (unsigned char *)dest.scanLine(_original_data.height()-y-1); + for ( x=0; x < _original_data.width(); ++x ) + destData[_original_data.width()-x-1] = srcData[x]; + } + break; + case Rotate270: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + dest.setNumColors(_original_data.numColors()); + srcTable = (unsigned int *)_original_data.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < _original_data.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned char *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned char *)dest.scanLine(_original_data.width()-x-1); + destData[y] = srcData[x]; + } + } + break; + default: + dest = _original_data; + break; + } + + } + _image_data = dest; +} + +void ImageScrollView::resizeEvent(QResizeEvent * e) +{ + odebug << "ImageScrollView resizeEvent" << oendl; + QScrollView::resizeEvent(e); + Rotation r = Rotate0; + if (width()>height()&&_original_data.width()<_original_data.height() || + width()<height()&&_original_data.width()>_original_data.height()) { + if (rotate_to_fit) r = Rotate90; + } + odebug << " r = " << r << oendl; + if (scale_to_fit) { + if (!_image_data.size().isValid()||width()>_image_data.width()||height()>_image_data.height()) { + if (r==Rotate0) { + _image_data = _original_data; + } else { + rotate_into_data(r); + } + } + rescaleImage(width(),height()); + resizeContents(width()-10,height()-10); + } else if (!first_resize_done||r!=last_rot) { + if (r==Rotate0) { + _image_data = _original_data; + } else { + rotate_into_data(r); + } + last_rot = r; + resizeContents(_image_data.width(),_image_data.height()); + } + first_resize_done = true; +} + void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph) @@ -46,2 +212,6 @@ void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw + if (!_image_data.size().isValid()) { + p->fillRect(clipx,clipy,clipw,cliph,white); + return; + } if (w>_image_data.width()) { @@ -60,3 +230,3 @@ void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw } - if (erase) { + if (erase||_image_data.hasAlphaBuffer()) { p->fillRect(clipx,clipy,clipw,cliph,white); @@ -100,2 +270,3 @@ ImageDlg::ImageDlg(const QString&fname,QWidget * parent, const char * name) dlglayout->addWidget(inf); + odebug << "Imagedlg constructor end" << oendl; } diff --git a/noncore/graphics/opie-eye/gui/imagescrollview.h b/noncore/graphics/opie-eye/gui/imagescrollview.h index edea235..e25f955 100644 --- a/noncore/graphics/opie-eye/gui/imagescrollview.h +++ b/noncore/graphics/opie-eye/gui/imagescrollview.h @@ -14,4 +14,4 @@ class ImageScrollView:public QScrollView public: - ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0 ); - ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0 ); + ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false ); + ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false ); virtual ~ImageScrollView(); @@ -19,2 +19,10 @@ public: void setImage(const QImage&); + + enum Rotation { + Rotate0, + Rotate90, + Rotate180, + Rotate270 + }; + protected: @@ -24,2 +32,3 @@ protected: QImage _image_data; + QImage _original_data; @@ -27,2 +36,11 @@ protected: + bool scale_to_fit; + bool rotate_to_fit; + bool first_resize_done; + Rotation last_rot; + + void rescaleImage(int w, int h); + + void rotate_into_data(Rotation r); + protected slots: @@ -31,2 +49,3 @@ protected slots: virtual void contentsMouseReleaseEvent ( QMouseEvent * e); + virtual void resizeEvent(QResizeEvent * e); }; |