Hi,

I’ve played a bit with Podofobrowser. And here is an insomnia-patch^^concept 
which allow  viewing of content streams (to be honest, just paths). The result 
is not really interesting but i would be happy to get your opinions about the 
way it’s done and eventually if you see obvious problems which would prevent 
to add support for some kind of objects. I know the fastest way would be to 
just use Poppler, but I’m happy at hacking PDFs and would be thrilled to 
support manipulation of PDF objects.

TIA

-- 
Pierre Marchand
Index: src/podofobrowserbase.ui
===================================================================
--- src/podofobrowserbase.ui	(révision 986)
+++ src/podofobrowserbase.ui	(copie de travail)
@@ -5,7 +5,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>758</width>
+    <width>891</width>
     <height>629</height>
    </rect>
   </property>
@@ -13,25 +13,11 @@
    <string>PoDoFo Browser</string>
   </property>
   <widget class="QWidget" name="widget" >
-   <property name="geometry" >
-    <rect>
-     <x>0</x>
-     <y>58</y>
-     <width>758</width>
-     <height>571</height>
-    </rect>
-   </property>
-   <layout class="QVBoxLayout" >
-    <property name="spacing" >
-     <number>6</number>
-    </property>
-    <property name="margin" >
-     <number>9</number>
-    </property>
-    <item>
+   <layout class="QGridLayout" name="gridLayout_3" >
+    <item row="0" column="0" >
      <widget class="QSplitter" name="splitter" >
       <property name="orientation" >
-       <enum>Qt::Vertical</enum>
+       <enum>Qt::Horizontal</enum>
       </property>
       <widget class="QTreeView" name="listObjects" >
        <property name="mouseTracking" >
@@ -47,24 +33,18 @@
         <bool>true</bool>
        </property>
       </widget>
-      <widget class="QSplitter" name="splitter3" >
-       <property name="orientation" >
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <widget class="QSplitter" name="splitter2" >
-        <property name="orientation" >
-         <enum>Qt::Vertical</enum>
-        </property>
-        <widget class="QWidget" name="layout3" >
-         <layout class="QVBoxLayout" >
-          <property name="spacing" >
-           <number>6</number>
-          </property>
-          <property name="margin" >
-           <number>0</number>
-          </property>
+      <widget class="QWidget" native="1" name="widget_2" >
+       <layout class="QGridLayout" name="gridLayout_2" >
+        <item row="0" column="0" >
+         <layout class="QHBoxLayout" name="horizontalLayout" >
           <item>
            <widget class="QLabel" name="textLabel1" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+              <horstretch>2</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
             <property name="text" >
              <string>Contents of the associated stream:</string>
             </property>
@@ -74,131 +54,129 @@
            </widget>
           </item>
           <item>
-           <widget class="QLabel" name="labelStream" >
+           <widget class="QCheckBox" name="showPreview" >
             <property name="text" >
-             <string/>
+             <string>Show Preview (if possible)</string>
             </property>
-            <property name="wordWrap" >
-             <bool>false</bool>
+            <property name="checked" >
+             <bool>true</bool>
             </property>
            </widget>
           </item>
