Le Thursday 08 November 2007 12:33:39 Pierre Marchand, vous avez écrit :
> Le Thursday 08 November 2007 11:08:14 Craig Ringer, vous avez écrit :
> > I've put together a quick reader based on Dom's code that can be used to
> > read a content stream an operator at a time, returning a pair containing
> > the string representation of the operator and a vector of PdfVariant
> > operands. There's also a simple function to accumulate the lot of them
> > if you want to read a whole stream at once.
>
> Does it mean that with a PdfOperator wrapper class which could register
> methods to do actual job, a renderer could be written incrementally and
> more or less easily ?

I took minutes to try with test/ContentParser. I guess you’ll find the code 
ugly but I can’t help to take part in this game :-)

-- 
Pierre Marchand
Index: test/ContentParser/main.cpp
===================================================================
--- test/ContentParser/main.cpp	(révision 755)
+++ test/ContentParser/main.cpp	(copie de travail)
@@ -10,20 +10,111 @@
 using namespace std;
 using namespace PoDoFo;
 
+struct PdfContentOperator
+{
+	std::string key;
+	int num_args;
+	void *userData;
+	void (*method)(std::stack<PoDoFo::PdfVariant>);
+	PdfContentOperator(std::string k, int n, void *u, void (*m)(std::stack<PoDoFo::PdfVariant>))
+	:key(k), num_args(n), userData(u), method(m)
+	{};
+	PdfContentOperator(){};
+};
+
+struct PdfContentEngine
+{
+	std::map<std::string, PdfContentOperator> knownOps;
+	void registerOperator(PdfContentOperator op)
+	{
+		knownOps[op.key] = op;
+	};
+	int process(std::string pdfOp, std::stack<PoDoFo::PdfVariant> opStack)
+	{
+		bool isSupported = false;
+		std::map<std::string, PdfContentOperator>::iterator it = knownOps.begin();
+		while(it != knownOps.end())
+		{
+			if(!pdfOp.compare(it->first))
+			{
+				isSupported = true;
+				break;
+			}
+			++it;
+		}
+		
+		if( !isSupported )
+			return 0;
+		
+		{
+			void (*m)(std::stack<PoDoFo::PdfVariant>) = knownOps[pdfOp].method;
+			m(opStack);
+		}
+		return knownOps[pdfOp].num_args;
+	};
+	
+};
+
 static bool print_output = false;
 
+void moveTo(std::stack<PdfVariant> stack)
+{
+	double dPosY = stack.top().GetReal();
+	stack.pop();
+	double dPosX = stack.top().GetReal();
+	stack.pop();
+	std::cout << string ( 12,' ' ) << " MoveTo: " << dPosX << " " << dPosY << std::endl;
+}
+
+void lineTo ( std::stack<PdfVariant>  stack)
+{
+	double dPosY = stack.top().GetReal();
+	stack.pop();
+	double dPosX = stack.top().GetReal();
+	stack.pop();
+	std::cout << string ( 12,' ' ) << " LineTo: " << dPosX << " " << dPosY << std::endl;
+}
+
+void concatenateMatrix(std::stack<PdfVariant>  stack)
+{
+	double a = stack.top().GetReal();
+	stack.pop();
+	double b = stack.top().GetReal();
+	stack.pop();
+	double c = stack.top().GetReal();
+	stack.pop();
+	double d = stack.top().GetReal();
+	stack.pop();
+	double e = stack.top().GetReal();
+	stack.pop();
+	double f = stack.top().GetReal();
+	stack.pop();
+	std::cout << string ( 12,' ' ) << " ConcatMatrix: " << a << " " << b <<" " << c << " " << d <<" " << e << " " << f <<std::endl;
+}
+
 void parse_contents( PdfContentsTokenizer* pTokenizer ) 
 {
     const char*      pszToken = NULL;
     PdfVariant       var;
     EPdfContentsType eType;
     std::string      str;
-
+    
+    PdfContentEngine engine;
+    PdfContentOperator moveOp("m", 2, 0, moveTo);
+    PdfContentOperator lineOp("l", 2, 0, lineTo);
+    PdfContentOperator concatOp("cm", 4, 0, concatenateMatrix);
+    engine.registerOperator(moveOp);
+    engine.registerOperator(lineOp);
+    engine.registerOperator(concatOp);
+    
+    
     int numKeywords = 0;
     int numVariants = 0;
 
     std::stack<PdfVariant> stack;
 
+    
+    
     while( pTokenizer->ReadNext( eType, pszToken, var ) )
     {
         if( eType == ePdfContentsType_Keyword )
@@ -32,25 +123,10 @@
             if (print_output) std::cout << setw(12) << (numKeywords+numVariants)
                                         << " Keyword: " << pszToken << std::endl;
 
-            // support 'l' and 'm' tokens
-            if( strcmp( pszToken, "l" ) == 0 ) 
-            {
-                double dPosY = stack.top().GetReal();
-                stack.pop();
-                double dPosX = stack.top().GetReal();
-                stack.pop();
-
-                if(print_output) std::cout << string(12,' ') << " LineTo: " << dPosX << " " << dPosY << std::endl;
-            }
-            else if( strcmp( pszToken, "m" ) == 0 ) 
-            {
-                double dPosY = stack.top().GetReal();
-                stack.pop();
-                double dPosX = stack.top().GetReal();
-                stack.pop();
-
-                if(print_output) std::cout << string(12,' ') << " MoveTo: " << dPosX << " " << dPosY << std::endl;
-            }
+	    int usedArgs = engine.process(pszToken, stack);
+	    for(int i = 0; i < usedArgs; ++i)
+		    stack.pop();
+	    
         }
         else if ( eType == ePdfContentsType_Variant )
         {
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to