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