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