use kDebug
[kdegraphics.git] / okular / core / utils.cpp
blob5dcc345f4617f526fa1cd436418f87ab32e281e2
1 /***************************************************************************
2 * Copyright (C) 2006 by Luigi Toscano <luigi.toscano@tiscali.it> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 ***************************************************************************/
10 #include "utils.h"
12 #include <QtCore/QRect>
13 #include <QImage>
15 #ifdef Q_WS_X11
16 #include <QX11Info>
17 #endif
19 #ifdef Q_WS_MAC
20 #include <ApplicationServices/ApplicationServices.h>
21 #include <IOKit/graphics/IOGraphicsLib.h>
22 #endif
26 using namespace Okular;
28 QRect Utils::rotateRect( const QRect & source, int width, int height, int orientation )
30 QRect ret;
32 // adapt the coordinates of the boxes to the rotation
33 switch ( orientation )
35 case 1:
36 ret = QRect( width - source.y() - source.height(), source.x(),
37 source.height(), source.width() );
38 break;
39 case 2:
40 ret = QRect( width - source.x() - source.width(), height - source.y() - source.height(),
41 source.width(), source.height() );
42 break;
43 case 3:
44 ret = QRect( source.y(), height - source.x() - source.width(),
45 source.height(), source.width() );
46 break;
47 case 0: // no modifications
48 default: // other cases
49 ret = source;
52 return ret;
55 #if defined(Q_WS_X11)
57 double Utils::dpiX()
59 return QX11Info::appDpiX();
62 double Utils::dpiY()
64 return QX11Info::appDpiY();
67 #elif defined(Q_WS_MAC)
69 * Code copied from http://developer.apple.com/qa/qa2001/qa1217.html
71 // Handy utility function for retrieving an int from a CFDictionaryRef
72 static int GetIntFromDictionaryForKey( CFDictionaryRef desc, CFStringRef key )
74 CFNumberRef value;
75 int num = 0;
76 if ( (value = (CFNumberRef)CFDictionaryGetValue(desc, key)) == NULL || CFGetTypeID(value) != CFNumberGetTypeID())
77 return 0;
78 CFNumberGetValue(value, kCFNumberIntType, &num);
79 return num;
82 static CGDisplayErr GetDisplayDPI( CFDictionaryRef displayModeDict, CGDirectDisplayID displayID,
83 double *horizontalDPI, double *verticalDPI )
85 CGDisplayErr err = kCGErrorFailure;
86 io_connect_t displayPort;
87 CFDictionaryRef displayDict;
89 // Grab a connection to IOKit for the requested display
90 displayPort = CGDisplayIOServicePort( displayID );
91 if ( displayPort != MACH_PORT_NULL )
93 // Find out what IOKit knows about this display
94 displayDict = IODisplayCreateInfoDictionary(displayPort, 0);
95 if ( displayDict != NULL )
97 const double mmPerInch = 25.4;
98 double horizontalSizeInInches =
99 (double)GetIntFromDictionaryForKey(displayDict,
100 CFSTR(kDisplayHorizontalImageSize)) / mmPerInch;
101 double verticalSizeInInches =
102 (double)GetIntFromDictionaryForKey(displayDict,
103 CFSTR(kDisplayVerticalImageSize)) / mmPerInch;
105 // Make sure to release the dictionary we got from IOKit
106 CFRelease(displayDict);
108 // Now we can calculate the actual DPI
109 // with information from the displayModeDict
110 *horizontalDPI =
111 (double)GetIntFromDictionaryForKey( displayModeDict, kCGDisplayWidth )
112 / horizontalSizeInInches;
113 *verticalDPI = (double)GetIntFromDictionaryForKey( displayModeDict,
114 kCGDisplayHeight ) / verticalSizeInInches;
115 err = CGDisplayNoErr;
118 return err;
121 double Utils::dpiX()
123 double x,y;
124 CGDisplayErr err = GetDisplayDPI( CGDisplayCurrentMode(kCGDirectMainDisplay),
125 kCGDirectMainDisplay,
126 &x, &y );
128 return err == CGDisplayNoErr ? x : 72.0;
131 double Utils::dpiY()
133 double x,y;
134 CGDisplayErr err = GetDisplayDPI( CGDisplayCurrentMode(kCGDirectMainDisplay),
135 kCGDirectMainDisplay,
136 &x, &y );
138 return err == CGDisplayNoErr ? y : 72.0;
140 #else
141 #include <QDesktopWidget>
143 double Utils::dpiX()
145 return QDesktopWidget().physicalDpiX();
148 double Utils::dpiY()
150 return QDesktopWidget().physicalDpiY();
152 #endif
154 inline static bool isWhite( QRgb argb ) {
155 return ( argb & 0xFFFFFF ) == 0xFFFFFF; // ignore alpha
158 NormalizedRect Utils::imageBoundingBox( const QImage * image )
160 if ( !image )
161 return NormalizedRect();
163 int width = image->width();
164 int height = image->height();
165 int left, top, bottom, right, x, y;
167 #ifdef BBOX_DEBUG
168 QTime time;
169 time.start();
170 #endif
172 // Scan pixels for top non-white
173 for ( top = 0; top < height; ++top )
174 for ( x = 0; x < width; ++x )
175 if ( !isWhite( image->pixel( x, top ) ) )
176 goto got_top;
177 return NormalizedRect( 0, 0, 0, 0 ); // the image is blank
178 got_top:
179 left = right = x;
181 // Scan pixels for bottom non-white
182 for ( bottom = height-1; bottom >= top; --bottom )
183 for ( x = width-1; x >= 0; --x )
184 if ( !isWhite( image->pixel( x, bottom ) ) )
185 goto got_bottom;
186 Q_ASSERT( 0 ); // image changed?!
187 got_bottom:
188 if ( x < left )
189 left = x;
190 if ( x > right )
191 right = x;
193 // Scan for leftmost and rightmost (we already found some bounds on these):
194 for ( y = top; y <= bottom && ( left > 0 || right < width-1 ); ++y )
196 for ( x = 0; x < left; ++x )
197 if ( !isWhite( image->pixel( x, y ) ) )
198 left = x;
199 for ( x = width-1; x > right+1; --x )
200 if ( !isWhite( image->pixel( x, y ) ) )
201 right = x;
204 NormalizedRect bbox( QRect( left, top, ( right - left + 1), ( bottom - top + 1 ) ),
205 image->width(), image->height() );
207 #ifdef BBOX_DEBUG
208 kDebug() << "Computed bounding box" << bbox << "in" << time.elapsed() << "ms";
209 #endif
211 return bbox;