-          <item>
-           <widget class="QStackedWidget" name="stackedWidget" >
-            <property name="currentIndex" >
-             <number>0</number>
-            </property>
-            <widget class="QWidget" name="pageStream" >
-             <property name="geometry" >
-              <rect>
-               <x>0</x>
-               <y>0</y>
-               <width>738</width>
-               <height>246</height>
-              </rect>
-             </property>
-             <layout class="QVBoxLayout" name="verticalLayout" >
-              <item>
-               <widget class="QTextEdit" name="textStream" >
-                <property name="undoRedoEnabled" >
-                 <bool>false</bool>
-                </property>
-                <property name="readOnly" >
-                 <bool>false</bool>
-                </property>
-                <property name="acceptRichText" >
-                 <bool>false</bool>
-                </property>
-               </widget>
-              </item>
-             </layout>
-            </widget>
-            <widget class="QWidget" name="pageHexView" >
-             <property name="geometry" >
-              <rect>
-               <x>0</x>
-               <y>0</y>
-               <width>738</width>
-               <height>246</height>
-              </rect>
-             </property>
-             <layout class="QVBoxLayout" name="verticalLayout_2" >
-              <item>
-               <widget class="QHexView" native="1" name="hexView" />
-              </item>
-             </layout>
-            </widget>
-           </widget>
-          </item>
-          <item>
-           <layout class="QHBoxLayout" >
-            <property name="spacing" >
-             <number>6</number>
-            </property>
-            <property name="margin" >
-             <number>0</number>
-            </property>
+         </layout>
+        </item>
+        <item row="1" column="0" >
+         <widget class="QLabel" name="labelStream" >
+          <property name="text" >
+           <string/>
+          </property>
+          <property name="wordWrap" >
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0" >
+         <widget class="QStackedWidget" name="stackedWidget" >
+          <property name="currentIndex" >
+           <number>0</number>
+          </property>
+          <widget class="QWidget" name="pageStream" >
+           <layout class="QVBoxLayout" name="verticalLayout" >
             <item>
-             <widget class="QPushButton" name="buttonImport" >
-              <property name="enabled" >
+             <widget class="QTextEdit" name="textStream" >
+              <property name="undoRedoEnabled" >
                <bool>false</bool>
               </property>
-              <property name="text" >
-               <string>&amp;Import Stream ...</string>
+              <property name="readOnly" >
+               <bool>false</bool>
               </property>
-              <property name="shortcut" >
-               <string>Alt+I</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QPushButton" name="buttonExport" >
-              <property name="enabled" >
+              <property name="acceptRichText" >
                <bool>false</bool>
               </property>
-              <property name="text" >
-               <string>&amp;Export Stream ...</string>
-              </property>
-              <property name="shortcut" >
-               <string>Alt+E</string>
-              </property>
              </widget>
             </item>
+           </layout>
+          </widget>
+          <widget class="QWidget" name="pageHexView" >
+           <layout class="QVBoxLayout" name="verticalLayout_2" >
             <item>
-             <spacer>
-              <property name="orientation" >
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeType" >
-               <enum>QSizePolicy::Expanding</enum>
-              </property>
-              <property name="sizeHint" stdset="0" >
-               <size>
-                <width>241</width>
-                <height>21</height>
-               </size>
-              </property>
-             </spacer>
+             <widget class="QHexView" native="1" name="hexView" />
             </item>
            </layout>
+          </widget>
+          <widget class="QWidget" name="pageView" >
+           <layout class="QGridLayout" name="gridLayout" >
+            <item row="0" column="0" >
+             <widget class="PodofoView" name="podofoView" />
+            </item>
+           </layout>
+          </widget>
+         </widget>
+        </item>
+        <item row="3" column="0" >
+         <layout class="QHBoxLayout" >
+          <property name="spacing" >
+           <number>6</number>
+          </property>
+          <property name="margin" >
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QPushButton" name="buttonImport" >
+            <property name="enabled" >
+             <bool>false</bool>
+            </property>
+            <property name="text" >
+             <string>&amp;Import Stream ...</string>
+            </property>
+            <property name="shortcut" >
+             <string>Alt+I</string>
+            </property>
+           </widget>
           </item>
+          <item>
+           <widget class="QPushButton" name="buttonExport" >
+            <property name="enabled" >
+             <bool>false</bool>
+            </property>
+            <property name="text" >
+             <string>&amp;Export Stream ...</string>
+            </property>
+            <property name="shortcut" >
+             <string>Alt+E</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer>
+            <property name="orientation" >
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType" >
+             <enum>QSizePolicy::Expanding</enum>
+            </property>
+            <property name="sizeHint" stdset="0" >
+             <size>
+              <width>241</width>
+              <height>21</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
          </layout>
