Hi,

Thanks for such a great tool (PoDoFo in general).

I made a few improvements to the podofoimpose tool. Hope they are useful to others as well. Here a short explanation for each patch.

- 1_Allow_to_set_the_bounding_box_with_the_legacy_plan_reader.patch
Also allow to set the bounding box with the legacy plan reader.

- 2_Return_none_zero_return_code.patch
If an exception happens, return none zero return code.

- 3_Allow_scaling_of_inserted_pages.patch
This is the biggest change. With this change it is possible to scale an inserted page (one by one with different scaling). I tried to make sure, that all additional parameters are optional and the previous behavior is retained if no scaling factors are given.

- 4_Handle_Name_datatype_correctly.patch
Handle the Name datatype correctly. Without this fix the Name datatype got converted to a dictionary after imposing the PDF. This resulted in having an invalid /ColorSpace for images and thus images that did not show up in the resulting PDF.

I tested and applied all patches against the trunk.

Best regards,
Chris
diff --git a/podofo/trunk/tools/podofoimpose/planreader_legacy.cpp b/podofo/trunk/tools/podofoimpose/planreader_legacy.cpp
index 2aa1b91fa..23d0f052c 100644
--- a/podofo/trunk/tools/podofoimpose/planreader_legacy.cpp
+++ b/podofo/trunk/tools/podofoimpose/planreader_legacy.cpp
@@ -268,6 +268,8 @@ PlanReader_Legacy::PlanReader_Legacy(const std::string & plan, PoDoFo::Impose::I
 	/// SUPPORTED
 	if ( I->vars.find("$ScaleFactor") != I->vars.end() )
 		I->setScale( PoDoFo::Impose::PageRecord::calc( I->vars["$ScaleFactor"] , I->vars));
+	if ( I->vars.find("$BoundingBox") != I->vars.end() )
+		I->setBoundingBox(I->vars["$BoundingBox"]);
 	/// END OF SUPPORTED
 	
 	
diff --git a/podofo/trunk/tools/podofoimpose/podofoimpose.cpp b/podofo/trunk/tools/podofoimpose/podofoimpose.cpp
index 6053f1c96..1d41b5a12 100644
--- a/podofo/trunk/tools/podofoimpose/podofoimpose.cpp
+++ b/podofo/trunk/tools/podofoimpose/podofoimpose.cpp
@@ -119,6 +119,7 @@ int main ( int argc, char *argv[] )
 	catch ( std::exception & e )
 	{
 		cerr << e.what() << endl;
+		return 4;
 	}
 
 	return 0;
diff --git a/podofo/trunk/tools/podofoimpose/impositionplan.cpp b/podofo/trunk/tools/podofoimpose/impositionplan.cpp
index 4d07970b9..71253455f 100644
--- a/podofo/trunk/tools/podofoimpose/impositionplan.cpp
+++ b/podofo/trunk/tools/podofoimpose/impositionplan.cpp
@@ -42,12 +42,14 @@ using std::runtime_error;
 
 #include <iostream> //XXX
 namespace PoDoFo { namespace Impose {
-PageRecord::PageRecord ( int s,int d,double r, double tx, double ty, int du )
+PageRecord::PageRecord ( int s,int d,double r, double tx, double ty, int du, double sx, double sy )
 		: sourcePage ( s ),
 		destPage ( d ),
 		rotate ( r ),
 		transX ( tx ),
 		transY ( ty ),
+		scaleX ( sx ),
+		scaleY ( sy ),
 		duplicateOf( du )
 {
 };
@@ -58,6 +60,8 @@ PageRecord::PageRecord ( )
 		rotate ( 0 ),
 		transX ( 0 ),
 		transY ( 0 ),
+		scaleX ( 1 ),
+		scaleY ( 1 ),
 		duplicateOf( 0 )
 {};
 
@@ -80,7 +84,7 @@ void PageRecord::load ( const std::string& buffer, const std::map<std::string, s
 		ts += ci;
 	}
 
-	if ( tokens.size() != 5 )
+	if ( tokens.size() != 5 && tokens.size() != 7 )
 	{
 		sourcePage = destPage = 0; // will return false for isValid()
 		std::cerr<<"INVALID_RECORD("<< tokens.size() <<") "<<buffer<<std::endl;
@@ -98,8 +102,14 @@ void PageRecord::load ( const std::string& buffer, const std::map<std::string, s
 	rotate	= calc ( tokens.at ( 2 ) , vars);
 	transX	= calc ( tokens.at ( 3 ) , vars);
 	transY	= calc ( tokens.at ( 4 ) , vars);
+	if (tokens.size() == 7) {
+		scaleX = calc ( tokens.at ( 5 ) , vars);
+		scaleY = calc ( tokens.at ( 6 ) , vars);
+	} else {
+		scaleX = scaleY = 1.0;
+	}
 
-	std::cerr<<" "<<sourcePage<<" "<<destPage<<" "<<rotate<<" "<<transX<<" "<<transY <<std::endl;
+	std::cerr<<" "<<sourcePage<<" "<<destPage<<" "<<rotate<<" "<<transX<<" "<<transY<<" "<<scaleX<<" "<<scaleY <<std::endl;
 
 }
 
diff --git a/podofo/trunk/tools/podofoimpose/impositionplan.h b/podofo/trunk/tools/podofoimpose/impositionplan.h
index 29eaf129b..b0bf09315 100644
--- a/podofo/trunk/tools/podofoimpose/impositionplan.h
+++ b/podofo/trunk/tools/podofoimpose/impositionplan.h
@@ -81,7 +81,7 @@ class Util
 class PageRecord
 {
 	public:
-		PageRecord ( int s,int d,double r, double tx, double ty , int du = 0 );
+		PageRecord ( int s,int d,double r, double tx, double ty , int du = 0, double sx = 1.0, double sy = 1.0 );
 		PageRecord( );
 		~PageRecord() {};
 		int sourcePage;
@@ -89,6 +89,8 @@ class PageRecord
 		double rotate;
 		double transX;
 		double transY;
+		double scaleX;
+		double scaleY;
 		int duplicateOf;
 		bool isValid() const;
 
diff --git a/podofo/trunk/tools/podofoimpose/pdftranslator.cpp b/podofo/trunk/tools/podofoimpose/pdftranslator.cpp
index d43f8eda9..5d171241a 100644
--- a/podofo/trunk/tools/podofoimpose/pdftranslator.cpp
+++ b/podofo/trunk/tools/podofoimpose/pdftranslator.cpp
@@ -431,6 +431,59 @@ namespace PoDoFo
 // 	delete sourceDoc;
 		}
 
+		void PdfTranslator::transform(double a, double b, double c, double d, double e, double f)
+		{
+			if (transformMatrix.empty()) {
+				transformMatrix.push_back(a);
+				transformMatrix.push_back(b);
+				transformMatrix.push_back(c);
+				transformMatrix.push_back(d);
+				transformMatrix.push_back(e);
+				transformMatrix.push_back(f);
+
+			} else {
+				std::vector<double> m0 = transformMatrix;
+				std::vector<double> m;
+
+				m.push_back(m0.at(0)*a + m0.at(1)*c);
+				m.push_back(m0.at(0)*b + m0.at(1)*d);
+				m.push_back(m0.at(2)*a + m0.at(3)*c);
+				m.push_back(m0.at(2)*b + m0.at(3)*d);
+
+				m.push_back(m0.at(4)*a + m0.at(5)*c + e);
+				m.push_back(m0.at(4)*b + m0.at(5)*d + f);
+
+				transformMatrix = m;
+			}
+		}
+
+		void PdfTranslator::rotate_and_translate(double theta, double dx, double dy)
+		{
+			double cosR = cos ( theta * 3.14159 / 180.0 );
+			double sinR = sin ( theta * 3.14159 / 180.0 );
+			transform(cosR, sinR, -sinR, cosR, dx, dy);
+		}
+
+		void PdfTranslator::translate(double dx, double dy)
+		{
+			transform(1, 0, 0, 1, dx, dy);
+		}
+
+		void PdfTranslator::scale(double sx, double sy)
+		{
+			transform(sx, 0, 0, sy, 0, 0);
+		}
+
+		void PdfTranslator::rotate(double theta)
+		{
+			double cosR = cos ( theta  *  3.14159 / 180.0 );
+			double sinR = sin ( theta  *  3.14159 / 180.0 );
+			// Counter-clockwise rotation (default):
+			transform(cosR, sinR, -sinR, cosR, 0, 0);
+			// Clockwise rotation:
+			// transform(cosR, -sinR, sinR, cosR, 0, 0);
+		}
+
 		void PdfTranslator::loadPlan ( const std::string & planFile , PoDoFo::Impose::PlanReader loader )
 		{
 // 			std::cerr<< "loadPlan" << planFile<<std::endl;
@@ -524,10 +577,11 @@ namespace PoDoFo
 // 					std::cerr<<curRecord.sourcePage<< " " << curRecord.destPage<<std::endl;
 					if(curRecord.sourcePage <= pcount)
 					{
-						double cosR = cos ( curRecord.rotate  *  3.14159 / 180.0 );
-						double sinR = sin ( curRecord.rotate  *  3.14159 / 180.0 );
+						double rot = curRecord.rotate;
 						double tx = curRecord.transX ;
 						double ty = curRecord.transY ;
+						double sx = curRecord.scaleX ;
+						double sy = curRecord.scaleY ;
 	
 						int resourceIndex ( /*(curRecord.duplicateOf > 0) ? curRecord.duplicateOf : */curRecord.sourcePage );
 						PdfXObject *xo = xobjects[resourceIndex];
@@ -563,9 +617,18 @@ namespace PoDoFo
 								std::cerr<<"ERROR Unknown type resource "<<resources[resourceIndex]->GetDataTypeString()  <<  std::endl;
 	
 						}
+						// Make sure we start with an empty transformMatrix.
+						transformMatrix.clear();
+						translate(0, 0);
+						// 1. Rotate, 2. Translate, 3. Scale
+						if (rot != 0 || tx != 0 || ty != 0) {
+							rotate_and_translate(rot, tx, ty);
+						}
+						scale(sx, sy);
+
 						// Very primitive but it makes it easy to track down imposition plan into content stream.
 						buffer << "q\n";
-						buffer << std::fixed << cosR <<" "<< sinR<<" "<<-sinR<<" "<< cosR<<" "<< tx <<" "<<  ty << " cm\n";
+						buffer << std::fixed << transformMatrix[0] <<" "<< transformMatrix[1] <<" "<< transformMatrix[2] <<" "<< transformMatrix[3] <<" "<< transformMatrix[4] <<" "<<  transformMatrix[5] << " cm\n";
 						buffer << "/OriginalPage" << resourceIndex << " Do\n";
 						buffer << "Q\n";
 					}
diff --git a/podofo/trunk/tools/podofoimpose/pdftranslator.h b/podofo/trunk/tools/podofoimpose/pdftranslator.h
index ec14d842d..40ff94175 100644
--- a/podofo/trunk/tools/podofoimpose/pdftranslator.h
+++ b/podofo/trunk/tools/podofoimpose/pdftranslator.h
@@ -133,6 +133,13 @@ class PdfTranslator
 		
 		std::map<std::string, PdfObject*> migrateMap;
 		std::set<PdfObject*> setMigrationPending;
+
+		std::vector<double> transformMatrix;
+		void transform(double a, double b, double c, double d, double e, double f);
+		void translate(double dx, double dy);
+		void scale(double sx, double sy);
+		void rotate(double theta);
+		void rotate_and_translate(double theta, double dx, double dy);
 	public:
 		int pcount;
 		double sourceWidth;
diff --git a/podofo/trunk/tools/podofoimpose/planreader_lua.cpp b/podofo/trunk/tools/podofoimpose/planreader_lua.cpp
index 334232f3b..d50000e53 100644
--- a/podofo/trunk/tools/podofoimpose/planreader_lua.cpp
+++ b/podofo/trunk/tools/podofoimpose/planreader_lua.cpp
@@ -111,6 +111,12 @@ int PlanReader_Lua::PushRecord ( lua_State * L )
 	                            lua_tonumber ( L, 3 ),
 	                            lua_tonumber ( L, 4 ),
 	                            lua_tonumber ( L, 5 ));
+
+	if (lua_isnumber ( L, 6 ))
+		P.scaleX = lua_tonumber ( L, 6 );
+	if (lua_isnumber ( L, 7 ))
+		P.scaleY = lua_tonumber ( L, 7 );
+
 	if(P.isValid())
 		that->plan->push_back ( P );
 
diff --git a/podofo/trunk/tools/podofoimpose/pdftranslator.cpp b/podofo/trunk/tools/podofoimpose/pdftranslator.cpp
index 5d171241a..43dffa4ff 100644
--- a/podofo/trunk/tools/podofoimpose/pdftranslator.cpp
+++ b/podofo/trunk/tools/podofoimpose/pdftranslator.cpp
@@ -281,6 +281,10 @@ namespace PoDoFo
 				else
 					return NULL; // avoid going through rest of method
 			}
+			else if ( obj->IsName() )
+			{
+				ret = targetDoc->GetObjects().CreateObject(obj->GetName());
+			}
 			else
 			{
 				ret = new PdfObject ( *obj );//targetDoc->GetObjects().CreateObject(*obj);
_______________________________________________
Podofo-users mailing list
Podofo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to