diff --git a/core/utils.cpp b/core/utils.cpp index 0fa5ecb3f..5dcc345f4 100644 --- a/core/utils.cpp +++ b/core/utils.cpp @@ -10,6 +10,7 @@ #include "utils.h" #include +#include #ifdef Q_WS_X11 #include @@ -149,3 +150,63 @@ double Utils::dpiY() return QDesktopWidget().physicalDpiY(); } #endif + +inline static bool isWhite( QRgb argb ) { + return ( argb & 0xFFFFFF ) == 0xFFFFFF; // ignore alpha +} + +NormalizedRect Utils::imageBoundingBox( const QImage * image ) +{ + if ( !image ) + return NormalizedRect(); + + int width = image->width(); + int height = image->height(); + int left, top, bottom, right, x, y; + +#ifdef BBOX_DEBUG + QTime time; + time.start(); +#endif + + // Scan pixels for top non-white + for ( top = 0; top < height; ++top ) + for ( x = 0; x < width; ++x ) + if ( !isWhite( image->pixel( x, top ) ) ) + goto got_top; + return NormalizedRect( 0, 0, 0, 0 ); // the image is blank +got_top: + left = right = x; + + // Scan pixels for bottom non-white + for ( bottom = height-1; bottom >= top; --bottom ) + for ( x = width-1; x >= 0; --x ) + if ( !isWhite( image->pixel( x, bottom ) ) ) + goto got_bottom; + Q_ASSERT( 0 ); // image changed?! +got_bottom: + if ( x < left ) + left = x; + if ( x > right ) + right = x; + + // Scan for leftmost and rightmost (we already found some bounds on these): + for ( y = top; y <= bottom && ( left > 0 || right < width-1 ); ++y ) + { + for ( x = 0; x < left; ++x ) + if ( !isWhite( image->pixel( x, y ) ) ) + left = x; + for ( x = width-1; x > right+1; --x ) + if ( !isWhite( image->pixel( x, y ) ) ) + right = x; + } + + NormalizedRect bbox( QRect( left, top, ( right - left + 1), ( bottom - top + 1 ) ), + image->width(), image->height() ); + +#ifdef BBOX_DEBUG + kDebug() << "Computed bounding box" << bbox << "in" << time.elapsed() << "ms"; +#endif + + return bbox; +} diff --git a/core/utils.h b/core/utils.h index 38ec7100d..9e125c9c0 100644 --- a/core/utils.h +++ b/core/utils.h @@ -11,8 +11,10 @@ #define _OKULAR_UTILS_H_ #include +#include class QRect; +class QImage; namespace Okular { @@ -40,6 +42,14 @@ class OKULAR_EXPORT Utils * Return the vertical DPI of the main display */ static double dpiY(); + + /** + * Compute the smallest rectangle that contains all non-white pixels in image), + * in normalized [0,1] coordinates. + * + * @since 0.7 (KDE 4.1) + */ + static NormalizedRect imageBoundingBox( const QImage* image ); }; }