-        </widget>
-       </widget>
+        </item>
+       </layout>
+       <zorder></zorder>
+       <zorder>labelStream</zorder>
+       <zorder>textStream</zorder>
+       <zorder>stackedWidget</zorder>
+       <zorder></zorder>
       </widget>
      </widget>
     </item>
    </layout>
   </widget>
   <widget class="QToolBar" name="toolBar" >
-   <property name="geometry" >
-    <rect>
-     <x>0</x>
-     <y>24</y>
-     <width>758</width>
-     <height>34</height>
-    </rect>
-   </property>
    <property name="orientation" >
     <enum>Qt::Horizontal</enum>
    </property>
@@ -227,8 +205,8 @@
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>758</width>
-     <height>24</height>
+     <width>891</width>
+     <height>28</height>
     </rect>
    </property>
    <widget class="QMenu" name="helpMenu" >
@@ -599,6 +577,11 @@
    <header>hexwidget/QHexView.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>PodofoView</class>
+   <extends>QGraphicsView</extends>
+   <header>podofoview.h</header>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="podofobrowserrsrc.qrc" />
Index: src/podofoview.cpp
===================================================================
--- src/podofoview.cpp	(révision 0)
+++ src/podofoview.cpp	(révision 0)
@@ -0,0 +1,439 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Pierre Marchand   *
+ *   [email protected]   *
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "podofoview.h"
+
+#include <QGraphicsItem>
+#include <QGraphicsScene>
+#include <QTransform>
+
+#include <QDebug>
+
+PodofoView::PodofoView ( QWidget * parent )
+		:QGraphicsView ( parent )
+{
+	setScene ( new QGraphicsScene );
+	QTransform t;
+	t.scale ( 1.0,-1.0 );
+	setTransform ( t, false );
+	setRenderHint(QPainter::Antialiasing, true);
+	setRenderHint(QPainter::TextAntialiasing, true);
+	setRenderHint(QPainter::SmoothPixmapTransform, true);
+
+	// makers
+	m_itemMakers << ( new SimpleColorMaker );
+	m_itemMakers << ( new PathItemMaker );
+	m_itemMakers << ( new SimpleTransformMaker );
+	m_itemMakers << ( new GraphicStackMaker );
+	// (...)
+	// last one just passes, kind of "default" clause
+	m_itemMakers << ( new NoOpMaker );
+}
+
+
+void PodofoView::clear()
+{
+	foreach ( QGraphicsItem *item, m_itemList )
+	{
+		if ( item )
+			delete item;
+	}
+	m_itemList.clear();
+	setSceneRect ( QRectF() );
+}
+
+void PodofoView::setGeometry ( QRectF rect )
+{
+	setSceneRect ( rect );
+}
+
+
+void PodofoView::renderStream ( const QByteArray & stream )
+{
+	qDebug() << "PodofoView::renderStream";
+	PoDoFo::PdfContentsTokenizer * tokenizer = new PoDoFo::PdfContentsTokenizer ( stream.data(), stream.length() );
+
+	const char*      pszToken = NULL;
+	PoDoFo::PdfVariant       var;
+	PoDoFo::EPdfContentsType eType;
+	std::string      str;
+
+	PdfContentStream contentStream;
+
+	QList<PoDoFo::PdfVariant> stack;
+
+	while ( tokenizer->ReadNext ( eType, pszToken, var ) )
+	{
+		if ( eType == PoDoFo::ePdfContentsType_Keyword )
+		{
+			contentStream << PdfOperation ( QString::fromAscii ( pszToken ), stack );
+			stack.clear();
+		}
+		else if ( eType == PoDoFo::ePdfContentsType_Variant )
+		{
+			stack << var;
+		}
+		else
+		{
+			// Impossible; type must be keyword or variant
+			qWarning ( "Impossible; type must be keyword or variant" );
+		}
+	}
+
+	delete tokenizer;
+// 	qDebug() <<"Content Stream tokenized";
+	
+	QBrush defaultBrush(QColor(Qt::transparent), Qt::SolidPattern);
+	QPen defaultPen(QColor(Qt::transparent));
+	GraphicState gState;
+	gState.pen = defaultPen;
+	gState.brush = defaultBrush;
+	
+	gState.scene = scene();
+	gState.itemList = &m_itemList;
+
+	PdfContentIterator it ( contentStream.begin() );
+	while ( it != contentStream.end() )
+	{
+		qDebug() <<"Processing op:"<<it->key;
+		foreach ( GraphicItemMakerBase *gim, m_itemMakers )
+		{
+			if ( gim->support ( it->key ) )
+			{
+// 				qDebug()<<"=========";
+// 				qDebug()<<gState.pen;
+				it = gim->item ( it, gState );
+// 				qDebug()<<gState.pen;
+
+				break;
+			}
+		}
+	}
+
+
+}
+
+
+/// item makers
+PdfContentIterator NoOpMaker::item ( PdfContentIterator csIterator,  GraphicState & gState )
+{
+	qDebug() <<"NoOp:"<< csIterator->key;
+	return ++csIterator;
+}
+
+// Paths
+PathItemMaker::PathItemMaker()
+{
+	supportedOps << QString::fromAscii ( "m" )
+	<< QString::fromAscii ( "l" )
+	<< QString::fromAscii ( "c" )
+	<< QString::fromAscii ( "v" )
+	<< QString::fromAscii ( "y" )
+	<< QString::fromAscii ( "h" )
+	<< QString::fromAscii ( "re" );
+}
+
+bool PathItemMaker::support ( const QString & op ) const
+{
+	return supportedOps.contains ( op );
+}
+
+PdfContentIterator PathItemMaker::item ( PdfContentIterator csIterator,  GraphicState & gState )
+{
+	PdfContentIterator it ( csIterator );
+	QPainterPath p;
+	while ( 1 )
+	{
+		if ( support ( it->key ) )
+		{
+			if ( it->key == QString::fromAscii ( "m" ) )
+			{
+				if ( checkVarCount ( 2, it->operands ) )
+				{
+					double dPosX ( it->operands[0].GetReal() );
+					double dPosY ( it->operands[1].GetReal() );
+					p.moveTo ( QPointF ( dPosX, dPosY ) );
+				}
+				else
+				{
+					qDebug ( QString::fromAscii ( "Wrong number of operands (%1) for operator m " ).arg ( it->operands.count() ).toUtf8() );
+				}
+			}
+			else if ( it->key == QString::fromAscii ( "l" ) )
+			{
+				if ( checkVarCount ( 2, it->operands ) )
+				{
+					double dPosX ( it->operands[0].GetReal() );
+					double dPosY ( it->operands[1].GetReal() );
+					p.lineTo ( QPointF ( dPosX, dPosY ) );
+				}
+				else
+				{
+					qDebug ( QString::fromAscii ( "Wrong number of operands (%1) for operator l " ).arg ( it->operands.count() ).toUtf8() );
+				}
+			}
+			else if ( it->key == QString::fromAscii ( "c" ) )
+			{
+				if ( checkVarCount ( 6, it->operands ) )
+				{
+					double x1 ( it->operands[0].GetReal() );
+					double y1 ( it->operands[1].GetReal() );
+					double x2 ( it->operands[2].GetReal() );
+					double y2 ( it->operands[3].GetReal() );
+					double x3 ( it->operands[4].GetReal() );
+					double y3 ( it->operands[5].GetReal() );
+
+					p.cubicTo ( QPointF ( x1, y1 ) ,
+					            QPointF ( x2, y2 ) ,
+					            QPointF ( x3, y3 )  );
+				}
+				else
+				{
+					qDebug ( QString::fromAscii ( "Wrong number of operands (%1) for operator c " ).arg ( it->operands.count() ).toUtf8() );
+				}
+			}
+			else if ( it->key == QString::fromAscii ( "v" ) )
+			{
+				if ( checkVarCount ( 4, it->operands ) )
+				{
+					double x1 ( p.currentPosition().x() );
+					double y1 ( p.currentPosition().y() );
+					double x2 ( it->operands[0].GetReal() );
+					double y2 ( it->operands[1].GetReal() );
+					double x3 ( it->operands[2].GetReal() );
+					double y3 ( it->operands[3].GetReal() );
+
+					p.cubicTo ( QPointF ( x1, y1 ) ,
+					            QPointF ( x2, y2 ) ,
+					            QPointF ( x3, y3 )  );
+				}
+				else
+				{
+					qDebug ( QString::fromAscii ( "Wrong number of operands (%1) for operator v " ).arg ( it->operands.count() ).toUtf8() );
+				}
+			}
+			else if ( it->key == QString::fromAscii ( "y" ) )
+			{
+				if ( checkVarCount ( 4, it->operands ) )
+				{
+					double x1 ( it->operands[0].GetReal() );
+					double y1 ( it->operands[1].GetReal() );
+					double x2 ( it->operands[2].GetReal() );
+					double y2 ( it->operands[3].GetReal() );
+					double x3 ( it->operands[2].GetReal() );
+					double y3 ( it->operands[3].GetReal() );
+
+					p.cubicTo ( QPointF ( x1, y1 ) ,
+					            QPointF ( x2, y2 ) ,
+					            QPointF ( x3, y3 )  );
+				}
+				else
+				{
+					qDebug ( QString::fromAscii ( "Wrong number of operands (%1) for operator y " ).arg ( it->operands.count() ).toUtf8() );
+				}
+			}
+			else if ( it->key == QString::fromAscii ( "h" ) )
+			{
+				p.closeSubpath();
+			}
+			else if ( it->key == QString::fromAscii ( "re" ) )
+			{
+				if ( checkVarCount ( 4, it->operands ) )
+				{
+					double x1 ( it->operands[0].GetReal() );
+					double y1 ( it->operands[1].GetReal() );
+					double width ( it->operands[2].GetReal() );
+					double height ( it->operands[3].GetReal() );
+
+					p.addRect ( x1, y1 , width, height );
+				}
+				else
+				{
+					qDebug ( QString::fromAscii ( "Wrong number of operands (%1) for operator re " ).arg ( it->operands.count() ).toUtf8() );
+				}
+			}
+			else
+			{
+				qDebug ( QString::fromAscii ( "Unsupported Path operator :\"%1\"" ).arg ( it->key ).toUtf8() );
+			}
+
+			it++;
+		}
+		else // path must be finished!
+		{
+			gState.itemList->append ( gState.scene->addPath ( p * gState.cm, gState.pen, gState.brush ) );
+			break;
+		}
+	}
+
+	return it;
+}
+
+// Simple colors
+
+SimpleColorMaker::SimpleColorMaker()
+{
+	supportedOps << QString::fromAscii ( "g" )
+	<< QString::fromAscii ( "G" )
+	<< QString::fromAscii ( "rg" )
+	<< QString::fromAscii ( "RG" )
+	<< QString::fromAscii ( "k" )
+	<< QString::fromAscii ( "K" );
+}
+
+bool SimpleColorMaker::support ( const QString & op ) const
+{
+	return supportedOps.contains ( op );
+}
+
+PdfContentIterator SimpleColorMaker::item ( PdfContentIterator csIterator,  GraphicState & gState )
+{
+	QColor color;
+	if ( ( csIterator->key == QString::fromAscii ( "G" ) ) )
+	{
+		if ( checkVarCount ( 1, csIterator->operands ) )
+		{
+			double g ( csIterator->operands[0].GetReal() );
+			color.setRgbF ( g,g,g,1.0 );
+			gState.pen.setColor ( color );
+		}
+	}
+	else if ( ( csIterator->key == QString::fromAscii ( "g" ) ) )
+	{
+		if ( checkVarCount ( 1, csIterator->operands ) )
+		{
+			double g ( csIterator->operands[0].GetReal() );
+			color.setRgbF ( g,g,g,1.0 );
+			gState.brush.setColor ( color );
+		}
+	}
+	else if ( ( csIterator->key == QString::fromAscii ( "RG" ) ) )
+	{
+		if ( checkVarCount ( 3, csIterator->operands ) )
+		{
+			double r ( csIterator->operands[0].GetReal() );
+			double g ( csIterator->operands[1].GetReal() );
+			double b ( csIterator->operands[2].GetReal() );
+			color.setRgbF ( r,g,b,1.0 );
+			gState.pen.setColor ( color );
+		}
+	}
+	else if ( ( csIterator->key == QString::fromAscii ( "rg" ) ) )
+	{
+		if ( checkVarCount ( 3, csIterator->operands ) )
+		{
+			double r ( csIterator->operands[0].GetReal() );
+			double g ( csIterator->operands[1].GetReal() );
+			double b ( csIterator->operands[2].GetReal() );
+			color.setRgbF ( r,g,b,1.0 );
+			gState.brush.setColor ( color );
+		}
+	}
+	else if ( ( csIterator->key == QString::fromAscii ( "K" ) ) )
+	{
+		if ( checkVarCount ( 4, csIterator->operands ) )
+		{
+			double c ( csIterator->operands[0].GetReal() );
+			double m ( csIterator->operands[1].GetReal() );
+			double y ( csIterator->operands[2].GetReal() );
+			double k ( csIterator->operands[3].GetReal() );
+			color.setCmykF ( c,m,y,k,1.0 );
+			gState.pen.setColor ( color );
+		}
+	}
+	else if ( ( csIterator->key == QString::fromAscii ( "k" ) ) )
+	{
+		if ( checkVarCount ( 4, csIterator->operands ) )
+		{
+			double c ( csIterator->operands[0].GetReal() );
+			double m ( csIterator->operands[1].GetReal() );
+			double y ( csIterator->operands[2].GetReal() );
+			double k ( csIterator->operands[3].GetReal() );
+			color.setCmykF ( c,m,y,k,1.0 );
+			gState.brush.setColor ( color );
+		}
+	}
+
+	return ++csIterator;
+}
+
+// simple ctm
+SimpleTransformMaker::SimpleTransformMaker()
+{
+	supportedOps << QString::fromAscii ( "cm" );
+}
+
+bool SimpleTransformMaker::support ( const QString & op ) const
+{
+	return supportedOps.contains ( op );
+}
+
+PdfContentIterator SimpleTransformMaker::item ( PdfContentIterator csIterator, GraphicState & gState )
+{
+	if ( checkVarCount ( 6, csIterator->operands ) )
+	{
+		double a ( csIterator->operands[0].GetReal() );
+		double b ( csIterator->operands[1].GetReal() );
+		double c ( csIterator->operands[2].GetReal() );
+		double d ( csIterator->operands[3].GetReal() );
+		double e ( csIterator->operands[4].GetReal() );
+		double f ( csIterator->operands[5].GetReal() );
+
+		QMatrix m ( a,b,c,d,e,f );
+		gState.cm = m;
+	}
+	return ++csIterator;
+}
+
+GraphicStackMaker::GraphicStackMaker()
+{
+	supportedOps << QString::fromAscii ( "q" )
+			<< QString::fromAscii ( "Q" );
+}
+
+bool GraphicStackMaker::support(const QString & op) const
+{
+	return supportedOps.contains ( op );
+}
+
+PdfContentIterator GraphicStackMaker::item(PdfContentIterator csIterator, GraphicState & gState)
+{
+	if(csIterator->key == QString::fromAscii("q"))
+	{
+		m_stack << gState;
+	}
+	else if(csIterator->key == QString::fromAscii("Q"))
+	{
+		if(!m_stack.isEmpty())
+		{
+			gState = m_stack.last();
+			m_stack.removeLast();
+		}
+	}
+	return ++csIterator;
+}
+
+
+
+
+
+
+
+
Index: src/podofoview.h
===================================================================
--- src/podofoview.h	(révision 0)
+++ src/podofoview.h	(révision 0)
@@ -0,0 +1,132 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Pierre Marchand   *
+ *   [email protected]   *
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef PODOFOVIEW_H
+#define PODOFOVIEW_H
+
+#include <podofo/podofo.h>
+
+#include <QByteArray>
+#include <QGraphicsView>
+#include <QList>
+#include <QMap>
+#include <QRectF>
+
+class QGraphicsScene;
+class QGraphicsItem;
+
+struct  PdfOperation
+{
+	QString key;
+	QList<PoDoFo::PdfVariant> operands;
+	
+	PdfOperation(const QString& k, const QList<PoDoFo::PdfVariant>& ops)
+		:key(k), operands(ops)
+		     {}
+};
+typedef QList<PdfOperation> PdfContentStream;
+typedef QList<PdfOperation>::iterator PdfContentIterator;
+
+
+struct GraphicState
+{
+	QPen pen;
+	QBrush brush;
+	QMatrix cm;	
+	
+	QGraphicsScene * scene;
+	QList<QGraphicsItem*> * itemList;  
+};
+
+class GraphicItemMakerBase
+{
+	public:
+		GraphicItemMakerBase(){}
+		~GraphicItemMakerBase(){}
+		
+		virtual PdfContentIterator item(PdfContentIterator csIterator,  GraphicState& gState) = 0;
+		virtual bool support(const QString& op) const {return false;}
+		
+	protected:
+		bool checkVarCount(unsigned int control, const QList<PoDoFo::PdfVariant>& ops) const 
+		{
+			return ( control == ops.count() ) ? true : false;
+		}
+};
+
+class NoOpMaker : public GraphicItemMakerBase
+{
+	public:
+		NoOpMaker(){}
+		PdfContentIterator item(PdfContentIterator csIterator,  GraphicState& gState);
+		bool support(const QString& op) const {return true;}
+};
+
+class GraphicStackMaker :  public GraphicItemMakerBase
+{
+	QStringList supportedOps;
+	QList<GraphicState> m_stack;
+	public:
+		GraphicStackMaker();
+		PdfContentIterator item(PdfContentIterator csIterator,  GraphicState& gState);
+		bool support(const QString& op) const ;
+};
+
+class SimpleTransformMaker : public GraphicItemMakerBase
+{
+	QStringList supportedOps;
+	public:
+		SimpleTransformMaker();
+		PdfContentIterator item(PdfContentIterator csIterator,  GraphicState& gState);
+		bool support(const QString& op) const ;
+};
+
+class SimpleColorMaker: public GraphicItemMakerBase
+{
+	QStringList supportedOps;
+	public:
+		SimpleColorMaker();
+		PdfContentIterator item(PdfContentIterator csIterator,  GraphicState& gState);
+		bool support(const QString& op) const ;
+};
+
+class PathItemMaker : public GraphicItemMakerBase
+{
+	QStringList supportedOps;
+	public:
+		PathItemMaker();
+		PdfContentIterator item(PdfContentIterator csIterator,  GraphicState& gState);
+		bool support(const QString& op) const ;
+};
+
+
+class PodofoView : public QGraphicsView
+{
+	public:
+		PodofoView(QWidget * parent);
+		void clear();
+		void setGeometry(QRectF rect=QRectF());
+		void renderStream(const QByteArray& stream);
+	private:
+		QList<QGraphicsItem*> m_itemList;
+		QList<GraphicItemMakerBase*> m_itemMakers;
+};
+
+#endif // PODOFOVIEW_H
\ No newline at end of file
Index: src/podofobrowser.cpp
===================================================================
--- src/podofobrowser.cpp	(révision 986)
+++ src/podofobrowser.cpp	(copie de travail)
@@ -20,6 +20,7 @@
 
 #include "podofobrowser.h"
 #include "podofoutil.h"
