1 /***************************************************************************
2 * Copyright (C) 2006 by Luigi Toscano <luigi.toscano@tiscali.it> *
3 * Copyright (C) 2008 by Pino Toscano <pino@kde.org> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
14 #include <QtCore/QRect>
23 #include <ApplicationServices/ApplicationServices.h>
24 #include <IOKit/graphics/IOGraphicsLib.h>
29 using namespace Okular
;
31 QRect
Utils::rotateRect( const QRect
& source
, int width
, int height
, int orientation
)
35 // adapt the coordinates of the boxes to the rotation
36 switch ( orientation
)
39 ret
= QRect( width
- source
.y() - source
.height(), source
.x(),
40 source
.height(), source
.width() );
43 ret
= QRect( width
- source
.x() - source
.width(), height
- source
.y() - source
.height(),
44 source
.width(), source
.height() );
47 ret
= QRect( source
.y(), height
- source
.x() - source
.width(),
48 source
.height(), source
.width() );
50 case 0: // no modifications
51 default: // other cases
62 return QX11Info::appDpiX();
67 return QX11Info::appDpiY();
70 #elif defined(Q_WS_MAC)
72 * Code copied from http://developer.apple.com/qa/qa2001/qa1217.html
74 // Handy utility function for retrieving an int from a CFDictionaryRef
75 static int GetIntFromDictionaryForKey( CFDictionaryRef desc
, CFStringRef key
)
79 if ( (value
= (CFNumberRef
)CFDictionaryGetValue(desc
, key
)) == NULL
|| CFGetTypeID(value
) != CFNumberGetTypeID())
81 CFNumberGetValue(value
, kCFNumberIntType
, &num
);
85 static CGDisplayErr
GetDisplayDPI( CFDictionaryRef displayModeDict
, CGDirectDisplayID displayID
,
86 double *horizontalDPI
, double *verticalDPI
)
88 CGDisplayErr err
= kCGErrorFailure
;
89 io_connect_t displayPort
;
90 CFDictionaryRef displayDict
;
92 // Grab a connection to IOKit for the requested display
93 displayPort
= CGDisplayIOServicePort( displayID
);
94 if ( displayPort
!= MACH_PORT_NULL
)
96 // Find out what IOKit knows about this display
97 displayDict
= IODisplayCreateInfoDictionary(displayPort
, 0);
98 if ( displayDict
!= NULL
)
100 const double mmPerInch
= 25.4;
101 double horizontalSizeInInches
=
102 (double)GetIntFromDictionaryForKey(displayDict
,
103 CFSTR(kDisplayHorizontalImageSize
)) / mmPerInch
;
104 double verticalSizeInInches
=
105 (double)GetIntFromDictionaryForKey(displayDict
,
106 CFSTR(kDisplayVerticalImageSize
)) / mmPerInch
;
108 // Make sure to release the dictionary we got from IOKit
109 CFRelease(displayDict
);
111 // Now we can calculate the actual DPI
112 // with information from the displayModeDict
114 (double)GetIntFromDictionaryForKey( displayModeDict
, kCGDisplayWidth
)
115 / horizontalSizeInInches
;
116 *verticalDPI
= (double)GetIntFromDictionaryForKey( displayModeDict
,
117 kCGDisplayHeight
) / verticalSizeInInches
;
118 err
= CGDisplayNoErr
;
127 CGDisplayErr err
= GetDisplayDPI( CGDisplayCurrentMode(kCGDirectMainDisplay
),
128 kCGDirectMainDisplay
,
131 return err
== CGDisplayNoErr
? x
: 72.0;
137 CGDisplayErr err
= GetDisplayDPI( CGDisplayCurrentMode(kCGDirectMainDisplay
),
138 kCGDirectMainDisplay
,
141 return err
== CGDisplayNoErr
? y
: 72.0;
144 #include <QDesktopWidget>
148 return QDesktopWidget().physicalDpiX();
153 return QDesktopWidget().physicalDpiY();
157 inline static bool isWhite( QRgb argb
) {
158 return ( argb
& 0xFFFFFF ) == 0xFFFFFF; // ignore alpha
161 NormalizedRect
Utils::imageBoundingBox( const QImage
* image
)
164 return NormalizedRect();
166 int width
= image
->width();
167 int height
= image
->height();
168 int left
, top
, bottom
, right
, x
, y
;
175 // Scan pixels for top non-white
176 for ( top
= 0; top
< height
; ++top
)
177 for ( x
= 0; x
< width
; ++x
)
178 if ( !isWhite( image
->pixel( x
, top
) ) )
180 return NormalizedRect( 0, 0, 0, 0 ); // the image is blank
184 // Scan pixels for bottom non-white
185 for ( bottom
= height
-1; bottom
>= top
; --bottom
)
186 for ( x
= width
-1; x
>= 0; --x
)
187 if ( !isWhite( image
->pixel( x
, bottom
) ) )
189 Q_ASSERT( 0 ); // image changed?!
196 // Scan for leftmost and rightmost (we already found some bounds on these):
197 for ( y
= top
; y
<= bottom
&& ( left
> 0 || right
< width
-1 ); ++y
)
199 for ( x
= 0; x
< left
; ++x
)
200 if ( !isWhite( image
->pixel( x
, y
) ) )
202 for ( x
= width
-1; x
> right
+1; --x
)
203 if ( !isWhite( image
->pixel( x
, y
) ) )
207 NormalizedRect
bbox( QRect( left
, top
, ( right
- left
+ 1), ( bottom
- top
+ 1 ) ),
208 image
->width(), image
->height() );
211 kDebug() << "Computed bounding box" << bbox
<< "in" << time
.elapsed() << "ms";
217 void Okular::copyQIODevice( QIODevice
*from
, QIODevice
*to
)
219 QByteArray
buffer( 65536, '\0' );
222 while ( ( read
= from
->read( buffer
.data(), buffer
.size() ) ) > 0 )
224 written
= to
->write( buffer
.constData(), read
);
225 if ( read
!= written
)