From 0934b778b10a98f7b2eda6d137859447f5b66d35 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 2 Oct 2012 14:19:09 +0200 Subject: [PATCH] use the version of PagePainter from ui --- active/components/CMakeLists.txt | 3 +- active/components/pageitem.cpp | 2 +- active/components/pagepainter.cpp | 927 ------------------------------ active/components/pagepainter.h | 85 --- 4 files changed, 3 insertions(+), 1014 deletions(-) delete mode 100644 active/components/pagepainter.cpp delete mode 100644 active/components/pagepainter.h diff --git a/active/components/CMakeLists.txt b/active/components/CMakeLists.txt index 165d862be..fece81306 100644 --- a/active/components/CMakeLists.txt +++ b/active/components/CMakeLists.txt @@ -10,7 +10,8 @@ include_directories( set(okular_SRCS okularplugin.cpp - pagepainter.cpp + ${CMAKE_SOURCE_DIR}/ui/pagepainter.cpp + ${CMAKE_SOURCE_DIR}/ui/guiutils.cpp pageitem.cpp documentitem.cpp thumbnailitem.cpp diff --git a/active/components/pageitem.cpp b/active/components/pageitem.cpp index f1b0ca105..427f5eb9f 100644 --- a/active/components/pageitem.cpp +++ b/active/components/pageitem.cpp @@ -29,7 +29,7 @@ #include #include -#include "pagepainter.h" +#include "ui/pagepainter.h" #include "settings.h" #define REDRAW_TIMEOUT 250 diff --git a/active/components/pagepainter.cpp b/active/components/pagepainter.cpp deleted file mode 100644 index 8c1b41299..000000000 --- a/active/components/pagepainter.cpp +++ /dev/null @@ -1,927 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Enrico Ros * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - ***************************************************************************/ - -#include "pagepainter.h" - -// qt / kde includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// system includes -#include - -// local includes -#include "core/area.h" -#include "core/page.h" -#include "core/annotations.h" -#include "core/utils.h" -#include "settings.h" - -K_GLOBAL_STATIC_WITH_ARGS( QPixmap, busyPixmap, ( KIconLoader::global()->loadIcon("okular", KIconLoader::NoGroup, 32, KIconLoader::DefaultState, QStringList(), 0, true) ) ) - -#define TEXTANNOTATION_ICONSIZE 24 - -inline QPen buildPen( const Okular::Annotation *ann, double width, const QColor &color ) -{ - QPen p( - QBrush( color ), - width, - ann->style().lineStyle() == Okular::Annotation::Dashed ? Qt::DashLine : Qt::SolidLine, - Qt::SquareCap, - Qt::MiterJoin - ); - return p; -} - -void PagePainter::paintPageOnPainter( QPainter * destPainter, const Okular::Page * page, - int pixID, int flags, int scaledWidth, int scaledHeight, const QRect &limits ) -{ - paintCroppedPageOnPainter( destPainter, page, pixID, flags, scaledWidth, scaledHeight, limits, - Okular::NormalizedRect( 0, 0, 1, 1 ), 0 ); -} - -void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okular::Page * page, - int pixID, int flags, int scaledWidth, int scaledHeight, const QRect &limits, - const Okular::NormalizedRect &crop, Okular::NormalizedPoint *viewPortPoint ) -{ - /* Calculate the cropped geometry of the page */ - QRect scaledCrop = crop.geometry( scaledWidth, scaledHeight ); - int croppedWidth = scaledCrop.width(); - int croppedHeight = scaledCrop.height(); - - /** 1 - RETRIEVE THE 'PAGE+ID' PIXMAP OR A SIMILAR 'PAGE' ONE **/ - const QPixmap * pixmap = page->_o_nearestPixmap( pixID, scaledWidth, scaledHeight ); - - QColor color = Qt::white; - if ( Okular::Settings::changeColors() ) - { - switch ( Okular::Settings::renderMode() ) - { - case Okular::Settings::EnumRenderMode::Inverted: - color = Qt::black; - break; - case Okular::Settings::EnumRenderMode::Paper: - color = Okular::Settings::paperColor(); - break; - case Okular::Settings::EnumRenderMode::Recolor: - color = Okular::Settings::recolorBackground(); - break; - default: ; - } - } - destPainter->fillRect( limits, color ); - - /** 1B - IF NO PIXMAP, DRAW EMPTY PAGE **/ - double pixmapRescaleRatio = pixmap ? scaledWidth / (double)pixmap->width() : -1; - long pixmapPixels = pixmap ? (long)pixmap->width() * (long)pixmap->height() : 0; - if ( !pixmap || pixmapRescaleRatio > 20.0 || pixmapRescaleRatio < 0.25 || - (scaledWidth != pixmap->width() && pixmapPixels > 6000000L) ) - { - // draw something on the blank page: the okular icon or a cross (as a fallback) - if ( !busyPixmap->isNull() ) - { - destPainter->drawPixmap( QPoint( 10, 10 ), *busyPixmap ); - } - else - { - destPainter->setPen( Qt::gray ); - destPainter->drawLine( 0, 0, croppedWidth-1, croppedHeight-1 ); - destPainter->drawLine( 0, croppedHeight-1, croppedWidth-1, 0 ); - } - return; - } - - /** 2 - FIND OUT WHAT TO PAINT (Flags + Configuration + Presence) **/ - bool canDrawHighlights = (flags & Highlights) && !page->m_highlights.isEmpty(); - bool canDrawTextSelection = (flags & TextSelection) && page->textSelection(); - bool canDrawAnnotations = (flags & Annotations) && !page->m_annotations.isEmpty(); - bool enhanceLinks = (flags & EnhanceLinks) && Okular::Settings::highlightLinks(); - bool enhanceImages = (flags & EnhanceImages) && Okular::Settings::highlightImages(); - // vectors containing objects to draw - // make this a qcolor, rect map, since we don't need - // to know s_id here! we are only drawing this right? - QList< QPair > * bufferedHighlights = 0; - QList< Okular::Annotation * > * bufferedAnnotations = 0; - QList< Okular::Annotation * > * unbufferedAnnotations = 0; - // fill up lists with visible annotation/highlight objects/text selections - if ( canDrawHighlights || canDrawTextSelection || canDrawAnnotations ) - { - // precalc normalized 'limits rect' for intersection - double nXMin = ( (double)limits.left() / (double)scaledWidth ) + crop.left, - nXMax = ( (double)limits.right() / (double)scaledWidth ) + crop.left, - nYMin = ( (double)limits.top() / (double)scaledHeight ) + crop.top, - nYMax = ( (double)limits.bottom() / (double)scaledHeight ) + crop.top; - // append all highlights inside limits to their list - if ( canDrawHighlights ) - { - if ( !bufferedHighlights ) - bufferedHighlights = new QList< QPair >(); -/* else - {*/ - - Okular::NormalizedRect* limitRect = new Okular::NormalizedRect(nXMin, nYMin, nXMax, nYMax ); - QLinkedList< Okular::HighlightAreaRect * >::const_iterator h2It = page->m_highlights.constBegin(), hEnd = page->m_highlights.constEnd(); - Okular::HighlightAreaRect::const_iterator hIt; - for ( ; h2It != hEnd; ++h2It ) - for (hIt=(*h2It)->constBegin(); hIt!=(*h2It)->constEnd(); ++hIt) - { - if ((*hIt).intersects(limitRect)) - bufferedHighlights->append( qMakePair((*h2It)->color,*hIt) ); - } - delete limitRect; - //} - } - if ( canDrawTextSelection ) - { - if ( !bufferedHighlights ) - bufferedHighlights = new QList< QPair >(); -/* else - {*/ - Okular::NormalizedRect* limitRect = new Okular::NormalizedRect(nXMin, nYMin, nXMax, nYMax ); - const Okular::RegularAreaRect *textSelection = page->textSelection(); - Okular::HighlightAreaRect::const_iterator hIt = textSelection->constBegin(), hEnd = textSelection->constEnd(); - for ( ; hIt != hEnd; ++hIt ) - { - if ( (*hIt).intersects( limitRect ) ) - bufferedHighlights->append( qMakePair( page->textSelectionColor(), *hIt ) ); - } - delete limitRect; - //} - } - // append annotations inside limits to the un/buffered list - if ( canDrawAnnotations ) - { - QLinkedList< Okular::Annotation * >::const_iterator aIt = page->m_annotations.constBegin(), aEnd = page->m_annotations.constEnd(); - for ( ; aIt != aEnd; ++aIt ) - { - Okular::Annotation * ann = *aIt; - if ( ann->flags() & ( Okular::Annotation::Hidden | Okular::Annotation::ExternallyDrawn ) ) - continue; - - bool intersects = ann->transformedBoundingRectangle().intersects( nXMin, nYMin, nXMax, nYMax ); - if ( ann->subType() == Okular::Annotation::AText ) - { - Okular::TextAnnotation * ta = static_cast< Okular::TextAnnotation * >( ann ); - if ( ta->textType() == Okular::TextAnnotation::Linked ) - { - Okular::NormalizedRect iconrect( ann->transformedBoundingRectangle().left, - ann->transformedBoundingRectangle().top, - ann->transformedBoundingRectangle().left + TEXTANNOTATION_ICONSIZE / page->width(), - ann->transformedBoundingRectangle().top + TEXTANNOTATION_ICONSIZE / page->height() ); - intersects = iconrect.intersects( nXMin, nYMin, nXMax, nYMax ); - } - } - if ( intersects ) - { - Okular::Annotation::SubType type = ann->subType(); - if ( type == Okular::Annotation::ALine || type == Okular::Annotation::AHighlight || - type == Okular::Annotation::AInk /*|| (type == Annotation::AGeom && ann->style().opacity() < 0.99)*/ ) - { - if ( !bufferedAnnotations ) - bufferedAnnotations = new QList< Okular::Annotation * >(); - bufferedAnnotations->append( ann ); - } - else - { - if ( !unbufferedAnnotations ) - unbufferedAnnotations = new QList< Okular::Annotation * >(); - unbufferedAnnotations->append( ann ); - } - } - } - } - // end of intersections checking - } - - /** 3 - ENABLE BACKBUFFERING IF DIRECT IMAGE MANIPULATION IS NEEDED **/ - bool bufferAccessibility = (flags & Accessibility) && Okular::Settings::changeColors() && (Okular::Settings::renderMode() != Okular::Settings::EnumRenderMode::Paper); - bool useBackBuffer = bufferAccessibility || bufferedHighlights || bufferedAnnotations || viewPortPoint; - QPixmap * backPixmap = 0; - QPainter * mixedPainter = 0; - QRect limitsInPixmap = limits.translated( crop.geometry( scaledWidth, scaledHeight ).topLeft() ); - // limits within full (scaled but uncropped) pixmap - - /** 4A -- REGULAR FLOW. PAINT PIXMAP NORMAL OR RESCALED USING GIVEN QPAINTER **/ - if ( !useBackBuffer ) - { - // 4A.1. if size is ok, draw the page pixmap using painter - if ( pixmap->width() == scaledWidth && pixmap->height() == scaledHeight ) - destPainter->drawPixmap( limits.topLeft(), *pixmap, limitsInPixmap ); - - // else draw a scaled portion of the magnified pixmap - else - { - QImage destImage; - scalePixmapOnImage( destImage, pixmap, scaledWidth, scaledHeight, limitsInPixmap ); - destPainter->drawImage( limits.left(), limits.top(), destImage, 0, 0, - limits.width(),limits.height() ); - } - - // 4A.2. active painter is the one passed to this method - mixedPainter = destPainter; - } - /** 4B -- BUFFERED FLOW. IMAGE PAINTING + OPERATIONS. QPAINTER OVER PIXMAP **/ - else - { - // the image over which we are going to draw - QImage backImage; - bool has_alpha = pixmap->hasAlpha(); - - // 4B.1. draw the page pixmap: normal or scaled - if ( pixmap->width() == scaledWidth && pixmap->height() == scaledHeight ) - cropPixmapOnImage( backImage, pixmap, limitsInPixmap ); - else - scalePixmapOnImage( backImage, pixmap, scaledWidth, scaledHeight, limitsInPixmap ); - - // 4B.2. modify pixmap following accessibility settings - if ( bufferAccessibility ) - { - switch ( Okular::Settings::renderMode() ) - { - case Okular::Settings::EnumRenderMode::Inverted: - // Invert image pixels using QImage internal function - backImage.invertPixels(QImage::InvertRgb); - break; - case Okular::Settings::EnumRenderMode::Recolor: - // Recolor image using Blitz::flatten with dither:0 - Blitz::flatten( backImage, Okular::Settings::recolorForeground(), Okular::Settings::recolorBackground() ); - break; - case Okular::Settings::EnumRenderMode::BlackWhite: - // Manual Gray and Contrast - unsigned int * data = (unsigned int *)backImage.bits(); - int val, pixels = backImage.width() * backImage.height(), - con = Okular::Settings::bWContrast(), thr = 255 - Okular::Settings::bWThreshold(); - for( int i = 0; i < pixels; ++i ) - { - val = qGray( data[i] ); - if ( val > thr ) - val = 128 + (127 * (val - thr)) / (255 - thr); - else if ( val < thr ) - val = (128 * val) / thr; - if ( con > 2 ) - { - val = con * ( val - thr ) / 2 + thr; - if ( val > 255 ) - val = 255; - else if ( val < 0 ) - val = 0; - } - data[i] = qRgba( val, val, val, 255 ); - } - break; - } - } - // 4B.3. highlight rects in page - if ( bufferedHighlights ) - { - // draw highlights that are inside the 'limits' paint region - QList< QPair >::const_iterator hIt = bufferedHighlights->constBegin(), hEnd = bufferedHighlights->constEnd(); - for ( ; hIt != hEnd; ++hIt ) - { - const Okular::NormalizedRect & r = (*hIt).second; - // find out the rect to highlight on pixmap - QRect highlightRect = r.geometry( scaledWidth, scaledHeight ).translated( -scaledCrop.topLeft() ).intersect( limits ); - highlightRect.translate( -limits.left(), -limits.top() ); - - // highlight composition (product: highlight color * destcolor) - unsigned int * data = (unsigned int *)backImage.bits(); - int val, newR, newG, newB, - rh = (*hIt).first.red(), - gh = (*hIt).first.green(), - bh = (*hIt).first.blue(), - offset = highlightRect.top() * backImage.width(); - for( int y = highlightRect.top(); y <= highlightRect.bottom(); ++y ) - { - for( int x = highlightRect.left(); x <= highlightRect.right(); ++x ) - { - val = data[ x + offset ]; - //for odt or epub - if(has_alpha) - { - newR = qRed(val); - newG = qGreen(val); - newB = qBlue(val); - - if(newR == newG && newG == newB && newR == 0) - newR = newG = newB = 255; - - newR = (newR * rh) / 255; - newG = (newG * gh) / 255; - newB = (newB * bh) / 255; - } - else - { - newR = (qRed(val) * rh) / 255; - newG = (qGreen(val) * gh) / 255; - newB = (qBlue(val) * bh) / 255; - } - data[ x + offset ] = qRgba( newR, newG, newB, 255 ); - } - offset += backImage.width(); - } - } - } - // 4B.4. paint annotations [COMPOSITED ONES] - if ( bufferedAnnotations ) - { - // Albert: This is quite "heavy" but all the backImage that reach here are QImage::Format_ARGB32_Premultiplied - // and have to be so that the QPainter::CompositionMode_Multiply works - // we could also put a - // backImage = backImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) - // that would be almost a noop, but we'll leave the assert for now - Q_ASSERT(backImage.format() == QImage::Format_ARGB32_Premultiplied); - // precalc constants for normalizing [0,1] page coordinates into normalized [0,1] limit rect coordinates - double pageScale = (double)croppedWidth / page->width(); - double xOffset = (double)limits.left() / (double)scaledWidth + crop.left, - xScale = (double)scaledWidth / (double)limits.width(), - yOffset = (double)limits.top() / (double)scaledHeight + crop.top, - yScale = (double)scaledHeight / (double)limits.height(); - - // paint all buffered annotations in the page - QList< Okular::Annotation * >::const_iterator aIt = bufferedAnnotations->constBegin(), aEnd = bufferedAnnotations->constEnd(); - for ( ; aIt != aEnd; ++aIt ) - { - Okular::Annotation * a = *aIt; - Okular::Annotation::SubType type = a->subType(); - QColor acolor = a->style().color(); - if ( !acolor.isValid() ) - acolor = Qt::yellow; - acolor.setAlphaF( a->style().opacity() ); - - // draw LineAnnotation MISSING: all - if ( type == Okular::Annotation::ALine ) - { - // get the annotation - Okular::LineAnnotation * la = (Okular::LineAnnotation *) a; - - NormalizedPath path; - // normalize page point to image - const QLinkedList points = la->transformedLinePoints(); - QLinkedList::const_iterator it = points.constBegin(); - QLinkedList::const_iterator itEnd = points.constEnd(); - for ( ; it != itEnd; ++it ) - { - Okular::NormalizedPoint point; - point.x = ( (*it).x - xOffset) * xScale; - point.y = ( (*it).y - yOffset) * yScale; - path.append( point ); - } - - const QPen linePen = buildPen( a, a->style().width(), a->style().color() ); - - // draw the line as normalized path into image - drawShapeOnImage( backImage, path, la->lineClosed(), - linePen, - QBrush(), pageScale ,Multiply); - - if ( path.count() == 2 && fabs( la->lineLeadingForwardPoint() ) > 0.1 ) - { - Okular::NormalizedPoint delta( la->transformedLinePoints().last().x - la->transformedLinePoints().first().x, la->transformedLinePoints().first().y - la->transformedLinePoints().last().y ); - double angle = atan2( delta.y, delta.x ); - if ( delta.y < 0 ) - angle += 2 * M_PI; - - int sign = la->lineLeadingForwardPoint() > 0.0 ? 1 : -1; - double LLx = fabs( la->lineLeadingForwardPoint() ) * cos( angle + sign * M_PI_2 + 2 * M_PI ) / page->width(); - double LLy = fabs( la->lineLeadingForwardPoint() ) * sin( angle + sign * M_PI_2 + 2 * M_PI ) / page->height(); - - NormalizedPath path2; - NormalizedPath path3; - - Okular::NormalizedPoint point; - point.x = ( la->transformedLinePoints().first().x + LLx - xOffset ) * xScale; - point.y = ( la->transformedLinePoints().first().y - LLy - yOffset ) * yScale; - path2.append( point ); - point.x = ( la->transformedLinePoints().last().x + LLx - xOffset ) * xScale; - point.y = ( la->transformedLinePoints().last().y - LLy - yOffset ) * yScale; - path3.append( point ); - // do we have the extension on the "back"? - if ( fabs( la->lineLeadingBackwardPoint() ) > 0.1 ) - { - double LLEx = la->lineLeadingBackwardPoint() * cos( angle - sign * M_PI_2 + 2 * M_PI ) / page->width(); - double LLEy = la->lineLeadingBackwardPoint() * sin( angle - sign * M_PI_2 + 2 * M_PI ) / page->height(); - point.x = ( la->transformedLinePoints().first().x + LLEx - xOffset ) * xScale; - point.y = ( la->transformedLinePoints().first().y - LLEy - yOffset ) * yScale; - path2.append( point ); - point.x = ( la->transformedLinePoints().last().x + LLEx - xOffset ) * xScale; - point.y = ( la->transformedLinePoints().last().y - LLEy - yOffset ) * yScale; - path3.append( point ); - } - else - { - path2.append( path[0] ); - path3.append( path[1] ); - } - - drawShapeOnImage( backImage, path2, false, linePen, QBrush(), pageScale, Multiply ); - drawShapeOnImage( backImage, path3, false, linePen, QBrush(), pageScale, Multiply ); - } - } - // draw HighlightAnnotation MISSING: under/strike width, feather, capping - else if ( type == Okular::Annotation::AHighlight ) - { - // get the annotation - Okular::HighlightAnnotation * ha = (Okular::HighlightAnnotation *) a; - Okular::HighlightAnnotation::HighlightType type = ha->highlightType(); - - // draw each quad of the annotation - int quads = ha->highlightQuads().size(); - for ( int q = 0; q < quads; q++ ) - { - NormalizedPath path; - const Okular::HighlightAnnotation::Quad & quad = ha->highlightQuads()[ q ]; - // normalize page point to image - for ( int i = 0; i < 4; i++ ) - { - Okular::NormalizedPoint point; - point.x = (quad.transformedPoint( i ).x - xOffset) * xScale; - point.y = (quad.transformedPoint( i ).y - yOffset) * yScale; - path.append( point ); - } - // draw the normalized path into image - switch ( type ) - { - // highlight the whole rect - case Okular::HighlightAnnotation::Highlight: - drawShapeOnImage( backImage, path, true, Qt::NoPen, acolor, pageScale, Multiply ); - break; - // highlight the bottom part of the rect - case Okular::HighlightAnnotation::Squiggly: - path[ 3 ].x = ( path[ 0 ].x + path[ 3 ].x ) / 2.0; - path[ 3 ].y = ( path[ 0 ].y + path[ 3 ].y ) / 2.0; - path[ 2 ].x = ( path[ 1 ].x + path[ 2 ].x ) / 2.0; - path[ 2 ].y = ( path[ 1 ].y + path[ 2 ].y ) / 2.0; - drawShapeOnImage( backImage, path, true, Qt::NoPen, acolor, pageScale, Multiply ); - break; - // make a line at 3/4 of the height - case Okular::HighlightAnnotation::Underline: - path[ 0 ].x = ( 3 * path[ 0 ].x + path[ 3 ].x ) / 4.0; - path[ 0 ].y = ( 3 * path[ 0 ].y + path[ 3 ].y ) / 4.0; - path[ 1 ].x = ( 3 * path[ 1 ].x + path[ 2 ].x ) / 4.0; - path[ 1 ].y = ( 3 * path[ 1 ].y + path[ 2 ].y ) / 4.0; - path.pop_back(); - path.pop_back(); - drawShapeOnImage( backImage, path, false, QPen( acolor, 2 ), QBrush(), pageScale ); - break; - // make a line at 1/2 of the height - case Okular::HighlightAnnotation::StrikeOut: - path[ 0 ].x = ( path[ 0 ].x + path[ 3 ].x ) / 2.0; - path[ 0 ].y = ( path[ 0 ].y + path[ 3 ].y ) / 2.0; - path[ 1 ].x = ( path[ 1 ].x + path[ 2 ].x ) / 2.0; - path[ 1 ].y = ( path[ 1 ].y + path[ 2 ].y ) / 2.0; - path.pop_back(); - path.pop_back(); - drawShapeOnImage( backImage, path, false, QPen( acolor, 2 ), QBrush(), pageScale ); - break; - } - } - } - // draw InkAnnotation MISSING:invar width, PENTRACER - else if ( type == Okular::Annotation::AInk ) - { - // get the annotation - Okular::InkAnnotation * ia = (Okular::InkAnnotation *) a; - - // draw each ink path - const QList< QLinkedList > transformedInkPaths = ia->transformedInkPaths(); - - const QPen inkPen = buildPen( a, a->style().width(), acolor ); - - int paths = transformedInkPaths.size(); - for ( int p = 0; p < paths; p++ ) - { - NormalizedPath path; - const QLinkedList & inkPath = transformedInkPaths[ p ]; - - // normalize page point to image - QLinkedList::const_iterator pIt = inkPath.constBegin(), pEnd = inkPath.constEnd(); - for ( ; pIt != pEnd; ++pIt ) - { - const Okular::NormalizedPoint & inkPoint = *pIt; - Okular::NormalizedPoint point; - point.x = (inkPoint.x - xOffset) * xScale; - point.y = (inkPoint.y - yOffset) * yScale; - path.append( point ); - } - // draw the normalized path into image - drawShapeOnImage( backImage, path, false, inkPen, QBrush(), pageScale ); - } - } - } // end current annotation drawing - } - - if(viewPortPoint) - { - QPainter painter(&backImage); - painter.translate( -limits.left(), -limits.top() ); - painter.setPen( QApplication::palette().color( QPalette::Active, QPalette::Highlight ) ); - painter.drawLine( 0, viewPortPoint->y * scaledHeight + 1, scaledWidth - 1, viewPortPoint->y * scaledHeight + 1 ); -// ROTATION CURRENTLY NOT IMPLEMENTED -/* - if( page->rotation() == Okular::Rotation0) - { - - } - else if(page->rotation() == Okular::Rotation270) - { - painter.drawLine( viewPortPoint->y * scaledHeight + 1, 0, viewPortPoint->y * scaledHeight + 1, scaledWidth - 1); - } - else if(page->rotation() == Okular::Rotation180) - { - painter.drawLine( 0, (1.0 - viewPortPoint->y) * scaledHeight - 1, scaledWidth - 1, (1.0 - viewPortPoint->y) * scaledHeight - 1 ); - } - else if(page->rotation() == Okular::Rotation90) // not right, rotation clock-wise - { - painter.drawLine( scaledWidth - (viewPortPoint->y * scaledHeight + 1), 0, scaledWidth - (viewPortPoint->y * scaledHeight + 1), scaledWidth - 1); - } -*/ - } - - // 4B.5. create the back pixmap converting from the local image - backPixmap = new QPixmap( QPixmap::fromImage( backImage ) ); - - // 4B.6. create a painter over the pixmap and set it as the active one - mixedPainter = new QPainter( backPixmap ); - mixedPainter->translate( -limits.left(), -limits.top() ); - } - - /** 5 -- MIXED FLOW. Draw ANNOTATIONS [OPAQUE ONES] on ACTIVE PAINTER **/ - if ( unbufferedAnnotations ) - { - // iterate over annotations and paint AText, AGeom, AStamp - QList< Okular::Annotation * >::const_iterator aIt = unbufferedAnnotations->constBegin(), aEnd = unbufferedAnnotations->constEnd(); - for ( ; aIt != aEnd; ++aIt ) - { - Okular::Annotation * a = *aIt; - - // honor opacity settings on supported types - unsigned int opacity = (unsigned int)( 255.0 * a->style().opacity() ); - // skip the annotation drawing if all the annotation is fully - // transparent, but not with text annotations - if ( opacity <= 0 && a->subType() != Okular::Annotation::AText ) - continue; - - QColor acolor = a->style().color(); - if ( !acolor.isValid() ) - acolor = Qt::yellow; - acolor.setAlpha( opacity ); - - // get annotation boundary and drawn rect - QRect annotBoundary = a->transformedBoundingRectangle().geometry( scaledWidth, scaledHeight ).translated( -scaledCrop.topLeft() ); - QRect annotRect = annotBoundary.intersect( limits ); - QRect innerRect( annotRect.left() - annotBoundary.left(), annotRect.top() - - annotBoundary.top(), annotRect.width(), annotRect.height() ); - - Okular::Annotation::SubType type = a->subType(); - - // draw TextAnnotation - if ( type == Okular::Annotation::AText ) - { - Okular::TextAnnotation * text = (Okular::TextAnnotation *)a; - if ( text->textType() == Okular::TextAnnotation::InPlace ) - { - QImage image( annotBoundary.size(), QImage::Format_ARGB32 ); - image.fill( acolor.rgba() ); - QPainter painter( &image ); - painter.setPen( Qt::black ); - painter.setFont( text->textFont() ); - Qt::AlignmentFlag halign = ( text->inplaceAlignment() == 1 ? Qt::AlignHCenter : ( text->inplaceAlignment() == 2 ? Qt::AlignRight : Qt::AlignLeft ) ); - painter.scale( 1.0 * scaledWidth / page->width(), 1.0 * scaledHeight / page->height() ); - painter.drawText( 2, 2, image.width() - 2, image.height() - 2, - Qt::AlignTop | halign | Qt::TextWordWrap, - text->inplaceText() ); - painter.resetTransform(); - painter.drawRect( 0, 0, image.width() - 1, image.height() - 1 ); - painter.end(); - - mixedPainter->drawImage( annotBoundary.topLeft(), image ); - } - else if ( text->textType() == Okular::TextAnnotation::Linked ) - {/* - // get pixmap, colorize and alpha-blend it - QString path; - QPixmap pixmap = GuiUtils::iconLoader()->loadIcon( text->textIcon().toLower(), KIconLoader::User, 32, KIconLoader::DefaultState, QStringList(), &path, true ); - if ( path.isEmpty() ) - pixmap = GuiUtils::iconLoader()->loadIcon( text->textIcon().toLower(), KIconLoader::NoGroup, 32 ); - QImage scaledImage; - QRect annotBoundary2 = QRect( annotBoundary.topLeft(), QSize( TEXTANNOTATION_ICONSIZE, TEXTANNOTATION_ICONSIZE ) ); - QRect annotRect2 = annotBoundary2.intersect( limits ); - QRect innerRect2( annotRect2.left() - annotBoundary2.left(), annotRect2.top() - - annotBoundary2.top(), annotRect2.width(), annotRect2.height() ); - scalePixmapOnImage( scaledImage, &pixmap, - TEXTANNOTATION_ICONSIZE, TEXTANNOTATION_ICONSIZE, - innerRect2, QImage::Format_ARGB32 ); - // if the annotation color is valid (ie it was set), then - // use it to colorize the icon, otherwise the icon will be - // "gray" - if ( a->style().color().isValid() ) - colorizeImage( scaledImage, a->style().color(), opacity ); - pixmap = QPixmap::fromImage( scaledImage ); - - // draw the mangled image to painter - mixedPainter->drawPixmap( annotRect.topLeft(), pixmap );*/ - } - - } - // draw StampAnnotation - else if ( type == Okular::Annotation::AStamp ) - { - Okular::StampAnnotation * stamp = (Okular::StampAnnotation *)a; - - // get pixmap and alpha blend it if needed - /*QPixmap pixmap = GuiUtils::loadStamp( stamp->stampIconName(), annotBoundary.size() ); - if ( !pixmap.isNull() ) // should never happen but can happen on huge sizes - { - QImage scaledImage; - scalePixmapOnImage( scaledImage, &pixmap, annotBoundary.width(), - annotBoundary.height(), innerRect, QImage::Format_ARGB32 ); - if ( opacity < 255 ) - changeImageAlpha( scaledImage, opacity ); - pixmap = QPixmap::fromImage( scaledImage ); - - // draw the scaled and al - mixedPainter->drawPixmap( annotRect.topLeft(), pixmap ); - }*/ - } - // draw GeomAnnotation - else if ( type == Okular::Annotation::AGeom ) - { - Okular::GeomAnnotation * geom = (Okular::GeomAnnotation *)a; - // check whether there's anything to draw - if ( geom->style().width() || geom->geometricalInnerColor().isValid() ) - { - mixedPainter->save(); - const double width = geom->style().width() * Okular::Utils::dpiX() / ( 72.0 * 2.0 ) * scaledWidth / page->width(); - QRectF r( .0, .0, annotBoundary.width(), annotBoundary.height() ); - r.adjust( width, width, -width, -width ); - r.translate( annotBoundary.topLeft() ); - if ( geom->geometricalInnerColor().isValid() ) - { - r.adjust( width, width, -width, -width ); - const QColor color = geom->geometricalInnerColor(); - mixedPainter->setPen( Qt::NoPen ); - mixedPainter->setBrush( QColor( color.red(), color.green(), color.blue(), opacity ) ); - if ( geom->geometricalType() == Okular::GeomAnnotation::InscribedSquare ) - mixedPainter->drawRect( r ); - else - mixedPainter->drawEllipse( r ); - r.adjust( -width, -width, width, width ); - } - if ( geom->style().width() ) // need to check the original size here.. - { - mixedPainter->setPen( buildPen( a, width * 2, acolor ) ); - mixedPainter->setBrush( Qt::NoBrush ); - if ( geom->geometricalType() == Okular::GeomAnnotation::InscribedSquare ) - mixedPainter->drawRect( r ); - else - mixedPainter->drawEllipse( r ); - } - mixedPainter->restore(); - } - } - - // draw extents rectangle - if ( Okular::Settings::debugDrawAnnotationRect() ) - { - mixedPainter->setPen( a->style().color() ); - mixedPainter->drawRect( annotBoundary ); - } - } - } - - /** 6 -- MIXED FLOW. Draw LINKS+IMAGES BORDER on ACTIVE PAINTER **/ - if ( enhanceLinks || enhanceImages ) - { - mixedPainter->save(); - mixedPainter->scale( scaledWidth, scaledHeight ); - mixedPainter->translate( -crop.left, -crop.top ); - - QColor normalColor = QApplication::palette().color( QPalette::Active, QPalette::Highlight ); - // enlarging limits for intersection is like growing the 'rectGeometry' below - QRect limitsEnlarged = limits; - limitsEnlarged.adjust( -2, -2, 2, 2 ); - // draw rects that are inside the 'limits' paint region as opaque rects - QLinkedList< Okular::ObjectRect * >::const_iterator lIt = page->m_rects.constBegin(), lEnd = page->m_rects.constEnd(); - for ( ; lIt != lEnd; ++lIt ) - { - Okular::ObjectRect * rect = *lIt; - if ( (enhanceLinks && rect->objectType() == Okular::ObjectRect::Action) || - (enhanceImages && rect->objectType() == Okular::ObjectRect::Image) ) - { - if ( limitsEnlarged.intersects( rect->boundingRect( scaledWidth, scaledHeight ).translated( -scaledCrop.topLeft() ) ) ) - { - mixedPainter->strokePath( rect->region(), QPen( normalColor ) ); - } - } - } - mixedPainter->restore(); - } - - /** 7 -- BUFFERED FLOW. Copy BACKPIXMAP on DESTINATION PAINTER **/ - if ( useBackBuffer ) - { - delete mixedPainter; - destPainter->drawPixmap( limits.left(), limits.top(), *backPixmap ); - delete backPixmap; - } - - // delete object containers - delete bufferedHighlights; - delete bufferedAnnotations; - delete unbufferedAnnotations; -} - - -/** Private Helpers :: Pixmap conversion **/ -void PagePainter::cropPixmapOnImage( QImage & dest, const QPixmap * src, const QRect & r ) -{ - // handle quickly the case in which the whole pixmap has to be converted - if ( r == QRect( 0, 0, src->width(), src->height() ) ) - { - dest = src->toImage(); - dest = dest.convertToFormat(QImage::Format_ARGB32_Premultiplied); - } - // else copy a portion of the src to an internal pixmap (smaller) and convert it - else - { - QImage croppedImage( r.width(), r.height(), QImage::Format_ARGB32_Premultiplied ); - QPainter p( &croppedImage ); - p.drawPixmap( 0, 0, *src, r.left(), r.top(), r.width(), r.height() ); - p.end(); - dest = croppedImage; - } -} - -void PagePainter::scalePixmapOnImage ( QImage & dest, const QPixmap * src, - int scaledWidth, int scaledHeight, const QRect & cropRect, QImage::Format format ) -{ - // {source, destination, scaling} params - int srcWidth = src->width(), - srcHeight = src->height(), - destLeft = cropRect.left(), - destTop = cropRect.top(), - destWidth = cropRect.width(), - destHeight = cropRect.height(); - - // destination image (same geometry as the pageLimits rect) - dest = QImage( destWidth, destHeight, format ); - unsigned int * destData = (unsigned int *)dest.bits(); - - // source image (1:1 conversion from pixmap) - QImage srcImage = src->toImage().convertToFormat(format); - unsigned int * srcData = (unsigned int *)srcImage.bits(); - - // precalc the x correspondancy conversion in a lookup table - QVarLengthArray xOffset( destWidth ); - for ( int x = 0; x < destWidth; x++ ) - xOffset[ x ] = ((x + destLeft) * srcWidth) / scaledWidth; - - // for each pixel of the destination image apply the color of the - // corresponsing pixel on the source image (note: keep parenthesis) - for ( int y = 0; y < destHeight; y++ ) - { - unsigned int srcOffset = srcWidth * (((destTop + y) * srcHeight) / scaledHeight); - for ( int x = 0; x < destWidth; x++ ) - (*destData++) = srcData[ srcOffset + xOffset[x] ]; - } -} - -/** Private Helpers :: Image Drawing **/ -// from Arthur - qt4 -inline int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; } - -void PagePainter::changeImageAlpha( QImage & image, unsigned int destAlpha ) -{ - // iterate over all pixels changing the alpha component value - unsigned int * data = (unsigned int *)image.bits(); - unsigned int pixels = image.width() * image.height(); - - int source, sourceAlpha; - for( register unsigned int i = 0; i < pixels; ++i ) - { // optimize this loop keeping byte order into account - source = data[i]; - if ( (sourceAlpha = qAlpha( source )) == 255 ) - { - // use destAlpha - data[i] = qRgba( qRed(source), qGreen(source), qBlue(source), destAlpha ); - } - else - { - // use destAlpha * sourceAlpha product - sourceAlpha = qt_div_255( destAlpha * sourceAlpha ); - data[i] = qRgba( qRed(source), qGreen(source), qBlue(source), sourceAlpha ); - } - } -} - -void PagePainter::colorizeImage( QImage & grayImage, const QColor & color, - unsigned int destAlpha ) -{ - // iterate over all pixels changing the alpha component value - unsigned int * data = (unsigned int *)grayImage.bits(); - unsigned int pixels = grayImage.width() * grayImage.height(); - int red = color.red(), - green = color.green(), - blue = color.blue(); - - int source, sourceSat, sourceAlpha; - for( register unsigned int i = 0; i < pixels; ++i ) - { // optimize this loop keeping byte order into account - source = data[i]; - sourceSat = qRed( source ); - int newR = qt_div_255( sourceSat * red ), - newG = qt_div_255( sourceSat * green ), - newB = qt_div_255( sourceSat * blue ); - if ( (sourceAlpha = qAlpha( source )) == 255 ) - { - // use destAlpha - data[i] = qRgba( newR, newG, newB, destAlpha ); - } - else - { - // use destAlpha * sourceAlpha product - if ( destAlpha < 255 ) - sourceAlpha = qt_div_255( destAlpha * sourceAlpha ); - data[i] = qRgba( newR, newG, newB, sourceAlpha ); - } - } -} - -void PagePainter::drawShapeOnImage( - QImage & image, - const NormalizedPath & normPath, - bool closeShape, - const QPen & pen, - const QBrush & brush, - double penWidthMultiplier, - RasterOperation op - //float antiAliasRadius - ) -{ - // safety checks - int pointsNumber = normPath.size(); - if ( pointsNumber < 2 ) - return; - - int imageWidth = image.width(); - int imageHeight = image.height(); - double fImageWidth = (double)imageWidth; - double fImageHeight = (double)imageHeight; - - // stroke outline - double penWidth = (double)pen.width() * penWidthMultiplier; - QPainter painter(&image); - painter.setRenderHint(QPainter::Antialiasing); - QPen pen2 = pen; - pen2.setWidthF(penWidth); - painter.setPen(pen2); - painter.setBrush(brush); - - if (op == Multiply) { - painter.setCompositionMode(QPainter::CompositionMode_Multiply); - } - - if ( brush.style() == Qt::NoBrush ) - { - // create a polygon - QPolygonF poly( closeShape ? pointsNumber + 1 : pointsNumber ); - for ( int i = 0; i < pointsNumber; ++i ) - { - poly[ i ] = QPointF( normPath[ i ].x * fImageWidth, normPath[ i ].y * fImageHeight ); - } - if ( closeShape ) - poly[ pointsNumber ] = poly[ 0 ]; - - painter.drawPolyline( poly ); - } - else - { - // create a 'path' - QPainterPath path; - path.moveTo( normPath[ 0 ].x * fImageWidth, normPath[ 0 ].y * fImageHeight ); - for ( int i = 1; i < pointsNumber; i++ ) - { - path.lineTo( normPath[ i ].x * fImageWidth, normPath[ i ].y * fImageHeight ); - } - if ( closeShape ) - path.closeSubpath(); - - painter.drawPath( path ); - } -} - -/* kate: replace-tabs on; indent-width 4; */ - diff --git a/active/components/pagepainter.h b/active/components/pagepainter.h deleted file mode 100644 index 42a73130f..000000000 --- a/active/components/pagepainter.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Enrico Ros * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - ***************************************************************************/ - -#ifndef _OKULAR_PAGEPAINTER_H_ -#define _OKULAR_PAGEPAINTER_H_ - -#include -#include -#include - -#include "core/area.h" // for NormalizedPoint - -class QPainter; -class QRect; -namespace Okular { - class Page; -} - -/** - * @short Paints a Okular::Page to an open painter using given flags. - */ -class PagePainter -{ - public: - // list of flags passed to the painting function. by OR-ing those flags - // you can decide whether or not to permit drawing of a certain feature. - enum PagePainterFlags { Accessibility = 1, EnhanceLinks = 2, - EnhanceImages = 4, Highlights = 8, - TextSelection = 16, Annotations = 32 }; - - // draw (using painter 'p') the 'page' requested by 'id' using features - // in 'flags'. 'limits' is the bounding rect of the paint operation, - // 'scaledWidth' and 'scaledHeight' the expected size of page contents - static void paintPageOnPainter( QPainter * p, const Okular::Page * page, int pixID, - int flags, int scaledWidth, int scaledHeight, const QRect & pageLimits ); - - // draw (using painter 'p') the 'page' requested by 'id' using features - // in 'flags'. - // 'pageLimits' is the bounding rect of the paint operation relative to the - // top left of the (cropped) page. - // 'scaledWidth' and 'scaledHeight' the size of the page pixmap (before cropping). - // 'crop' is the (normalized) cropped rectangle within the page. - // The painter's (0,0) is assumed to be top left of the painted ('pageLimits') rect. - static void paintCroppedPageOnPainter( QPainter * p, const Okular::Page * page, int pixID, - int flags, int scaledWidth, int scaledHeight, const QRect & pageLimits, - const Okular::NormalizedRect & crop, Okular::NormalizedPoint *viewPortPoint ); - - private: - static void cropPixmapOnImage( QImage & dest, const QPixmap * src, const QRect & r ); - - // create an image taking the 'cropRect' portion of an image scaled - // to 'scaledWidth' by 'scaledHeight' pixels. cropRect must be inside - // the QRect(0,0, scaledWidth,scaledHeight) - static void scalePixmapOnImage( QImage & dest, const QPixmap *src, - int scaledWidth, int scaledHeight, const QRect & cropRect, QImage::Format format = QImage::Format_ARGB32_Premultiplied ); - - // set the alpha component of the image to a given value - static void changeImageAlpha( QImage & image, unsigned int alpha ); - - // colorize a gray image to the given color - static void colorizeImage( QImage & image, const QColor & color, - unsigned int alpha = 255 ); - - // my pretty dear raster function - typedef QList< Okular::NormalizedPoint > NormalizedPath; - enum RasterOperation { Normal, Multiply }; - static void drawShapeOnImage( - QImage & image, - const NormalizedPath & imagePoints, - bool closeShape = true, - const QPen & pen = QPen(), - const QBrush & brush = QBrush(), - double penWidthMultiplier = 1.0, - RasterOperation op = Normal - //float antiAliasRadius = 1.0 - ); -}; - -#endif