Commit 65ba29ed authored by Christophe Devriese's avatar Christophe Devriese

Fixed design a little bit. Still need to remove redundant components though.

svn path=/trunk/kdegraphics/kpdf/; revision=234795
parent 298b1eb6
......@@ -43,7 +43,7 @@ shellrc_DATA = kpdf_shell.rc
kde_module_LTLIBRARIES = libkpdfpart.la
# the Part's source, library search path, and link libraries
libkpdfpart_la_SOURCES = kpdf_canvas.cpp kpdf_part.cpp kpdf_pagewidget.cc QOutputDev.cpp part.ui
libkpdfpart_la_SOURCES = kpdf_canvas.cpp kpdf_part.cpp kpdf_pagewidget.cc QOutputDev.cpp QOutputDevPixmap.cpp part.ui
libkpdfpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
libkpdfpart_la_LIBADD = ../xpdf/libxpdf.la $(LIB_KPARTS) $(LIB_KFILE) $(LIB_KDEPRINT)
......
This diff is collapsed.
//========================================================================
//
// XOutputDev.h
//
// Copyright 1996 Derek B. Noonburg
//
//========================================================================
#ifndef QOUTPUTDEVPIXMAP_H
#define QOUTPUTDEVPIXMAP_H
#ifdef __GNUC__
#pragma interface
#endif
#include "aconf.h"
#include <stddef.h>
class Object;
#include "config.h"
#include "CharTypes.h"
#include "GlobalParams.h"
#include "OutputDev.h"
class GString;
class GList;
struct GfxRGB;
class GfxFont;
class GfxSubpath;
class TextPage;
class XOutputFontCache;
class Link;
class Catalog;
class DisplayFontParam;
class UnicodeMap;
class CharCodeToUnicode;
class QPainter;
class QPixmap;
class QPointArray;
#include <qstring.h>
#include <qrect.h>
typedef double fp_t;
class QOutputDevPixmap : public OutputDev {
public:
// Constructor.
QOutputDevPixmap( );
// Destructor.
virtual ~QOutputDevPixmap();
//---- get info about output device
// Does this device use upside-down coordinates?
// (Upside-down means (0,0) is the top left corner of the page.)
virtual GBool upsideDown() { return gTrue; }
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() { return gTrue; }
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gFalse; }
// Does this device need non-text content?
virtual GBool needNonText() { return gFalse; }
//----- initialization and control
// Start a page.
virtual void startPage(int pageNum, GfxState *state);
// End a page.
virtual void endPage();
//----- link borders
virtual void drawLink(Link *link, Catalog /* *catalog */);
//----- save/restore graphics state
virtual void saveState(GfxState *state);
virtual void restoreState(GfxState *state);
//----- update graphics state
virtual void updateAll(GfxState *state);
virtual void updateCTM(GfxState *state, fp_t m11, fp_t m12,
fp_t m21, fp_t m22, fp_t m31, fp_t m32);
virtual void updateLineDash(GfxState *state);
virtual void updateFlatness(GfxState *state);
virtual void updateLineJoin(GfxState *state);
virtual void updateLineCap(GfxState *state);
virtual void updateMiterLimit(GfxState *state);
virtual void updateLineWidth(GfxState *state);
virtual void updateFillColor(GfxState *state);
virtual void updateStrokeColor(GfxState *state);
//----- update text state
virtual void updateFont(GfxState *state);
//----- path painting
virtual void stroke(GfxState *state);
virtual void fill(GfxState *state);
virtual void eoFill(GfxState *state);
//----- path clipping
virtual void clip(GfxState *state);
virtual void eoClip(GfxState *state);
//----- text drawing
virtual void beginString(GfxState *state, GString *s);
virtual void endString(GfxState *state);
virtual void drawChar(GfxState *state, fp_t x, fp_t y,
fp_t dx, fp_t dy,
fp_t originX, fp_t originY,
CharCode code, Unicode *u, int uLen);
//----- image drawing
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg);
virtual void drawImage(GfxState *state, Object *ref, Stream *str,
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg);
// Find a string. If <top> is true, starts looking at <l>,<t>;
// otherwise starts looking at top of page. If <bottom> is true,
// stops looking at <l+w-1>,<t+h-1>; otherwise stops looking at bottom
// of page. If found, sets the text bounding rectange and returns
// true; otherwise returns false.
GBool findText ( Unicode *s, int len, GBool top, GBool bottom, int *xMin, int *yMin, int *xMax, int *yMax );
//----- special QT access
bool findText ( const QString &str, int &l, int &t, int &w, int &h, bool top = 0, bool bottom = 0 );
bool findText ( const QString &str, QRect &r, bool top = 0, bool bottom = 0 );
// Get the text which is inside the specified rectangle.
QString getText ( int left, int top, int width, int height );
QString getText ( const QRect &r );
public:
QPixmap * getPixmap() { return m_pixmap; };
private:
QPixmap * m_pixmap; // pixmap to draw into
QPainter * m_painter; // painter to draw to the pixmap
TextPage * m_text; // text from the current page
private:
QFont matchFont ( GfxFont *, fp_t m11, fp_t m12, fp_t m21, fp_t m22 );
void updateLineAttrs ( GfxState *state, GBool updateDash );
void doFill ( GfxState *state, bool winding );
void doClip ( GfxState *state, bool winding );
int convertPath ( GfxState *state, QPointArray &points, QArray<int> &lengths );
int convertSubpath ( GfxState *state, GfxSubpath *subpath, QPointArray &points );
};
#endif // QOUTPUTDEVPIXMAP
#include "QOutputDevPixmap.h"
#include <qcursor.h>
#include <qpainter.h>
#include "PDFDoc.h"
#include "kpdf_pagewidget.h"
#include "kpdf_pagewidget.moc"
using namespace KPDF;
#include "utils.h"
PageWidget::PageWidget(QWidget* parent, const char* name)
: QWidget(parent, name),
m_doc(0),
m_pressedAction( 0 )
namespace KPDF
{
setMouseTracking(true);
}
PageWidget::PageWidget(QWidget* parent, const char* name)
: QScrollView(parent, name, WRepaintNoErase),
m_doc(0),
m_zoomFactor( 1.0 ),
m_currentPage( 1 ),
m_pressedAction( 0 )
{
m_outputdev = new QOutputDevPixmap();
setMouseTracking(true);
}
void
PageWidget::setPixmap(const QPixmap& pm)
{
m_pixmap = pm;
}
void
PageWidget::setPDFDocument(PDFDoc* doc)
{
m_doc = doc;
updatePixmap();
}
void
PageWidget::setPDFDocument(PDFDoc* doc)
{
m_doc = doc;
}
void
PageWidget::setPixelsPerPoint(float ppp)
{
m_ppp = ppp;
}
void
PageWidget::setPixelsPerPoint(float ppp)
{
m_ppp = ppp;
}
void
PageWidget::contentsMousePressEvent(QMouseEvent* e)
{
if (m_doc == 0)
return;
void
PageWidget::mousePressEvent(QMouseEvent* e)
{
if (m_doc == 0)
return;
m_pressedAction = m_doc->findLink(e->x()/m_ppp, e->y()/m_ppp);
}
m_pressedAction = m_doc->findLink(e->x()/m_ppp, e->y()/m_ppp);
}
void
PageWidget::contentsMouseReleaseEvent(QMouseEvent* e)
{
if (m_doc == 0)
return;
void
PageWidget::mouseReleaseEvent(QMouseEvent* e)
{
if (m_doc == 0)
return;
LinkAction* action = m_doc->findLink(e->x()/m_ppp, e->y()/m_ppp);
if (action == m_pressedAction)
emit linkClicked(action);
LinkAction* action = m_doc->findLink(e->x()/m_ppp, e->y()/m_ppp);
if (action == m_pressedAction)
emit linkClicked(action);
m_pressedAction = 0;
}
m_pressedAction = 0;
}
void
PageWidget::contentsMouseMoveEvent(QMouseEvent* e)
{
if (m_doc == 0)
return;
void
PageWidget::mouseMoveEvent(QMouseEvent* e)
{
if (m_doc == 0)
return;
LinkAction* action = m_doc->findLink(e->x()/m_ppp, e->y()/m_ppp);
setCursor(action != 0 ? Qt::PointingHandCursor : Qt::ArrowCursor);
LinkAction* action = m_doc->findLink(e->x()/m_ppp, e->y()/m_ppp);
setCursor(action != 0 ? Qt::PointingHandCursor : Qt::ArrowCursor);
}
void PageWidget::drawContents ( QPainter *p, int clipx, int clipy, int clipw, int cliph )
{
QPixmap * m_pixmap = NULL;
if (m_outputdev)
m_pixmap = m_outputdev->getPixmap();
if ( m_pixmap != NULL && ! m_pixmap->isNull() )
p->drawPixmap ( clipx, clipy, *m_pixmap, clipx, clipy, clipw, cliph );
else
p->fillRect ( clipx, clipy, clipw, cliph, white );
}
void PageWidget::nextPage()
{
setPage( getPage() + 1);
};
void PageWidget::previousPage()
{
setPage( getPage() - 1 );
};
void PageWidget::zoomIn()
{
m_zoomFactor += 0.1;
updatePixmap();
};
void PageWidget::zoomOut()
{
m_zoomFactor -= 0.1;
updatePixmap();
};
void PageWidget::setPage(int page)
{
if (m_doc)
{
m_currentPage = max(0, min( page, m_doc->getNumPages()));
} else {
m_currentPage = 0;
}
updatePixmap();
};
void PageWidget::updatePixmap()
{
const double pageWidth = m_doc->getPageWidth (m_currentPage) * m_zoomFactor;
const double pageHeight = m_doc->getPageHeight(m_currentPage) * m_zoomFactor;
// Pixels per point when the zoomFactor is 1.
const float basePpp = QPaintDevice::x11AppDpiX() / 72.0;
const float ppp = basePpp * m_zoomFactor; // pixels per point
m_doc->displayPage(m_outputdev, m_currentPage, int(ppp * 72.0), 0, true);
resizeContents ( m_outputdev->getPixmap()->width ( ), m_outputdev->getPixmap()->height ( ));
viewport()->update();
}
}
// vim:ts=2:sw=2:tw=78:et
......@@ -3,42 +3,65 @@
#include <qpixmap.h>
#include <qwidget.h>
#include <qscrollview.h>
class LinkAction;
class PDFDoc;
class QOutputDevPixmap;
namespace KPDF
{
/**
* Widget displaying a pixmap containing a PDF page and Links.
*/
class PageWidget : public QWidget
{
Q_OBJECT
public:
PageWidget(QWidget* parent = 0, const char* name = 0);
void setPixmap(const QPixmap&);
void setPDFDocument(PDFDoc*);
void setPixelsPerPoint(float);
// void setLinks();
signals:
void linkClicked(LinkAction*);
protected:
void mousePressEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
private:
QPixmap m_pixmap;
PDFDoc* m_doc;
float m_ppp; // Pixels per point
LinkAction* m_pressedAction;
};
/**
* Widget displaying a pixmap containing a PDF page and Links.
*/
class PageWidget : public QScrollView
{
Q_OBJECT
enum ZoomMode { FitInWindow, FitWidth, FitVisible, FixedFactor };
public:
PageWidget(QWidget* parent = 0, const char* name = 0);
void setPDFDocument(PDFDoc*);
void setPixelsPerPoint(float);
/* void setLinks(); */
void setPage(int pagenum);
int getPage() { return m_currentPage; };
public slots:
void nextPage();
void previousPage();
void zoomIn();
void zoomOut();
void updatePixmap();
signals:
void linkClicked(LinkAction*);
protected:
void contentsMousePressEvent(QMouseEvent*);
void contentsMouseReleaseEvent(QMouseEvent*);
void contentsMouseMoveEvent(QMouseEvent*);
virtual void drawContents ( QPainter *p, int, int, int, int );
private:
QOutputDevPixmap * m_outputdev;
PDFDoc* m_doc;
float m_ppp; // Pixels per point
float m_zoomFactor;
ZoomMode m_zoomMode;
int m_currentPage;
LinkAction* m_pressedAction;
};
}
#endif
......
......@@ -14,6 +14,8 @@
#include <kstdaction.h>
#include <kparts/genericfactory.h>
#include "part.h"
#include <kdebug.h>
#include "GString.h"
......@@ -23,9 +25,8 @@
#include "XOutputDev.h"
// #include "kpdf_canvas.h"
// #include "kpdf_pagewidget.h"
#include "kpdf_pagewidget.h"
#include "part.h"
typedef KParts::GenericFactory<KPDF::Part> KPDFPartFactory;
K_EXPORT_COMPONENT_FACTORY(libkpdfpart, KPDFPartFactory);
......@@ -54,6 +55,8 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
this, SLOT( pageClicked ( QListBoxItem * ) ));
m_outputDev = pdfpartview->outputdev;
setWidget(pdfpartview);
// create our actions
......@@ -65,18 +68,18 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_fitToWidth = new KToggleAction(i18n("Fit to Page &Width"), 0,
this, SLOT(slotFitToWidthToggled()),
actionCollection(), "fit_to_width");
KStdAction::zoomIn (this, SLOT(zoomIn()),
KStdAction::zoomIn (m_outputDev, SLOT(zoomIn()),
actionCollection(), "zoom_in");
KStdAction::zoomOut (this, SLOT(zoomOut()),
KStdAction::zoomOut (m_outputDev, SLOT(zoomOut()),
actionCollection(), "zoom_out");
KStdAction::back (this, SLOT(back()),
actionCollection(), "back");
KStdAction::forward (this, SLOT(forward()),
actionCollection(), "forward");
KStdAction::prior (this, SLOT(displayPreviousPage()),
KStdAction::prior (m_outputDev, SLOT(previousPage()),
actionCollection(), "previous_page");
KStdAction::next (this, SLOT(displayNextPage()),
KStdAction::next (m_outputDev, SLOT(nextPage()),
actionCollection(), "next_page" );
// set our XML-UI resource file
......@@ -121,7 +124,7 @@ Part::openFile()
if (!m_doc->isOk())
return false;
// just for fun, set the status bar
// emit setStatusBarText( QString::number( m_doc->getNumPages() ) );
......@@ -136,6 +139,8 @@ Part::openFile()
pdfpartview->pagesListBox->update();
displayPage(1);
m_outputDev->setPDFDocument(m_doc);
return true;
}
......@@ -143,25 +148,6 @@ Part::openFile()
void
Part::displayPage(int pageNumber, float /*zoomFactor*/)
{
kdDebug() << "display page" << endl;
kdDebug() << "page : " << pageNumber << endl;
kdDebug() << "zoom factor : " << m_zoomFactor << endl;
Page * p = m_doc->getCatalog()->getPage(pageNumber);
kdDebug() << "metadata stream : " << endl;
char * md = new char[4096];
if (p->getMetadata())
{
while(p->getMetadata()->getLine(md, 4096) != NULL)
{
kdDebug() << md << endl;
}
}
kdDebug() << "------------" << endl;
if (pageNumber <= 0 || pageNumber > m_doc->getNumPages())
return;
......@@ -172,48 +158,47 @@ Part::displayPage(int pageNumber, float /*zoomFactor*/)
const float basePpp = QPaintDevice::x11AppDpiX() / 72.0;
switch (m_zoomMode)
{
case FitWidth:
{
const double pageAR = pageWidth/pageHeight; // Aspect ratio
const int canvasWidth = m_outputDev->contentsRect().width();
const int canvasHeight = m_outputDev->contentsRect().height();
const int scrollBarWidth = m_outputDev->verticalScrollBar()->width();
// Calculate the height so that the page fits the viewport width
// assuming that we need a vertical scrollbar.
float height = float(canvasWidth - scrollBarWidth) / pageAR;
// If the vertical scrollbar wasn't needed after all, calculate the page
// size so that the page fits the viewport width without the scrollbar.
if (ceil(height) <= canvasHeight)
{
height = float(canvasWidth) / pageAR;
// Handle the rare case that enlarging the page resulted in the need of
// a vertical scrollbar. We can fit the page to the viewport height in
// this case.
if (ceil(height) > canvasHeight)
height = float(canvasHeight) * pageAR;
}
m_zoomFactor = (height / pageHeight) / basePpp;
break;
}
case FixedFactor:
default:
break;
}
{
case FitWidth:
{
const double pageAR = pageWidth/pageHeight; // Aspect ratio
const int canvasWidth = m_outputDev->contentsRect().width();
const int canvasHeight = m_outputDev->contentsRect().height();
const int scrollBarWidth = m_outputDev->verticalScrollBar()->width();
// Calculate the height so that the page fits the viewport width
// assuming that we need a vertical scrollbar.
float height = float(canvasWidth - scrollBarWidth) / pageAR;
// If the vertical scrollbar wasn't needed after all, calculate the page
// size so that the page fits the viewport width without the scrollbar.
if (ceil(height) <= canvasHeight)
{
height = float(canvasWidth) / pageAR;
// Handle the rare case that enlarging the page resulted in the need of
// a vertical scrollbar. We can fit the page to the viewport height in
// this case.
if (ceil(height) > canvasHeight)
height = float(canvasHeight) * pageAR;
}
m_zoomFactor = (height / pageHeight) / basePpp;
break;
}
case FixedFactor:
default:
break;
}
const float ppp = basePpp * m_zoomFactor; // pixels per point
m_doc->displayPage(m_outputDev, pageNumber, int(m_zoomFactor * ppp * 72.0), 0, true);
// m_doc->displayPage(m_outputDev, pageNumber, int(m_zoomFactor * ppp * 72.0), 0, true);
m_outputDev->show();
// m_outputDev->show();