+#include "podofoview.h"
 #include "backgroundloader.h"
 #include "ui_podofoaboutdlg.h"
 #include "ui_podofofinddlg.h"
@@ -179,8 +180,8 @@
     list << width()/3;
     list << (width()/3 * 2);
 
-    splitter2->setSizes( list );
-    splitter3->setSizes( list );
+//     splitter2->setSizes( list );
+//     splitter3->setSizes( list );
 
     this->resize( w, h );
 
@@ -351,6 +352,8 @@
     m_pByteArrayIO = NULL;
     delete m_pByteArray;
     m_pByteArray = NULL;
+    
+    podofoView->clear();
 
     // make keyboard navigation easier, especially in Catalog View mode
     // hopefully this does not slow down to much.
@@ -422,11 +425,20 @@
     {
         // TODO FIXME XXX AUUGH! Encoding assumption like nothing ever
         // seen before!
+	    if(!showPreview->isChecked())
+	    {
         QString data = QString::fromAscii(pBuf, lLen);
         textStream->setEnabled(true);
         textStream->setText( data );
         displayInfo = tr("displayed in full");
         stackedWidget->setCurrentWidget( pageStream );
+	    }
+	    else
+	    {
+		    QByteArray ba(pBuf, lLen);
+		    podofoView->renderStream(ba);
+		    stackedWidget->setCurrentWidget(pageView);
+	    }
     }
     else
     {
Index: src/CMakeLists.txt
===================================================================
--- src/CMakeLists.txt	(révision 986)
+++ src/CMakeLists.txt	(copie de travail)
@@ -33,6 +33,7 @@
 	podofoutil.cpp
 	pdfobjectmodel.cpp
 	podofobrowser.cpp
+	podofoview.cpp
 	main.cpp
 	hexwidget/QHexView.cpp
 	${podofobrowser_QRC_SRCS}
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(révision 986)
+++ CMakeLists.txt	(copie de travail)
@@ -16,10 +16,19 @@
 FIND_PACKAGE(Qt4 REQUIRED)
 INCLUDE(${QT_USE_FILE})
 
-#FIND_PACKAGE(ZLIB REQUIRED)
-#FIND_PACKAGE(LIBFREETYPE REQUIRED)
-#FIND_PACKAGE(LIBJPEG REQUIRED)
+FIND_PACKAGE(ZLIB REQUIRED)
+FIND_PACKAGE(LIBFREETYPE REQUIRED)
+FIND_PACKAGE(LIBJPEG REQUIRED)
 
+IF(DEFINED PODOFO_NOT_SYSTEM)
+  SET(PODOFO_BUILD_STATIC 1)
+        SET(PODOFO_BUILD_SHARED 0)
+        SET(PODOFO_BUILD_LIB_ONLY 1)
+        ADD_SUBDIRECTORY(externals/required_libpodofo)
+        SET(LIBPODOFO_H ${CMAKE_CURRENT_SOURCE_DIR}/externals/required_libpodofo)
+        SET(LIBPODOFO_LIB podofo_static)
+        MESSAGE("+++Done setting up private PoDoFo copy")
+ELSE(DEFINED PODOFO_NOT_SYSTEM)
 FIND_PACKAGE(LIBPODOFO)
 IF(NOT LIBPODOFO_FOUND)
 	MESSAGE("+++PoDoFo not found... building private copy")
@@ -31,8 +40,8 @@
 	SET(LIBPODOFO_LIB podofo_static)
 	MESSAGE("+++Done setting up private PoDoFo copy")
 ENDIF(NOT LIBPODOFO_FOUND)
+ENDIF(DEFINED PODOFO_NOT_SYSTEM)
 
-
 FIND_PACKAGE(LIBSTLPORT)
 SET(stlport_libraries_if_use_stlport)
 IF(USE_STLPORT)
------------------------------------------------------------------------------
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to