~ubuntu-branches/ubuntu/quantal/cups-filters/quantal-security

« back to all changes in this revision

Viewing changes to filter/pdftopdf/qpdf_xobject.cc

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2012-08-20 14:53:42 UTC
  • mfrom: (2.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20120820145342-bddzpwqv0klmt84d
Tags: 1.0.22-1
* New upstream release
   - pdftopdf filter replaced by new QPDF-based filter from Tobias
     Hoffmann's Google Summer of Code project. The former Poppler-based
     pdftopdf duplicated a lot of Poppler's code. The old filter is
     still in the package as pdftopdf.old with source code in
     filter/pdftopdf.old. It will be removed in a later release.
   - bannertopdf: Page duplication routine fixed.
   - bannertopdf: Fixed invalid output of a direct stream object.
   - Added most recent contributors to AUTHORS and COPYING files.
* debian/control: Added build dependency on libqpdf-dev.
* debian/copyright: Updated for the addition of the new pdftopdf filter.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "qpdf_xobject.h"
 
2
//#include <qpdf/Types.h>
 
3
#include <qpdf/QPDF.hh>
 
4
#include <qpdf/Pl_Discard.hh>
 
5
#include <qpdf/Pl_Count.hh>
 
6
#include <qpdf/Pl_Concatenate.hh>
 
7
#include "qpdf_tools.h"
 
8
#include "qpdf_pdftopdf.h"
 
9
 
 
10
// TODO: need to remove  Struct Parent stuff  (or fix)
 
11
 
 
12
// NOTE: use /TrimBox to position content inside Nup cell, /BleedBox to clip against
 
13
 
 
14
class CombineFromContents_Provider : public QPDFObjectHandle::StreamDataProvider {
 
15
public:
 
16
  CombineFromContents_Provider(const std::vector<QPDFObjectHandle> &contents);
 
17
 
 
18
  void provideStreamData(int objid, int generation, Pipeline* pipeline);
 
19
private:
 
20
  std::vector<QPDFObjectHandle> contents;
 
21
};
 
22
 
 
23
CombineFromContents_Provider::CombineFromContents_Provider(const std::vector<QPDFObjectHandle> &contents)
 
24
  : contents(contents)
 
25
{
 
26
}
 
27
 
 
28
void CombineFromContents_Provider::provideStreamData(int objid, int generation, Pipeline* pipeline)
 
29
{
 
30
  Pl_Concatenate concat("concat", pipeline);
 
31
  const int clen=contents.size();
 
32
  for (int iA=0;iA<clen;iA++) {
 
33
    contents[iA].pipeStreamData(&concat, true, false, false);
 
34
  }
 
35
  concat.manualFinish();
 
36
}
 
37
 
 
38
/*
 
39
To convert a page to an XObject there are several keys to consider:
 
40
 
 
41
/Type /Page        -> /Type /XObject (/Type optional for XObject)
 
42
                   -> /Subtype /Form
 
43
                   -> [/FormType 1]  (optional)
 
44
/Parent ? ? R      -> remove
 
45
/Resources dict    -> copy
 
46
/MediaBox rect [/CropBox /BleedBox /TrimBox /ArtBox] 
 
47
                   -> /BBox  (use TrimBox [+ Bleed consideration?], with fallback to /MediaBox)
 
48
                      note that /BBox is in *Form Space*, see /Matrix!
 
49
[/BoxColorInfo dict]   (used for guidelines that may be shown by viewer)
 
50
                   -> ignore/remove
 
51
[/Contents asfd]   -> concatenate into stream data of the XObject (page is a dict, XObject a stream)
 
52
 
 
53
[/Rotate 90]   ... must be handled (either use CTM where XObject is /used/ -- or set /Matrix)
 
54
[/UserUnit] (PDF 1.6)   -> to /Matrix ?   -- it MUST be handled.
 
55
 
 
56
[/Group dict]      -> copy
 
57
[/Thumb stream]    -> remove, not needed any more / would have to be regenerated (combined)
 
58
[/B]               article beads -- ignore for now
 
59
[/Dur]             -> remove  (transition duration)
 
60
[/Trans]           -> remove  (transitions)
 
61
[/AA]              -> remove  (additional-actions)
 
62
 
 
63
[/Metadata]        what shall we do?? (kill: we can't combine XML)
 
64
[/PieceInfo]       -> remove, we can't combine private app data (?)
 
65
[/LastModified  date]  (opt except /PieceInfo)  -> see there
 
66
 
 
67
[/PZ]              -> remove, can't combine/keep (preferred zoom level)
 
68
[/SeparationInfo]  -> remove, no way to keep this (needed for separation)
 
69
 
 
70
[/ID]              related to web capture -- ignore/kill?
 
71
[/StructParents]   (opt except pdf contains "structural content items")
 
72
                   -> copy (is this correct?)
 
73
 
 
74
[/Annots]          annotations -- ignore for now
 
75
[/Tabs]            tab order for annotations (/R row, /C column, /S structure order) -- see /Annots
 
76
 
 
77
[/TemplateInstantiated]  (reqd, if page was created from named page obj, 1.5) -- ? just ignore?
 
78
[/PresSteps]       -> remove (sub-page navigation for presentations) [no subpage navigation for printing / nup]
 
79
[/VP]              viewport rects -- ignore/drop or recalculate into new page
 
80
 
 
81
*/
 
82
QPDFObjectHandle makeXObject(QPDF *pdf,QPDFObjectHandle page)
 
83
{
 
84
  page.assertPageObject();
 
85
 
 
86
  QPDFObjectHandle ret=QPDFObjectHandle::newStream(pdf);
 
87
  QPDFObjectHandle dict=ret.getDict();
 
88
 
 
89
  dict.replaceKey("/Type",QPDFObjectHandle::newName("/XObject")); // optional
 
90
  dict.replaceKey("/Subtype",QPDFObjectHandle::newName("/Form")); // required
 
91
//  dict.replaceKey("/FormType",QPDFObjectHandle::newInteger(1)); // optional
 
92
 
 
93
  QPDFObjectHandle box=getTrimBox(page); // already in "form space"
 
94
  dict.replaceKey("/BBox",box); // reqd
 
95
 
 
96
  // [/Matrix .]   ...  default is [1 0 0 1 0 0]; we incorporate /UserUnit and /Rotate here
 
97
  Matrix mtx;
 
98
  if (page.hasKey("/UserUnit")) {
 
99
    mtx.scale(page.getKey("/UserUnit").getNumericValue());
 
100
  }
 
101
 
 
102
  // transform, so that bbox is [0 0 w h]  (in outer space, but after UserUnit)
 
103
  Rotation rot=getRotate(page);
 
104
  
 
105
  // calculate rotation effect on [0 0 w h]
 
106
  PageRect bbox=getBoxAsRect(box),tmp;
 
107
  tmp.left=0;
 
108
  tmp.bottom=0;
 
109
  tmp.right=0;
 
110
  tmp.top=0;
 
111
  tmp.rotate_move(rot,bbox.width,bbox.height);
 
112
  // tmp.rotate_move moves the bbox; we must achieve this move with the matrix.
 
113
  mtx.translate(tmp.left,tmp.bottom); // 1. move origin to end up at left,bottom after rotation
 
114
 
 
115
  mtx.rotate(rot);  // 2. rotate coordinates according to /Rotate
 
116
  mtx.translate(-bbox.left,-bbox.bottom);  // 3. move origin from 0,0 to "form space"
 
117
 
 
118
  dict.replaceKey("/Matrix",mtx.get());
 
119
 
 
120
  dict.replaceKey("/Resources",page.getKey("/Resources"));
 
121
  if (page.hasKey("/Group")) {
 
122
    dict.replaceKey("/Group",page.getKey("/Group")); // (transparency); opt, copy if there
 
123
  }
 
124
 
 
125
// ?? /StructParents   ... can basically copy from page, but would need fixup in Structure Tree
 
126
// FIXME: remove (globally) Tagged spec (/MarkInfo), and Structure Tree
 
127
 
 
128
  // Note: [/Name]  (reqd. only in 1.0 -- but there we even can't use our normal img/patter procedures)
 
129
 
 
130
// none:
 
131
//  QPDFObjectHandle filter=QPDFObjectHandle::newArray();
 
132
//  QPDFObjectHandle decode_parms=QPDFObjectHandle::newArray();
 
133
  // null leads to use of "default filters" from qpdf's settings
 
134
  QPDFObjectHandle filter=QPDFObjectHandle::newNull();
 
135
  QPDFObjectHandle decode_parms=QPDFObjectHandle::newNull();
 
136
 
 
137
  std::vector<QPDFObjectHandle> contents=page.getPageContents();  // (will assertPageObject)
 
138
 
 
139
  auto ph=PointerHolder<QPDFObjectHandle::StreamDataProvider>(new CombineFromContents_Provider(contents));
 
140
  ret.replaceStreamData(ph,filter,decode_parms);
 
141
 
 
142
  return ret;
 
143
}
 
144
 
 
145
/*
 
146
  we will have to fix up the structure tree (e.g. /K in element), when copying  /StructParents;
 
147
    (there is /Pg, which has to point to the containing page, /Stm when it's not part of the page's content stream 
 
148
     i.e. when it is in our XObject!; then there is /StmOwn ...)
 
149
  when not copying, we have to remove the structure tree completely (also /MarkInfo dict)
 
150
  Still this might not be sufficient(?), as there are probably BDC and EMC operators in the stream.
 
151
*/
 
152
 
 
153
/* /XObject /Form has
 
154
[/Type /XObject]
 
155
/Subtype /Form
 
156
[/FormType 1]
 
157
/BBox rect         from crop box, or recalculate
 
158
[/Matrix .]   ...  default is [1 0 0 1 0 0] ---   we have to incorporate /UserUnit here?!
 
159
[/Resources dict]  from page.
 
160
[/Group dict]      used for transparency -- can copy from page
 
161
[/Ref dict]        not needed; for external reference
 
162
[/Metadata]        not, as long we can not combine.
 
163
[/PieceInfo]       can copy, but not combine 
 
164
[/LastModified date]    copy if /PieceInfo there
 
165
[/StructParent]    . don't want to be one   ... have to read more spec
 
166
[/StructParents]   . copy from page!
 
167
[/OPI]             no opi version. don't set
 
168
[/OC]              is this optional content? NO! not needed.
 
169
[/Name]            (only reqd. in 1.0 -- but there we even can't use our normal img/patter procedures)
 
170
*/
 
171
 
 
172