compile
[kdegraphics.git] / okular / core / page.cpp
blob64d20a1a31f74205b945be4fd09fc62250419cd9
1 /***************************************************************************
2 * Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> *
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 2 of the License, or *
6 * (at your option) any later version. *
7 ***************************************************************************/
9 #include "page.h"
10 #include "page_p.h"
12 // qt/kde includes
13 #include <QtCore/QHash>
14 #include <QtCore/QSet>
15 #include <QtCore/QString>
16 #include <QtCore/QVariant>
17 #include <QtGui/QPixmap>
18 #include <QtXml/QDomDocument>
19 #include <QtXml/QDomElement>
21 #include <kdebug.h>
23 // local includes
24 #include "action.h"
25 #include "annotations.h"
26 #include "annotations_p.h"
27 #include "area.h"
28 #include "debug_p.h"
29 #include "form.h"
30 #include "form_p.h"
31 #include "pagecontroller_p.h"
32 #include "pagesize.h"
33 #include "pagetransition.h"
34 #include "rotationjob_p.h"
35 #include "textpage.h"
36 #include "textpage_p.h"
38 #ifdef PAGE_PROFILE
39 #include <QtCore/QTime>
40 #endif
42 using namespace Okular;
44 static void deleteObjectRects( QLinkedList< ObjectRect * >& rects, const QSet<ObjectRect::ObjectType>& which )
46 QLinkedList< ObjectRect * >::iterator it = rects.begin(), end = rects.end();
47 for ( ; it != end; )
48 if ( which.contains( (*it)->objectType() ) )
50 delete *it;
51 it = rects.erase( it );
53 else
54 ++it;
57 PagePrivate::PagePrivate( Page *page, uint n, double w, double h, Rotation o )
58 : m_page( page ), m_number( n ), m_orientation( o ),
59 m_width( w ), m_height( h ), m_boundingBox( 0, 0, 1, 1 ),
60 m_rotation( Rotation0 ), m_maxuniqueNum( 0 ),
61 m_text( 0 ), m_transition( 0 ), m_textSelections( 0 ),
62 m_openingAction( 0 ), m_closingAction( 0 ), m_duration( -1 ),
63 m_isBoundingBoxKnown( false )
65 // avoid Division-By-Zero problems in the program
66 if ( m_width <= 0 )
67 m_width = 1;
69 if ( m_height <= 0 )
70 m_height = 1;
73 PagePrivate::~PagePrivate()
75 qDeleteAll( formfields );
76 delete m_openingAction;
77 delete m_closingAction;
78 delete m_text;
79 delete m_transition;
83 void PagePrivate::imageRotationDone( RotationJob * job )
85 QMap< int, PixmapObject >::iterator it = m_pixmaps.find( job->id() );
86 if ( it != m_pixmaps.end() )
88 PixmapObject &object = it.value();
89 (*object.m_pixmap) = QPixmap::fromImage( job->image() );
90 object.m_rotation = job->rotation();
91 } else {
92 PixmapObject object;
93 object.m_pixmap = new QPixmap( QPixmap::fromImage( job->image() ) );
94 object.m_rotation = job->rotation();
96 m_pixmaps.insert( job->id(), object );
100 QMatrix PagePrivate::rotationMatrix() const
102 QMatrix matrix;
103 matrix.rotate( (int)m_rotation * 90 );
105 switch ( m_rotation )
107 case Rotation90:
108 matrix.translate( 0, -1 );
109 break;
110 case Rotation180:
111 matrix.translate( -1, -1 );
112 break;
113 case Rotation270:
114 matrix.translate( -1, 0 );
115 break;
116 default: ;
119 return matrix;
122 /** class Page **/
124 Page::Page( uint page, double w, double h, Rotation o )
125 : d( new PagePrivate( this, page, w, h, o ) )
129 Page::~Page()
131 deletePixmaps();
132 deleteRects();
133 d->deleteHighlights();
134 deleteAnnotations();
135 d->deleteTextSelections();
136 deleteSourceReferences();
138 delete d;
141 int Page::number() const
143 return d->m_number;
146 Rotation Page::orientation() const
148 return d->m_orientation;
151 Rotation Page::rotation() const
153 return d->m_rotation;
156 Rotation Page::totalOrientation() const
158 return (Rotation)( ( (int)d->m_orientation + (int)d->m_rotation ) % 4 );
161 double Page::width() const
163 return d->m_width;
166 double Page::height() const
168 return d->m_height;
171 double Page::ratio() const
173 return d->m_height / d->m_width;
176 NormalizedRect Page::boundingBox() const
178 return d->m_boundingBox;
181 bool Page::isBoundingBoxKnown() const
183 return d->m_isBoundingBoxKnown;
186 void Page::setBoundingBox( const NormalizedRect& bbox )
188 if ( d->m_isBoundingBoxKnown && d->m_boundingBox == bbox )
189 return;
191 // Allow tiny rounding errors (happens during rotation)
192 static const double epsilon = 0.00001;
193 Q_ASSERT( bbox.left >= -epsilon && bbox.top >= -epsilon && bbox.right <= 1 + epsilon && bbox.bottom <= 1 + epsilon );
195 d->m_boundingBox = bbox & NormalizedRect( 0., 0., 1., 1. );
196 d->m_isBoundingBoxKnown = true;
199 bool Page::hasPixmap( int id, int width, int height ) const
201 QMap< int, PagePrivate::PixmapObject >::const_iterator it = d->m_pixmaps.constFind( id );
202 if ( it == d->m_pixmaps.constEnd() )
203 return false;
205 if ( width == -1 || height == -1 )
206 return true;
208 const QPixmap *pixmap = it.value().m_pixmap;
210 return (pixmap->width() == width && pixmap->height() == height);
213 bool Page::hasTextPage() const
215 return d->m_text != 0;
218 RegularAreaRect * Page::textArea ( TextSelection * selection ) const
220 if ( d->m_text )
221 return d->m_text->textArea( selection );
223 return 0;
226 bool Page::hasObjectRect( double x, double y, double xScale, double yScale ) const
228 if ( m_rects.isEmpty() )
229 return false;
231 QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
232 for ( ; it != end; ++it )
233 if ( (*it)->contains( x, y, xScale, yScale ) )
234 return true;
236 return false;
239 bool Page::hasHighlights( int s_id ) const
241 // simple case: have no highlights
242 if ( m_highlights.isEmpty() )
243 return false;
244 // simple case: we have highlights and no id to match
245 if ( s_id == -1 )
246 return true;
247 // iterate on the highlights list to find an entry by id
248 QLinkedList< HighlightAreaRect * >::const_iterator it = m_highlights.begin(), end = m_highlights.end();
249 for ( ; it != end; ++it )
250 if ( (*it)->s_id == s_id )
251 return true;
252 return false;
255 bool Page::hasTransition() const
257 return d->m_transition != 0;
260 bool Page::hasAnnotations() const
262 return !m_annotations.isEmpty();
265 RegularAreaRect * Page::findText( int id, const QString & text, SearchDirection direction,
266 Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *lastRect ) const
268 RegularAreaRect* rect = 0;
269 if ( text.isEmpty() || !d->m_text )
270 return rect;
272 rect = d->m_text->findText( id, text, direction, caseSensitivity, lastRect );
273 return rect;
276 QString Page::text( const RegularAreaRect * area ) const
278 QString ret;
280 if ( !d->m_text )
281 return ret;
283 if ( area )
285 RegularAreaRect rotatedArea = *area;
286 rotatedArea.transform( d->rotationMatrix().inverted() );
288 ret = d->m_text->text( &rotatedArea );
290 else
291 ret = d->m_text->text();
293 return ret;
296 void PagePrivate::rotateAt( Rotation orientation )
298 if ( orientation == m_rotation )
299 return;
301 deleteHighlights();
302 deleteTextSelections();
304 if ( ( (int)m_orientation + (int)m_rotation ) % 2 != ( (int)m_orientation + (int)orientation ) % 2 )
305 qSwap( m_width, m_height );
307 Rotation oldRotation = m_rotation;
308 m_rotation = orientation;
311 * Rotate the images of the page.
313 QMapIterator< int, PagePrivate::PixmapObject > it( m_pixmaps );
314 while ( it.hasNext() ) {
315 it.next();
317 const PagePrivate::PixmapObject &object = it.value();
319 RotationJob *job = new RotationJob( object.m_pixmap->toImage(), object.m_rotation, m_rotation, it.key() );
320 job->setPage( this );
321 PageController::self()->addRotationJob(job);
325 * Rotate the object rects on the page.
327 const QMatrix matrix = rotationMatrix();
328 QLinkedList< ObjectRect * >::const_iterator objectIt = m_page->m_rects.begin(), end = m_page->m_rects.end();
329 for ( ; objectIt != end; ++objectIt )
330 (*objectIt)->transform( matrix );
332 QLinkedList< HighlightAreaRect* >::const_iterator hlIt = m_page->m_highlights.begin(), hlItEnd = m_page->m_highlights.end();
333 for ( ; hlIt != hlItEnd; ++hlIt )
335 (*hlIt)->transform( RotationJob::rotationMatrix( oldRotation, m_rotation ) );
339 void PagePrivate::changeSize( const PageSize &size )
341 if ( size.isNull() || ( size.width() == m_width && size.height() == m_height ) )
342 return;
344 m_page->deletePixmaps();
345 // deleteHighlights();
346 // deleteTextSelections();
348 m_width = size.width();
349 m_height = size.height();
350 if ( m_rotation % 2 )
351 qSwap( m_width, m_height );
354 const ObjectRect * Page::objectRect( ObjectRect::ObjectType type, double x, double y, double xScale, double yScale ) const
356 QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
357 for ( ; it != end; ++it )
358 if ( ( (*it)->objectType() == type ) && (*it)->contains( x, y, xScale, yScale ) )
359 return *it;
360 return 0;
363 const PageTransition * Page::transition() const
365 return d->m_transition;
368 QLinkedList< Annotation* > Page::annotations() const
370 return m_annotations;
373 const Action * Page::pageAction( PageAction action ) const
375 switch ( action )
377 case Page::Opening:
378 return d->m_openingAction;
379 break;
380 case Page::Closing:
381 return d->m_closingAction;
382 break;
385 return 0;
388 QLinkedList< FormField * > Page::formFields() const
390 return d->formfields;
393 void Page::setPixmap( int id, QPixmap *pixmap )
395 if ( d->m_rotation == Rotation0 ) {
396 QMap< int, PagePrivate::PixmapObject >::iterator it = d->m_pixmaps.find( id );
397 if ( it != d->m_pixmaps.end() )
399 delete it.value().m_pixmap;
401 else
403 it = d->m_pixmaps.insert( id, PagePrivate::PixmapObject() );
405 it.value().m_pixmap = pixmap;
406 it.value().m_rotation = d->m_rotation;
407 } else {
408 RotationJob *job = new RotationJob( pixmap->toImage(), Rotation0, d->m_rotation, id );
409 job->setPage( d );
410 PageController::self()->addRotationJob(job);
412 delete pixmap;
416 void Page::setTextPage( TextPage * textPage )
418 delete d->m_text;
420 d->m_text = textPage;
421 if ( d->m_text )
423 d->m_text->d->m_page = d;
427 void Page::setObjectRects( const QLinkedList< ObjectRect * > & rects )
429 QSet<ObjectRect::ObjectType> which;
430 which << ObjectRect::Action << ObjectRect::Image;
431 deleteObjectRects( m_rects, which );
434 * Rotate the object rects of the page.
436 const QMatrix matrix = d->rotationMatrix();
438 QLinkedList< ObjectRect * >::const_iterator objectIt = rects.begin(), end = rects.end();
439 for ( ; objectIt != end; ++objectIt )
440 (*objectIt)->transform( matrix );
442 m_rects << rects;
445 void PagePrivate::setHighlight( int s_id, RegularAreaRect *rect, const QColor & color )
447 HighlightAreaRect * hr = new HighlightAreaRect(rect);
448 hr->s_id = s_id;
449 hr->color = color;
451 m_page->m_highlights.append( hr );
454 void PagePrivate::setTextSelections( RegularAreaRect *r, const QColor & color )
456 deleteTextSelections();
457 if ( r )
459 HighlightAreaRect * hr = new HighlightAreaRect( r );
460 hr->s_id = -1;
461 hr->color = color;
462 m_textSelections = hr;
463 delete r;
467 void Page::setSourceReferences( const QLinkedList< SourceRefObjectRect * > & refRects )
469 deleteSourceReferences();
470 foreach( SourceRefObjectRect * rect, refRects )
471 m_rects << rect;
474 void Page::setDuration( double seconds )
476 d->m_duration = seconds;
479 double Page::duration() const
481 return d->m_duration;
484 void Page::setLabel( const QString& label )
486 d->m_label = label;
489 QString Page::label() const
491 return d->m_label;
494 const RegularAreaRect * Page::textSelection() const
496 return d->m_textSelections;
499 QColor Page::textSelectionColor() const
501 return d->m_textSelections ? d->m_textSelections->color : QColor();
504 void Page::addAnnotation( Annotation * annotation )
506 //uniqueName: okular-PAGENUM-ID
507 if(annotation->uniqueName().isEmpty())
509 QString uniqueName = "okular-";
510 uniqueName += ( QString::number(d->m_number) + '-' + QString::number(++(d->m_maxuniqueNum)) );
512 kDebug(OkularDebug).nospace() << "inc m_maxuniqueNum=" << d->m_maxuniqueNum;
514 annotation->setUniqueName( uniqueName );
516 annotation->d_ptr->m_page = d;
517 m_annotations.append( annotation );
519 AnnotationObjectRect *rect = new AnnotationObjectRect( annotation );
521 // Rotate the annotation on the page.
522 const QMatrix matrix = d->rotationMatrix();
523 annotation->d_ptr->baseTransform( matrix.inverted() );
524 annotation->d_ptr->annotationTransform( matrix );
526 m_rects.append( rect );
529 void PagePrivate::modifyAnnotation(Annotation * newannotation )
531 if(!newannotation)
532 return;
534 QLinkedList< Annotation * >::iterator aIt = m_page->m_annotations.begin(), aEnd = m_page->m_annotations.end();
535 for ( ; aIt != aEnd; ++aIt )
537 if((*aIt)==newannotation)
538 return; //modified already
539 if((*aIt) && (*aIt)->uniqueName()==newannotation->uniqueName())
541 int rectfound = false;
542 QLinkedList< ObjectRect * >::iterator it = m_page->m_rects.begin(), end = m_page->m_rects.end();
543 for ( ; it != end && !rectfound; ++it )
544 if ( ( (*it)->objectType() == ObjectRect::OAnnotation ) && ( (*it)->object() == (*aIt) ) )
546 delete *it;
547 *it = new AnnotationObjectRect( newannotation );
548 rectfound = true;
550 delete *aIt;
551 *aIt = newannotation;
552 break;
557 bool Page::removeAnnotation( Annotation * annotation )
559 if ( !annotation || ( annotation->flags() & Annotation::DenyDelete ) )
560 return false;
562 QLinkedList< Annotation * >::iterator aIt = m_annotations.begin(), aEnd = m_annotations.end();
563 for ( ; aIt != aEnd; ++aIt )
565 if((*aIt) && (*aIt)->uniqueName()==annotation->uniqueName())
567 int rectfound = false;
568 QLinkedList< ObjectRect * >::iterator it = m_rects.begin(), end = m_rects.end();
569 for ( ; it != end && !rectfound; ++it )
570 if ( ( (*it)->objectType() == ObjectRect::OAnnotation ) && ( (*it)->object() == (*aIt) ) )
572 delete *it;
573 it = m_rects.erase( it );
574 rectfound = true;
576 kDebug(OkularDebug) << "removed annotation:" << annotation->uniqueName();
577 delete *aIt;
578 m_annotations.erase( aIt );
579 break;
583 return true;
586 void Page::setTransition( PageTransition * transition )
588 delete d->m_transition;
589 d->m_transition = transition;
592 void Page::setPageAction( PageAction action, Action * link )
594 switch ( action )
596 case Page::Opening:
597 delete d->m_openingAction;
598 d->m_openingAction = link;
599 break;
600 case Page::Closing:
601 delete d->m_closingAction;
602 d->m_closingAction = link;
603 break;
607 void Page::setFormFields( const QLinkedList< FormField * >& fields )
609 qDeleteAll( d->formfields );
610 d->formfields = fields;
611 QLinkedList< FormField * >::const_iterator it = d->formfields.begin(), itEnd = d->formfields.end();
612 for ( ; it != itEnd; ++it )
614 (*it)->d_ptr->setDefault();
618 void Page::deletePixmap( int id )
620 PagePrivate::PixmapObject object = d->m_pixmaps.take( id );
621 delete object.m_pixmap;
624 void Page::deletePixmaps()
626 QMapIterator< int, PagePrivate::PixmapObject > it( d->m_pixmaps );
627 while ( it.hasNext() ) {
628 it.next();
629 delete it.value().m_pixmap;
632 d->m_pixmaps.clear();
635 void Page::deleteRects()
637 // delete ObjectRects of type Link and Image
638 QSet<ObjectRect::ObjectType> which;
639 which << ObjectRect::Action << ObjectRect::Image;
640 deleteObjectRects( m_rects, which );
643 void PagePrivate::deleteHighlights( int s_id )
645 // delete highlights by ID
646 QLinkedList< HighlightAreaRect* >::iterator it = m_page->m_highlights.begin(), end = m_page->m_highlights.end();
647 while ( it != end )
649 HighlightAreaRect* highlight = *it;
650 if ( s_id == -1 || highlight->s_id == s_id )
652 it = m_page->m_highlights.erase( it );
653 delete highlight;
655 else
656 ++it;
660 void PagePrivate::deleteTextSelections()
662 delete m_textSelections;
663 m_textSelections = 0;
666 void Page::deleteSourceReferences()
668 deleteObjectRects( m_rects, QSet<ObjectRect::ObjectType>() << ObjectRect::SourceRef );
671 void Page::deleteAnnotations()
673 // delete ObjectRects of type Annotation
674 deleteObjectRects( m_rects, QSet<ObjectRect::ObjectType>() << ObjectRect::OAnnotation );
675 // delete all stored annotations
676 QLinkedList< Annotation * >::const_iterator aIt = m_annotations.begin(), aEnd = m_annotations.end();
677 for ( ; aIt != aEnd; ++aIt )
678 delete *aIt;
679 m_annotations.clear();
682 void PagePrivate::restoreLocalContents( const QDomNode & pageNode )
684 // iterate over all chilren (annotationList, ...)
685 QDomNode childNode = pageNode.firstChild();
686 while ( childNode.isElement() )
688 QDomElement childElement = childNode.toElement();
689 childNode = childNode.nextSibling();
691 // parse annotationList child element
692 if ( childElement.tagName() == "annotationList" )
694 #ifdef PAGE_PROFILE
695 QTime time;
696 time.start();
697 #endif
699 // iterate over all annotations
700 QDomNode annotationNode = childElement.firstChild();
701 while( annotationNode.isElement() )
703 // get annotation element and advance to next annot
704 QDomElement annotElement = annotationNode.toElement();
705 annotationNode = annotationNode.nextSibling();
707 // get annotation from the dom element
708 Annotation * annotation = AnnotationUtils::createAnnotation( annotElement );
710 // append annotation to the list or show warning
711 if ( annotation )
713 annotation->d_ptr->m_page = this;
714 m_page->m_annotations.append( annotation );
715 m_page->m_rects.append( new AnnotationObjectRect( annotation ) );
716 int pos = annotation->uniqueName().lastIndexOf("-");
717 if(pos != -1)
719 int uniqID=annotation->uniqueName().right(annotation->uniqueName().length()-pos-1).toInt();
720 if ( m_maxuniqueNum < uniqID )
721 m_maxuniqueNum = uniqID;
724 kDebug(OkularDebug) << "restored annot:" << annotation->uniqueName();
726 else
727 kWarning(OkularDebug).nospace() << "page (" << m_number << "): can't restore an annotation from XML.";
729 #ifdef PAGE_PROFILE
730 kDebug(OkularDebug).nospace() << "annots: XML Load time: " << time.elapsed() << "ms";
731 #endif
733 // parse formList child element
734 else if ( childElement.tagName() == "forms" )
736 if ( formfields.isEmpty() )
737 continue;
739 QHash<int, FormField*> hashedforms;
740 QLinkedList< FormField * >::const_iterator fIt = formfields.begin(), fItEnd = formfields.end();
741 for ( ; fIt != fItEnd; ++fIt )
743 hashedforms[(*fIt)->id()] = (*fIt);
746 // iterate over all forms
747 QDomNode formsNode = childElement.firstChild();
748 while( formsNode.isElement() )
750 // get annotation element and advance to next annot
751 QDomElement formElement = formsNode.toElement();
752 formsNode = formsNode.nextSibling();
754 if ( formElement.tagName() != "form" )
755 continue;
757 bool ok = true;
758 int index = formElement.attribute( "id" ).toInt( &ok );
759 if ( !ok )
760 continue;
762 QHash<int, FormField*>::const_iterator wantedIt = hashedforms.find( index );
763 if ( wantedIt == hashedforms.end() )
764 continue;
766 QString value = formElement.attribute( "value" );
767 (*wantedIt)->d_ptr->setValue( value );
773 void PagePrivate::saveLocalContents( QDomNode & parentNode, QDomDocument & document ) const
775 // only add a node if there is some stuff to write into
776 if ( m_page->m_annotations.isEmpty() && formfields.isEmpty() )
777 return;
779 // create the page node and set the 'number' attribute
780 QDomElement pageElement = document.createElement( "page" );
781 pageElement.setAttribute( "number", m_number );
783 #if 0
784 // add bookmark info if is bookmarked
785 if ( d->m_bookmarked )
787 // create the pageElement's 'bookmark' child
788 QDomElement bookmarkElement = document.createElement( "bookmark" );
789 pageElement.appendChild( bookmarkElement );
791 // add attributes to the element
792 //bookmarkElement.setAttribute( "name", bookmark name );
794 #endif
796 // add annotations info if has got any
797 if ( !m_page->m_annotations.isEmpty() )
799 // create the annotationList
800 QDomElement annotListElement = document.createElement( "annotationList" );
802 // add every annotation to the annotationList
803 QLinkedList< Annotation * >::const_iterator aIt = m_page->m_annotations.begin(), aEnd = m_page->m_annotations.end();
804 for ( ; aIt != aEnd; ++aIt )
806 // get annotation
807 const Annotation * a = *aIt;
808 // only save okular annotations (not the embedded in file ones)
809 if ( !(a->flags() & Annotation::External) )
811 // append an filled-up element called 'annotation' to the list
812 QDomElement annElement = document.createElement( "annotation" );
813 AnnotationUtils::storeAnnotation( a, annElement, document );
814 annotListElement.appendChild( annElement );
815 kDebug(OkularDebug) << "save annotation:" << a->uniqueName();
819 // append the annotationList element if annotations have been set
820 if ( annotListElement.hasChildNodes() )
821 pageElement.appendChild( annotListElement );
824 // add forms info if has got any
825 if ( !formfields.isEmpty() )
827 // create the formList
828 QDomElement formListElement = document.createElement( "forms" );
830 // add every form data to the formList
831 QLinkedList< FormField * >::const_iterator fIt = formfields.begin(), fItEnd = formfields.end();
832 for ( ; fIt != fItEnd; ++fIt )
834 // get the form field
835 const FormField * f = *fIt;
837 QString newvalue = f->d_ptr->value();
838 if ( f->d_ptr->m_default == newvalue )
839 continue;
841 // append an filled-up element called 'annotation' to the list
842 QDomElement formElement = document.createElement( "form" );
843 formElement.setAttribute( "id", f->id() );
844 formElement.setAttribute( "value", newvalue );
845 formListElement.appendChild( formElement );
848 // append the annotationList element if annotations have been set
849 if ( formListElement.hasChildNodes() )
850 pageElement.appendChild( formListElement );
853 // append the page element only if has children
854 if ( pageElement.hasChildNodes() )
855 parentNode.appendChild( pageElement );
858 const QPixmap * Page::_o_nearestPixmap( int pixID, int w, int h ) const
860 Q_UNUSED( h )
862 const QPixmap * pixmap = 0;
864 // if a pixmap is present for given id, use it
865 QMap< int, PagePrivate::PixmapObject >::const_iterator itPixmap = d->m_pixmaps.find( pixID );
866 if ( itPixmap != d->m_pixmaps.end() )
867 pixmap = itPixmap.value().m_pixmap;
868 // else find the closest match using pixmaps of other IDs (great optim!)
869 else if ( !d->m_pixmaps.isEmpty() )
871 int minDistance = -1;
872 QMap< int, PagePrivate::PixmapObject >::const_iterator it = d->m_pixmaps.begin(), end = d->m_pixmaps.end();
873 for ( ; it != end; ++it )
875 int pixWidth = (*it).m_pixmap->width(),
876 distance = pixWidth > w ? pixWidth - w : w - pixWidth;
877 if ( minDistance == -1 || distance < minDistance )
879 pixmap = (*it).m_pixmap;
880 minDistance = distance;
885 return pixmap;