Commit f0d84a18 authored by Tobias Koenig's avatar Tobias Koenig

KPDF reads the transition effects from the PDF document now.

svn path=/trunk/kdegraphics/kpdf/; revision=375033
parent d7ac1ce3
......@@ -5,6 +5,6 @@ INCLUDES = -I$(srcdir)/generator_pdf -I$(srcdir)/.. -I$(srcdir)/../xpdf -I$(srcd
METASOURCES = AUTO
libkpdfcore_la_LIBADD = ./generator_pdf/libgeneratorpdf.la
libkpdfcore_la_SOURCES = document.cpp link.cpp page.cpp
libkpdfcore_la_SOURCES = document.cpp link.cpp page.cpp pagetransition.cpp
noinst_LTLIBRARIES = libkpdfcore.la
......@@ -33,6 +33,7 @@
#include "gp_outputdev.h"
#include "core/observer.h" //for PAGEVIEW_ID
#include "core/page.h"
#include "core/pagetransition.h"
#include "conf/settings.h"
// id for DATA_READY ThreadedGenerator Event
......@@ -118,8 +119,13 @@ bool PDFGenerator::loadDocument( const QString & fileName, QValueVector<KPDFPage
// build Pages (currentPage was set -1 by deletePages)
uint pageCount = pdfdoc->getNumPages();
pagesVector.resize( pageCount );
for ( uint i = 0; i < pageCount ; i++ )
pagesVector[i] = new KPDFPage( i, pdfdoc->getPageWidth(i+1), pdfdoc->getPageHeight(i+1), pdfdoc->getPageRotate(i+1) );
for ( uint i = 0; i < pageCount ; i++ ) {
KPDFPage * page = new KPDFPage( i, pdfdoc->getPageWidth(i+1),
pdfdoc->getPageHeight(i+1),
pdfdoc->getPageRotate(i+1) );
addTransition( i, page );
pagesVector[i] = page;
}
// the file has been loaded correctly
return true;
......@@ -226,6 +232,80 @@ void PDFGenerator::addSynopsisChildren( QDomNode * parent, GList * items )
}
}
void PDFGenerator::addTransition( int pageNumber, KPDFPage * page )
{
KPDFPageTransition *transition = new KPDFPageTransition();
Page *pdfPage = pdfdoc->getCatalog()->getPage( pageNumber + 1 );
if ( pdfPage && pdfPage->getTransition() ) {
PageTransition *pdfTransition = pdfPage->getTransition();
switch ( pdfTransition->getType() ) {
case PageTransition::Replace:
transition->setType( KPDFPageTransition::Replace );
break;
case PageTransition::Split:
transition->setType( KPDFPageTransition::Split );
break;
case PageTransition::Blinds:
transition->setType( KPDFPageTransition::Blinds );
break;
case PageTransition::Box:
transition->setType( KPDFPageTransition::Box );
break;
case PageTransition::Wipe:
transition->setType( KPDFPageTransition::Wipe );
break;
case PageTransition::Dissolve:
transition->setType( KPDFPageTransition::Dissolve );
break;
case PageTransition::Glitter:
transition->setType( KPDFPageTransition::Glitter );
break;
case PageTransition::Fly:
transition->setType( KPDFPageTransition::Fly );
break;
case PageTransition::Push:
transition->setType( KPDFPageTransition::Push );
break;
case PageTransition::Cover:
transition->setType( KPDFPageTransition::Cover );
break;
case PageTransition::Uncover:
transition->setType( KPDFPageTransition::Uncover );
break;
case PageTransition::Fade:
transition->setType( KPDFPageTransition::Fade );
break;
}
transition->setDuration( pdfTransition->getDuration() );
switch ( pdfTransition->getAlignment() ) {
case PageTransition::Horizontal:
transition->setAlignment( KPDFPageTransition::Horizontal );
break;
case PageTransition::Vertical:
transition->setAlignment( KPDFPageTransition::Vertical );
break;
}
switch ( pdfTransition->getDirection() ) {
case PageTransition::Inward:
transition->setDirection( KPDFPageTransition::Inward );
break;
case PageTransition::Outward:
transition->setDirection( KPDFPageTransition::Outward );
break;
}
transition->setAngle( pdfTransition->getAngle() );
transition->setScale( pdfTransition->getScale() );
transition->setIsRectangular( pdfTransition->isRectangular() == gTrue );
}
page->setTransition( transition );
}
bool PDFGenerator::print( KPrinter& printer )
{
......
......@@ -75,6 +75,8 @@ class PDFGenerator : public Generator
QString getDocumentDate( const QString & data ) const;
// private function for creating the document synopsis hieracy
void addSynopsisChildren( QDomNode * parent, GList * items );
// private function for creating the transition information
void addTransition( int pageNumber, KPDFPage * page );
// (GT) take the first queued item from the stack and feed it to the thread
void startNewThreadedGeneration();
// (GT) receive data from the generator thread
......
......@@ -32,7 +32,7 @@
KPDFPage::KPDFPage( uint page, float w, float h, int r )
: m_number( page ), m_rotation( r ), m_attributes( 0 ),
m_width( w ), m_height( h ), m_sLeft( 0 ), m_sTop( 0 ),
m_sRight( 0 ), m_sBottom( 0 ), m_text( 0 )
m_sRight( 0 ), m_sBottom( 0 ), m_text( 0 ), m_transition( 0 )
{
// if landscape swap width <-> height (rotate 90deg CCW)
if ( r == 90 || r == 270 )
......@@ -91,6 +91,11 @@ const KPDFPageRect * KPDFPage::getRect( int mouseX, int mouseY ) const
return 0;
}
const KPDFPageTransition * KPDFPage::getTransition() const
{
return m_transition;
}
const QString KPDFPage::getTextInRect( const QRect & rect, double zoom ) const
{
if ( !m_text )
......@@ -146,6 +151,11 @@ void KPDFPage::setRects( const QValueList< KPDFPageRect * > rects )
m_rects = rects;
}
void KPDFPage::setTransition( const KPDFPageTransition * transition )
{
m_transition = transition;
}
void KPDFPage::deletePixmap( int id )
{
if ( m_pixmaps.contains( id ) )
......
......@@ -15,8 +15,10 @@
class QPainter;
class QPixmap;
class QRect;
class TextPage;
class KPDFPageRect;
class KPDFPageTransition;
/**
* @short Collector for all the data belonging to a page.
......@@ -50,6 +52,7 @@ class KPDFPage
bool hasRect( int mouseX, int mouseY ) const;
bool hasLink( int mouseX, int mouseY ) const;
const KPDFPageRect * getRect( int mouseX, int mouseY ) const;
const KPDFPageTransition * getTransition() const;
const QString getTextInRect( const QRect & rect, double zoom = 1.0 ) const;
// operations (by KPDFDocument)
......@@ -62,6 +65,7 @@ class KPDFPage
void setPixmap( int id, QPixmap * pixmap );
void setSearchPage( TextPage * text );
void setRects( const QValueList< KPDFPageRect * > rects );
void setTransition( const KPDFPageTransition * transition );
void deletePixmap( int id );
void deletePixmapsAndRects();
......@@ -74,6 +78,7 @@ class KPDFPage
QMap< int, QPixmap * > m_pixmaps;
TextPage * m_text;
QValueList< KPDFPageRect * > m_rects;
const KPDFPageTransition * m_transition;
};
......
/***************************************************************************
* Copyright (C) 2005 by Tobias Koenig <tokoe@kde.org> *
* *
* 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. *
***************************************************************************/
// local includes
#include "pagetransition.h"
/** class KPDFPageTransition **/
KPDFPageTransition::KPDFPageTransition()
: m_type( Replace ),
m_duration( 1 ),
m_alignment( Horizontal ),
m_direction( Inward ),
m_angle( 0 ),
m_scale( 1.0 ),
m_rectangular( false )
{
}
KPDFPageTransition::~KPDFPageTransition()
{
}
/***************************************************************************
* Copyright (C) 2005 by Tobias Koenig <tokoe@kde.org> *
* *
* 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 _KPDF_PAGE_TRANSITION_H_
#define _KPDF_PAGE_TRANSITION_H_
/**
* @short Information object for the transition effect of a page.
*/
class KPDFPageTransition
{
public:
KPDFPageTransition();
~KPDFPageTransition();
enum Type {
Replace,
Split,
Blinds,
Box,
Wipe,
Dissolve,
Glitter,
Fly,
Push,
Cover,
Uncover,
Fade
};
enum Alignment {
Horizontal,
Vertical
};
enum Direction {
Inward,
Outward
};
// Get type of the transition.
inline Type type() const { return m_type; }
// Get duration of the transition in seconds.
inline int duration() const { return m_duration; }
// Get dimension in which the transition effect occurs.
inline Alignment alignment() const { return m_alignment; }
// Get direction of motion of the transition effect.
inline Direction direction() const { return m_direction; }
// Get direction in which the transition effect moves.
inline int angle() const { return m_angle; }
// Get starting or ending scale.
inline double scale() const { return m_scale; }
// Returns true if the area to be flown is rectangular and opaque.
inline bool isRectangular() const { return m_rectangular; }
inline void setType( Type type ) { m_type = type; }
inline void setDuration( int duration ) { m_duration = duration; }
inline void setAlignment( Alignment alignment ) { m_alignment = alignment; }
inline void setDirection( Direction direction ) { m_direction = direction; }
inline void setAngle( int angle ) { m_angle = angle; }
inline void setScale( double scale ) { m_scale = scale; }
inline void setIsRectangular( bool rectangular ) { m_rectangular = rectangular; }
private:
Type m_type;
int m_duration;
Alignment m_alignment;
Direction m_direction;
int m_angle;
double m_scale;
bool m_rectangular;
};
#endif
......@@ -41,8 +41,6 @@ struct PresentationFrame
{
const KPDFPage * page;
QRect geometry;
PresentationWidget::TransitionType transType;
PresentationWidget::TransitionDirection transDir;
};
......@@ -122,9 +120,6 @@ void PresentationWidget::pageSetup( const QValueVector<KPDFPage*> & pageSet, boo
{
PresentationFrame * frame = new PresentationFrame();
frame->page = *setIt;
//TODO get transition from the document
frame->transType = Settings::slidesGlitterTrans() ? Glitter : NoTrans;
frame->transDir = Left;
// calculate frame geometry keeping constant aspect ratio
float pageRatio = frame->page->ratio();
int pageWidth = m_width,
......@@ -287,8 +282,7 @@ void PresentationWidget::generatePage()
#endif
// start transition or immediately update viewport
TransitionType type = m_frameIndex != -1 ? m_frames[ m_frameIndex ]->transType : NoTrans;
initTransition( type );
initTransition( m_frames[ m_frameIndex ]->page->getTransition() );
}
void PresentationWidget::generateIntroPage( QPainter & p )
......@@ -554,14 +548,33 @@ void PresentationWidget::slotTransitionStep()
/** ONLY the TRANSITIONS GENERATION function from here on **/
void PresentationWidget::initTransition( TransitionType type )
void PresentationWidget::initTransition( const KPDFPageTransition *transition )
{
m_transitionRects.clear();
const int gridXstep = 50;
const int gridYstep = 38;
switch( type )
switch( transition->type() )
{
case Glitter: {
// TODO: implement missing transitions
case KPDFPageTransition::Replace:
update();
return;
case KPDFPageTransition::Split:
update();
return;
case KPDFPageTransition::Blinds:
update();
return;
case KPDFPageTransition::Box:
update();
return;
case KPDFPageTransition::Wipe:
update();
return;
case KPDFPageTransition::Dissolve:
update();
return;
case KPDFPageTransition::Glitter: {
int oldX = 0,
oldY = 0;
// create a grid of gridXstep by gridYstep QRects
......@@ -595,15 +608,19 @@ void PresentationWidget::initTransition( TransitionType type )
m_transitionMul = 40;
m_transitionDelay = (m_transitionMul * 500) / steps;
} break;
// TODO: implement missing transitions
case NoTrans:
case BoxIn:
case BoxOut:
case GlitterDir:
case FuseDir:
case SplitDir:
case WipeDir:
case KPDFPageTransition::Fly:
update();
return;
case KPDFPageTransition::Push:
update();
return;
case KPDFPageTransition::Cover:
update();
return;
case KPDFPageTransition::Uncover:
update();
return;
case KPDFPageTransition::Fade:
update();
return;
}
......
......@@ -15,6 +15,7 @@
#include <qstringlist.h>
#include <qvaluevector.h>
#include "core/observer.h"
#include "core/pagetransition.h"
class KToolBar;
class QTimer;
......@@ -35,11 +36,6 @@ class PresentationWidget : public QWidget, public KPDFDocumentObserver
PresentationWidget( KPDFDocument * doc );
~PresentationWidget();
// define type of transitions used by presentation frames
enum TransitionType { NoTrans, BoxIn, BoxOut, Glitter, GlitterDir,
FuseDir, SplitDir, WipeDir };
enum TransitionDirection { Left, Top, Right, Bottom };
// inherited from KPDFDocumentObserver
uint observerId() const { return PRESENTATION_ID; }
void pageSetup( const QValueVector<KPDFPage*> & pages, bool documentChanged );
......@@ -59,7 +55,7 @@ class PresentationWidget : public QWidget, public KPDFDocumentObserver
void generateIntroPage( QPainter & p );
void generateContentsPage( int page, QPainter & p );
void generateOverlay();
void initTransition( TransitionType type );
void initTransition( const KPDFPageTransition *transition );
// cache stuff
int m_width;
......
......@@ -172,6 +172,105 @@ GBool PageAttrs::readBox(Dict *dict, const char *key, PDFRectangle *box) {
return ok;
}
//------------------------------------------------------------------------
// PageTransition
//------------------------------------------------------------------------
PageTransition::PageTransition(Dict *dict)
: type(Replace),
duration(1),
alignment(Horizontal),
direction(Inward),
angle(0),
scale(1.0),
rectangular(false)
{
Object dictObj;
Object obj;
dict->lookup("Trans", &dictObj);
if (dictObj.isDict()) {
Dict *transDict = dictObj.getDict();
if (transDict->lookup("S", &obj)->isName()) {
const char *s = obj.getName();
if (strcmp("R", s) == 0)
type = Replace;
else if (strcmp("Split", s) == 0)
type = Split;
else if (strcmp("Blinds", s) == 0)
type = Blinds;
else if (strcmp("Box", s) == 0)
type = Box;
else if (strcmp("Wipe", s) == 0)
type = Wipe;
else if (strcmp("Dissolve", s) == 0)
type = Dissolve;
else if (strcmp("Glitter", s) == 0)
type = Glitter;
else if (strcmp("Fly", s) == 0)
type = Fly;
else if (strcmp("Push", s) == 0)
type = Push;
else if (strcmp("Cover", s) == 0)
type = Cover;
else if (strcmp("Uncover", s) == 0)
type = Push;
else if (strcmp("Fade", s) == 0)
type = Cover;
}
obj.free();
if (transDict->lookup("D", &obj)->isInt()) {
duration = obj.getInt();
}
obj.free();
if (transDict->lookup("Dm", &obj)->isName()) {
const char *dm = obj.getName();
if ( strcmp( "H", dm ) == 0 )
alignment = Horizontal;
else if ( strcmp( "V", dm ) == 0 )
alignment = Vertical;
}
obj.free();
if (transDict->lookup("M", &obj)->isName()) {
const char *m = obj.getName();
if ( strcmp( "I", m ) == 0 )
direction = Inward;
else if ( strcmp( "O", m ) == 0 )
direction = Outward;
}
obj.free();
if (transDict->lookup("Di", &obj)->isInt()) {
angle = obj.getInt();
}
obj.free();
if (transDict->lookup("Di", &obj)->isName()) {
if ( strcmp( "None", obj.getName() ) == 0 )
angle = 0;
}
obj.free();
if (transDict->lookup("SS", &obj)->isReal()) {
scale = obj.getReal();
}
obj.free();
if (transDict->lookup("B", &obj)->isBool()) {
rectangular = obj.getBool();
}
obj.free();
}
dictObj.free();
}
PageTransition::~PageTransition() {
}
//------------------------------------------------------------------------
// Page
//------------------------------------------------------------------------
......@@ -184,6 +283,9 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA) {
// get attributes
attrs = attrsA;
// get transition
transition = new PageTransition( pageDict );
// annotations
pageDict->lookupNF("Annots", &annots);
if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
......@@ -214,6 +316,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA) {
Page::~Page() {
delete attrs;
delete transition;
annots.free();
contents.free();
}
......
......@@ -97,6 +97,74 @@ private:
Object resources;
};
//------------------------------------------------------------------------
// PageTransition
//------------------------------------------------------------------------
class PageTransition {
public:
enum Type {
Replace,
Split,
Blinds,
Box,
Wipe,
Dissolve,
Glitter,
Fly,
Push,
Cover,
Uncover,
Fade
};
enum Alignment {
Horizontal,
Vertical
};
enum Direction {
Inward,
Outward
};
// Construct a new PageTransition object from a page dictionary.
PageTransition( Dict *dict );
// Destructor
~PageTransition();
// Get type of the transition.
Type getType() const { return type; }
// Get duration of the transition in seconds.
int getDuration() const { return duration; }
// Get dimension in which the transition effect
// occurs.
Alignment getAlignment() const { return alignment; }
// Get direction of motion of the transition effect.
Direction getDirection() const { return direction; }
// Get direction in which the transition effect moves.
int getAngle() const { return angle; }
// Get starting or ending scale.
double getScale() const { return scale; }
// Returns true if the area to be flown is rectangular and
// opaque.
GBool isRectangular() const { return rectangular; }
private:
Type type;
int duration;
Alignment alignment;
Direction direction;
int angle;
double scale;
GBool rectangular;
};