Commit 2e7ee23bf63da6de221737907bcc6fa8526c3fda

Authored by Jay Berkenbilt
1 parent 4cded108

Add QPDFPageDocumentHelper and QPDFPageObjectHelper

This is the beginning of higher-level API support using helper
classes. The goal is to be able to add more helpers without continuing
to pollute QPDF's and QPDFObjectHandle's public interfaces.
ChangeLog
  1 +2018-06-20 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Added new classes QPDFPageDocumentHelper and QPDFPageObjctHelper
  4 + for page-level API functions. These classes introduce a new API
  5 + pattern of document helpers and object helpers in qpdf. The helper
  6 + classes provide a higher level API for working with certain types
  7 + of structural features of PDF while still staying true to qpdf's
  8 + philosophy of not isolating the user from the underlying
  9 + structure. Please see the chapter in the documentation entitled
  10 + "Design and Library Notes" for additional discussion.
  11 +
1 2018-06-19 Jay Berkenbilt <ejb@ql.org> 12 2018-06-19 Jay Berkenbilt <ejb@ql.org>
2 13
3 * New QPDFObject::Rectangle class will convert to and from arrays 14 * New QPDFObject::Rectangle class will convert to and from arrays
include/qpdf/QPDF.hh
@@ -452,15 +452,17 @@ class QPDF @@ -452,15 +452,17 @@ class QPDF
452 void optimize(std::map<int, int> const& object_stream_data, 452 void optimize(std::map<int, int> const& object_stream_data,
453 bool allow_changes = true); 453 bool allow_changes = true);
454 454
455 - // Convenience routines for common functions. See also  
456 - // QPDFObjectHandle.hh for additional convenience routines.  
457 -  
458 - // Page handling API  
459 -  
460 - // Traverse page tree return all /Page objects. Note that calls  
461 - // to page manipulation APIs will change the internal vector that  
462 - // this routine returns a pointer to. If you don't want that,  
463 - // assign this to a regular vector rather than a const reference. 455 + // Traverse page tree return all /Page objects. For efficiency,
  456 + // this method returns a const reference to an internal vector of
  457 + // pages. Calls to addPage, addPageAt, and removePage safely
  458 + // update this, but directly manipulation of the pages three or
  459 + // pushing inheritable objects to the page level may invalidate
  460 + // it. See comments for updateAllPagesCache() for additional
  461 + // notes. Newer code should use
  462 + // QPDFPageDocumentHelper::getAllPages instead. The decision to
  463 + // expose this internal cache was arguably incorrect, but it is
  464 + // being left here for compatibility. It is, however, completely
  465 + // safe to use this for files that you are not modifying.
464 QPDF_DLL 466 QPDF_DLL
465 std::vector<QPDFObjectHandle> const& getAllPages(); 467 std::vector<QPDFObjectHandle> const& getAllPages();
466 468
@@ -479,32 +481,25 @@ class QPDF @@ -479,32 +481,25 @@ class QPDF
479 QPDF_DLL 481 QPDF_DLL
480 void updateAllPagesCache(); 482 void updateAllPagesCache();
481 483
482 - // The PDF /Pages tree allows inherited values. Working with  
483 - // the pages of a pdf is much easier when the inheritance is  
484 - // resolved by explicitly setting the values in each /Page. 484 + // Legacy handling API. These methods are not going anywhere, and
  485 + // you should feel free to continue using them if it simplifies
  486 + // your code. Newer code should make use of QPDFPageDocumentHelper
  487 + // instead as future page handling methods will be added there.
  488 + // The functionality and specification of these legacy methods is
  489 + // identical to the identically named methods there, except that
  490 + // these versions use QPDFObjectHandle instead of
  491 + // QPDFPageObjectHelper, so please see comments in that file for
  492 + // descriptions.
485 QPDF_DLL 493 QPDF_DLL
486 void pushInheritedAttributesToPage(); 494 void pushInheritedAttributesToPage();
487 -  
488 - // Add new page at the beginning or the end of the current pdf.  
489 - // The newpage parameter may be either a direct object, an  
490 - // indirect object from this QPDF, or an indirect object from  
491 - // another QPDF. If it is a direct object, it will be made  
492 - // indirect. If it is an indirect object from another QPDF, this  
493 - // method will call pushInheritedAttributesToPage on the other  
494 - // file and then copy the page to this QPDF using the same  
495 - // underlying code as copyForeignObject.  
496 QPDF_DLL 495 QPDF_DLL
497 void addPage(QPDFObjectHandle newpage, bool first); 496 void addPage(QPDFObjectHandle newpage, bool first);
498 -  
499 - // Add new page before or after refpage. See comments for addPage  
500 - // for details about what newpage should be.  
501 QPDF_DLL 497 QPDF_DLL
502 void addPageAt(QPDFObjectHandle newpage, bool before, 498 void addPageAt(QPDFObjectHandle newpage, bool before,
503 QPDFObjectHandle refpage); 499 QPDFObjectHandle refpage);
504 -  
505 - // Remove page from the pdf.  
506 QPDF_DLL 500 QPDF_DLL
507 void removePage(QPDFObjectHandle page); 501 void removePage(QPDFObjectHandle page);
  502 + // End legacy page helpers
508 503
509 // Writer class is restricted to QPDFWriter so that only it can 504 // Writer class is restricted to QPDFWriter so that only it can
510 // call certain methods. 505 // call certain methods.
include/qpdf/QPDFDocumentHelper.hh 0 โ†’ 100644
  1 +// Copyright (c) 2005-2018 Jay Berkenbilt
  2 +//
  3 +// This file is part of qpdf.
  4 +//
  5 +// Licensed under the Apache License, Version 2.0 (the "License");
  6 +// you may not use this file except in compliance with the License.
  7 +// You may obtain a copy of the License at
  8 +//
  9 +// http://www.apache.org/licenses/LICENSE-2.0
  10 +//
  11 +// Unless required by applicable law or agreed to in writing, software
  12 +// distributed under the License is distributed on an "AS IS" BASIS,
  13 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +// See the License for the specific language governing permissions and
  15 +// limitations under the License.
  16 +//
  17 +// Versions of qpdf prior to version 7 were released under the terms
  18 +// of version 2.0 of the Artistic License. At your option, you may
  19 +// continue to consider qpdf to be licensed under those terms. Please
  20 +// see the manual for additional information.
  21 +
  22 +#ifndef __QPDFDOCUMENTHELPER_HH__
  23 +#define __QPDFDOCUMENTHELPER_HH__
  24 +
  25 +#include <qpdf/DLL.h>
  26 +#include <qpdf/QPDF.hh>
  27 +
  28 +// This is a base class for QPDF Document Helper classes. Document
  29 +// helpers are classes that provide a convenient, higher-level API for
  30 +// accessing document-level structures with a PDF file. Document
  31 +// helpers are always initialized with a reference to a QPDF object,
  32 +// and the object can always be retrieved. The intention is that you
  33 +// may freely intermix use of document helpers with the underlying
  34 +// QPDF object unless there is a specific comment in a specific helper
  35 +// method that says otherwise. The pattern of using helper objects was
  36 +// introduced to allow creation of higher level helper functions
  37 +// without polluting the public interface of QPDF.
  38 +
  39 +class QPDFDocumentHelper
  40 +{
  41 + public:
  42 + QPDF_DLL
  43 + QPDFDocumentHelper(QPDF& qpdf) :
  44 + qpdf(qpdf)
  45 + {
  46 + }
  47 + QPDF_DLL
  48 + QPDF& getQPDF()
  49 + {
  50 + return this->qpdf;
  51 + }
  52 + QPDF_DLL
  53 + QPDF const& getQPDF() const
  54 + {
  55 + return this->qpdf;
  56 + }
  57 +
  58 + protected:
  59 + QPDF& qpdf;
  60 +};
  61 +
  62 +#endif // __QPDFDOCUMENTHELPER_HH__
include/qpdf/QPDFObjectHandle.hh
@@ -278,37 +278,21 @@ class QPDFObjectHandle @@ -278,37 +278,21 @@ class QPDFObjectHandle
278 StringDecrypter* decrypter, 278 StringDecrypter* decrypter,
279 QPDF* context); 279 QPDF* context);
280 280
281 - // Helpers for parsing content streams  
282 -  
283 - // Parse a page's contents through ParserCallbacks, described  
284 - // above. This method works whether the contents are a single  
285 - // stream or an array of streams. Call on a page object.  
286 - QPDF_DLL  
287 - void parsePageContents(ParserCallbacks* callbacks);  
288 -  
289 - // Pass a page's contents through the given TokenFilter. If a  
290 - // pipeline is also provided, it will be the target of the write  
291 - // methods from the token filter. If a pipeline is not specified,  
292 - // any output generated by the token filter will be discarded. Use  
293 - // this interface if you need to pass a page's contents through  
294 - // filter for work purposes without having that filter  
295 - // automatically applied to the page's contents, as happens with  
296 - // addContentTokenFilter. See examples/pdf-count-strings.cc for an  
297 - // example.  
298 - QPDF_DLL  
299 - void filterPageContents(TokenFilter* filter, Pipeline* next = 0);  
300 -  
301 - // Pipe a page's contents through the given pipeline. This method  
302 - // works whether the contents are a single stream or an array of  
303 - // streams. Call on a page object. 281 + // Older method: stream_or_array should be the value of /Contents
  282 + // from a page object. It's more convenient to just call
  283 + // QPDFPageObjectHelper::parsePageContents on the page object, and
  284 + // error messages will also be more useful because the page object
  285 + // information will be known.
304 QPDF_DLL 286 QPDF_DLL
305 - void pipePageContents(Pipeline* p); 287 + static void parseContentStream(QPDFObjectHandle stream_or_array,
  288 + ParserCallbacks* callbacks);
306 289
307 // When called on a stream or stream array that is some page's 290 // When called on a stream or stream array that is some page's
308 // content streams, do the same as pipePageContents. This method 291 // content streams, do the same as pipePageContents. This method
309 - // is a lower level way to do what pipePageContents does, but it  
310 - // allows you to perform this operation on a contents object that  
311 - // is disconnected from a page object. The description argument 292 + // is a lower level way to do what
  293 + // QPDFPageObjectHelper::pipePageContents does, but it allows you
  294 + // to perform this operation on a contents object that is
  295 + // disconnected from a page object. The description argument
312 // should describe the containing page and is used in error 296 // should describe the containing page and is used in error
313 // messages. The all_description argument is initialized to 297 // messages. The all_description argument is initialized to
314 // something that could be used to describe the result of the 298 // something that could be used to describe the result of the
@@ -318,32 +302,33 @@ class QPDFObjectHandle @@ -318,32 +302,33 @@ class QPDFObjectHandle
318 void pipeContentStreams(Pipeline* p, std::string const& description, 302 void pipeContentStreams(Pipeline* p, std::string const& description,
319 std::string& all_description); 303 std::string& all_description);
320 304
321 - // Older method: stream_or_array should be the value of /Contents  
322 - // from a page object. It's more convenient to just call  
323 - // parsePageContents on the page object, and error messages will  
324 - // also be more useful because the page object information will be  
325 - // known.  
326 - QPDF_DLL  
327 - static void parseContentStream(QPDFObjectHandle stream_or_array,  
328 - ParserCallbacks* callbacks);  
329 -  
330 - // Attach a token filter to a page's contents. If the page's  
331 - // contents is an array of streams, it is automatically coalesced.  
332 - // The token filter is applied to the page's contents as a single  
333 - // stream.  
334 - QPDF_DLL  
335 - void addContentTokenFilter(PointerHolder<TokenFilter> token_filter);  
336 -  
337 // As of qpdf 8, it is possible to add custom token filters to a 305 // As of qpdf 8, it is possible to add custom token filters to a
338 // stream. The tokenized stream data is passed through the token 306 // stream. The tokenized stream data is passed through the token
339 // filter after all original filters but before content stream 307 // filter after all original filters but before content stream
340 // normalization if requested. This is a low-level interface to 308 // normalization if requested. This is a low-level interface to
341 // add it to a stream. You will usually want to call 309 // add it to a stream. You will usually want to call
342 - // addContentTokenFilter instead, which can be applied to a page  
343 - // object, and which will automatically handle the case of pages  
344 - // whose contents are split across multiple streams. 310 + // QPDFPageObjectHelper::addContentTokenFilter instead, which can
  311 + // be applied to a page object, and which will automatically
  312 + // handle the case of pages whose contents are split across
  313 + // multiple streams.
345 void addTokenFilter(PointerHolder<TokenFilter> token_filter); 314 void addTokenFilter(PointerHolder<TokenFilter> token_filter);
346 315
  316 + // Legacy helpers for parsing content streams. These methods are
  317 + // not going away, but newer code should call the correspond
  318 + // methods in QPDFPageObjectHelper instead. The specification and
  319 + // behavior of these methods are the same as the identically named
  320 + // methods in that class, but newer functionality will be added
  321 + // there.
  322 + QPDF_DLL
  323 + void parsePageContents(ParserCallbacks* callbacks);
  324 + QPDF_DLL
  325 + void filterPageContents(TokenFilter* filter, Pipeline* next = 0);
  326 + QPDF_DLL
  327 + void pipePageContents(Pipeline* p);
  328 + QPDF_DLL
  329 + void addContentTokenFilter(PointerHolder<TokenFilter> token_filter);
  330 + // End legacy content stream helpers
  331 +
347 // Type-specific factories 332 // Type-specific factories
348 QPDF_DLL 333 QPDF_DLL
349 static QPDFObjectHandle newNull(); 334 static QPDFObjectHandle newNull();
@@ -731,51 +716,22 @@ class QPDFObjectHandle @@ -731,51 +716,22 @@ class QPDFObjectHandle
731 QPDF_DLL 716 QPDF_DLL
732 std::string unparseResolved(); 717 std::string unparseResolved();
733 718
734 - // Convenience routines for commonly performed functions  
735 -  
736 - // Returns an empty map if there are no images or no resources.  
737 - // This function does not presently support inherited resources.  
738 - // If this is a significant concern, call  
739 - // pushInheritedAttributesToPage() on the QPDF object that owns  
740 - // this page. See comment in the source for details. Return value  
741 - // is a map from XObject name to the image object, which is always  
742 - // a stream. 719 + // Legacy helper methods for commonly performed operations on
  720 + // pages. Newer code should use QPDFPageObjectHelper instead. The
  721 + // specification and behavior of these methods are the same as the
  722 + // identically named methods in that class, but newer
  723 + // functionality will be added there.
743 QPDF_DLL 724 QPDF_DLL
744 std::map<std::string, QPDFObjectHandle> getPageImages(); 725 std::map<std::string, QPDFObjectHandle> getPageImages();
745 -  
746 - // Returns a vector of stream objects representing the content  
747 - // streams for the given page. This routine allows the caller to  
748 - // not care whether there are one or more than one content streams  
749 - // for a page.  
750 QPDF_DLL 726 QPDF_DLL
751 std::vector<QPDFObjectHandle> getPageContents(); 727 std::vector<QPDFObjectHandle> getPageContents();
752 -  
753 - // Add the given object as a new content stream for this page. If  
754 - // parameter 'first' is true, add to the beginning. Otherwise, add  
755 - // to the end. This routine automatically converts the page  
756 - // contents to an array if it is a scalar, allowing the caller not  
757 - // to care what the initial structure is. You can call  
758 - // coalesceContentStreams() afterwards if you want to force it to  
759 - // be a single stream.  
760 QPDF_DLL 728 QPDF_DLL
761 void addPageContents(QPDFObjectHandle contents, bool first); 729 void addPageContents(QPDFObjectHandle contents, bool first);
762 -  
763 - // Rotate a page. If relative is false, set the rotation of the  
764 - // page to angle. Otherwise, add angle to the rotation of the  
765 - // page. Angle must be a multiple of 90. Adding 90 to the rotation  
766 - // rotates clockwise by 90 degrees.  
767 QPDF_DLL 730 QPDF_DLL
768 void rotatePage(int angle, bool relative); 731 void rotatePage(int angle, bool relative);
769 -  
770 - // Coalesce a page's content streams. A page's content may be a  
771 - // stream or an array of streams. If this page's content is an  
772 - // array, concatenate the streams into a single stream. This can  
773 - // be useful when working with files that split content streams in  
774 - // arbitrary spots, such as in the middle of a token, as that can  
775 - // confuse some software. You could also call this after calling  
776 - // addPageContents.  
777 QPDF_DLL 732 QPDF_DLL
778 void coalesceContentStreams(); 733 void coalesceContentStreams();
  734 + // End legacy page helpers
779 735
780 // Issue a warning about this object if possible. If the object 736 // Issue a warning about this object if possible. If the object
781 // has a description, a warning will be issued. Otherwise, if 737 // has a description, a warning will be issued. Otherwise, if
include/qpdf/QPDFObjectHelper.hh 0 โ†’ 100644
  1 +// Copyright (c) 2005-2018 Jay Berkenbilt
  2 +//
  3 +// This file is part of qpdf.
  4 +//
  5 +// Licensed under the Apache License, Version 2.0 (the "License");
  6 +// you may not use this file except in compliance with the License.
  7 +// You may obtain a copy of the License at
  8 +//
  9 +// http://www.apache.org/licenses/LICENSE-2.0
  10 +//
  11 +// Unless required by applicable law or agreed to in writing, software
  12 +// distributed under the License is distributed on an "AS IS" BASIS,
  13 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +// See the License for the specific language governing permissions and
  15 +// limitations under the License.
  16 +//
  17 +// Versions of qpdf prior to version 7 were released under the terms
  18 +// of version 2.0 of the Artistic License. At your option, you may
  19 +// continue to consider qpdf to be licensed under those terms. Please
  20 +// see the manual for additional information.
  21 +
  22 +#ifndef __QPDFOBJECTHELPER_HH__
  23 +#define __QPDFOBJECTHELPER_HH__
  24 +
  25 +#include <qpdf/DLL.h>
  26 +
  27 +#include <qpdf/QPDFObjectHandle.hh>
  28 +
  29 +// This is a base class for QPDF Object Helper classes. Object helpers
  30 +// are classes that provide a convenient, higher-level API for working
  31 +// with specific types of QPDF objects. Object helpers are always
  32 +// initialized with a QPDFObjectHandle, and the underlying object
  33 +// handle can always be retrieved. The intention is that you may
  34 +// freely intermix use of document helpers with the underlying QPDF
  35 +// objects unless there is a specific comment in a specific helper
  36 +// method that says otherwise. The pattern of using helper objects was
  37 +// introduced to allow creation of higher level helper functions
  38 +// without polluting the public interface of QPDFObjectHandle.
  39 +
  40 +class QPDFObjectHelper
  41 +{
  42 + public:
  43 + QPDF_DLL
  44 + QPDFObjectHelper(QPDFObjectHandle oh) :
  45 + oh(oh)
  46 + {
  47 + }
  48 + QPDF_DLL
  49 + QPDFObjectHandle getObjectHandle()
  50 + {
  51 + return this->oh;
  52 + }
  53 + QPDF_DLL
  54 + QPDFObjectHandle const getObjectHandle() const
  55 + {
  56 + return this->oh;
  57 + }
  58 +
  59 + protected:
  60 + QPDFObjectHandle oh;
  61 +};
  62 +
  63 +#endif // __QPDFOBJECTHELPER_HH__
include/qpdf/QPDFPageDocumentHelper.hh 0 โ†’ 100644
  1 +// Copyright (c) 2005-2018 Jay Berkenbilt
  2 +//
  3 +// This file is part of qpdf.
  4 +//
  5 +// Licensed under the Apache License, Version 2.0 (the "License");
  6 +// you may not use this file except in compliance with the License.
  7 +// You may obtain a copy of the License at
  8 +//
  9 +// http://www.apache.org/licenses/LICENSE-2.0
  10 +//
  11 +// Unless required by applicable law or agreed to in writing, software
  12 +// distributed under the License is distributed on an "AS IS" BASIS,
  13 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +// See the License for the specific language governing permissions and
  15 +// limitations under the License.
  16 +//
  17 +// Versions of qpdf prior to version 7 were released under the terms
  18 +// of version 2.0 of the Artistic License. At your option, you may
  19 +// continue to consider qpdf to be licensed under those terms. Please
  20 +// see the manual for additional information.
  21 +
  22 +#ifndef __QPDFPAGEDOCUMENTHELPER_HH__
  23 +#define __QPDFPAGEDOCUMENTHELPER_HH__
  24 +
  25 +#include <qpdf/QPDFDocumentHelper.hh>
  26 +#include <qpdf/QPDFPageObjectHelper.hh>
  27 +
  28 +#include <qpdf/DLL.h>
  29 +
  30 +#include <vector>
  31 +
  32 +#include <qpdf/QPDF.hh>
  33 +
  34 +class QPDFPageDocumentHelper: public QPDFDocumentHelper
  35 +{
  36 + public:
  37 + QPDFPageDocumentHelper(QPDF&);
  38 +
  39 + // Traverse page tree, and return all /Page objects wrapped in
  40 + // QPDFPageObjectHelper objects. Unlike with
  41 + // QPDFObjectHandle::getAllPages, the vector of pages returned by
  42 + // this call is not affected by additions or removals of pages. If
  43 + // you manipulate pages, you will have to call this again to get a
  44 + // new copy. Please comments in QPDFObjectHandle.hh for
  45 + // getAllPages() for additional details.
  46 + QPDF_DLL
  47 + std::vector<QPDFPageObjectHelper> getAllPages();
  48 +
  49 + // The PDF /Pages tree allows inherited values. Working with the
  50 + // pages of a pdf is much easier when the inheritance is resolved
  51 + // by explicitly setting the values in each /Page.
  52 + QPDF_DLL
  53 + void pushInheritedAttributesToPage();
  54 +
  55 + // Add new page at the beginning or the end of the current pdf.
  56 + // The newpage parameter may be either a direct object, an
  57 + // indirect object from this QPDF, or an indirect object from
  58 + // another QPDF. If it is a direct object, it will be made
  59 + // indirect. If it is an indirect object from another QPDF, this
  60 + // method will call pushInheritedAttributesToPage on the other
  61 + // file and then copy the page to this QPDF using the same
  62 + // underlying code as copyForeignObject.
  63 + QPDF_DLL
  64 + void addPage(QPDFPageObjectHelper newpage, bool first);
  65 +
  66 + // Add new page before or after refpage. See comments for addPage
  67 + // for details about what newpage should be.
  68 + QPDF_DLL
  69 + void addPageAt(QPDFPageObjectHelper newpage, bool before,
  70 + QPDFPageObjectHelper refpage);
  71 +
  72 + // Remove page from the pdf.
  73 + QPDF_DLL
  74 + void removePage(QPDFPageObjectHelper page);
  75 +
  76 + private:
  77 + class Members
  78 + {
  79 + friend class QPDFPageDocumentHelper;
  80 +
  81 + public:
  82 + ~Members();
  83 +
  84 + private:
  85 + Members();
  86 + Members(Members const&);
  87 + };
  88 +
  89 + PointerHolder<Members> m;
  90 +};
  91 +
  92 +#endif // __QPDFPAGEDOCUMENTHELPER_HH__
include/qpdf/QPDFPageObjectHelper.hh 0 โ†’ 100644
  1 +// Copyright (c) 2005-2018 Jay Berkenbilt
  2 +//
  3 +// This file is part of qpdf.
  4 +//
  5 +// Licensed under the Apache License, Version 2.0 (the "License");
  6 +// you may not use this file except in compliance with the License.
  7 +// You may obtain a copy of the License at
  8 +//
  9 +// http://www.apache.org/licenses/LICENSE-2.0
  10 +//
  11 +// Unless required by applicable law or agreed to in writing, software
  12 +// distributed under the License is distributed on an "AS IS" BASIS,
  13 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +// See the License for the specific language governing permissions and
  15 +// limitations under the License.
  16 +//
  17 +// Versions of qpdf prior to version 7 were released under the terms
  18 +// of version 2.0 of the Artistic License. At your option, you may
  19 +// continue to consider qpdf to be licensed under those terms. Please
  20 +// see the manual for additional information.
  21 +
  22 +#ifndef __QPDFPAGEOBJECTHELPER_HH__
  23 +#define __QPDFPAGEOBJECTHELPER_HH__
  24 +
  25 +#include <qpdf/QPDFObjectHelper.hh>
  26 +
  27 +#include <qpdf/DLL.h>
  28 +
  29 +#include <qpdf/QPDFObjectHandle.hh>
  30 +
  31 +class QPDFPageObjectHelper: public QPDFObjectHelper
  32 +{
  33 + public:
  34 + QPDFPageObjectHelper(QPDFObjectHandle);
  35 +
  36 + // Returns an empty map if there are no images or no resources.
  37 + // This function does not presently support inherited resources.
  38 + // If this is a significant concern, call
  39 + // pushInheritedAttributesToPage() on the QPDF object that owns
  40 + // this page. See comment in the source for details. Return value
  41 + // is a map from XObject name to the image object, which is always
  42 + // a stream.
  43 + QPDF_DLL
  44 + std::map<std::string, QPDFObjectHandle> getPageImages();
  45 +
  46 + // Returns a vector of stream objects representing the content
  47 + // streams for the given page. This routine allows the caller to
  48 + // not care whether there are one or more than one content streams
  49 + // for a page.
  50 + QPDF_DLL
  51 + std::vector<QPDFObjectHandle> getPageContents();
  52 +
  53 + // Add the given object as a new content stream for this page. If
  54 + // parameter 'first' is true, add to the beginning. Otherwise, add
  55 + // to the end. This routine automatically converts the page
  56 + // contents to an array if it is a scalar, allowing the caller not
  57 + // to care what the initial structure is. You can call
  58 + // coalesceContentStreams() afterwards if you want to force it to
  59 + // be a single stream.
  60 + QPDF_DLL
  61 + void addPageContents(QPDFObjectHandle contents, bool first);
  62 +
  63 + // Rotate a page. If relative is false, set the rotation of the
  64 + // page to angle. Otherwise, add angle to the rotation of the
  65 + // page. Angle must be a multiple of 90. Adding 90 to the rotation
  66 + // rotates clockwise by 90 degrees.
  67 + QPDF_DLL
  68 + void rotatePage(int angle, bool relative);
  69 +
  70 + // Coalesce a page's content streams. A page's content may be a
  71 + // stream or an array of streams. If this page's content is an
  72 + // array, concatenate the streams into a single stream. This can
  73 + // be useful when working with files that split content streams in
  74 + // arbitrary spots, such as in the middle of a token, as that can
  75 + // confuse some software. You could also call this after calling
  76 + // addPageContents.
  77 + QPDF_DLL
  78 + void coalesceContentStreams();
  79 +
  80 + //
  81 + // Content stream handling
  82 + //
  83 +
  84 + // Parse a page's contents through ParserCallbacks, described
  85 + // above. This method works whether the contents are a single
  86 + // stream or an array of streams. Call on a page object.
  87 + QPDF_DLL
  88 + void parsePageContents(QPDFObjectHandle::ParserCallbacks* callbacks);
  89 +
  90 + // Pass a page's contents through the given TokenFilter. If a
  91 + // pipeline is also provided, it will be the target of the write
  92 + // methods from the token filter. If a pipeline is not specified,
  93 + // any output generated by the token filter will be discarded. Use
  94 + // this interface if you need to pass a page's contents through
  95 + // filter for work purposes without having that filter
  96 + // automatically applied to the page's contents, as happens with
  97 + // addContentTokenFilter. See examples/pdf-count-strings.cc for an
  98 + // example.
  99 + QPDF_DLL
  100 + void filterPageContents(QPDFObjectHandle::TokenFilter* filter,
  101 + Pipeline* next = 0);
  102 +
  103 + // Pipe a page's contents through the given pipeline. This method
  104 + // works whether the contents are a single stream or an array of
  105 + // streams. Call on a page object.
  106 + QPDF_DLL
  107 + void pipePageContents(Pipeline* p);
  108 +
  109 + // Attach a token filter to a page's contents. If the page's
  110 + // contents is an array of streams, it is automatically coalesced.
  111 + // The token filter is applied to the page's contents as a single
  112 + // stream.
  113 + QPDF_DLL
  114 + void addContentTokenFilter(
  115 + PointerHolder<QPDFObjectHandle::TokenFilter> token_filter);
  116 +
  117 + private:
  118 + class Members
  119 + {
  120 + friend class QPDFPageObjectHelper;
  121 +
  122 + public:
  123 + ~Members();
  124 +
  125 + private:
  126 + Members();
  127 + Members(Members const&);
  128 + };
  129 +
  130 + PointerHolder<Members> m;
  131 +};
  132 +
  133 +#endif // __QPDFPAGEOBJECTHELPER_HH__
libqpdf/QPDFPageDocumentHelper.cc 0 โ†’ 100644
  1 +#include <qpdf/QPDFPageDocumentHelper.hh>
  2 +
  3 +QPDFPageDocumentHelper::Members::~Members()
  4 +{
  5 +}
  6 +
  7 +QPDFPageDocumentHelper::Members::Members()
  8 +{
  9 +}
  10 +
  11 +QPDFPageDocumentHelper::QPDFPageDocumentHelper(QPDF& qpdf) :
  12 + QPDFDocumentHelper(qpdf)
  13 +{
  14 +}
  15 +
  16 +std::vector<QPDFPageObjectHelper>
  17 +QPDFPageDocumentHelper::getAllPages()
  18 +{
  19 + std::vector<QPDFObjectHandle> const& pages_v = this->qpdf.getAllPages();
  20 + std::vector<QPDFPageObjectHelper> pages;
  21 + for (std::vector<QPDFObjectHandle>::const_iterator iter = pages_v.begin();
  22 + iter != pages_v.end(); ++iter)
  23 + {
  24 + pages.push_back(QPDFPageObjectHelper(*iter));
  25 + }
  26 + return pages;
  27 +}
  28 +
  29 +void
  30 +QPDFPageDocumentHelper::pushInheritedAttributesToPage()
  31 +{
  32 + this->qpdf.pushInheritedAttributesToPage();
  33 +}
  34 +
  35 +void
  36 +QPDFPageDocumentHelper::addPage(QPDFPageObjectHelper newpage, bool first)
  37 +{
  38 + this->qpdf.addPage(newpage.getObjectHandle(), first);
  39 +}
  40 +
  41 +void
  42 +QPDFPageDocumentHelper::addPageAt(QPDFPageObjectHelper newpage, bool before,
  43 + QPDFPageObjectHelper refpage)
  44 +{
  45 + this->qpdf.addPageAt(newpage.getObjectHandle(), before,
  46 + refpage.getObjectHandle());
  47 +}
  48 +
  49 +void
  50 +QPDFPageDocumentHelper::removePage(QPDFPageObjectHelper page)
  51 +{
  52 + this->qpdf.removePage(page.getObjectHandle());
  53 +}
libqpdf/QPDFPageObjectHelper.cc 0 โ†’ 100644
  1 +#include <qpdf/QPDFPageObjectHelper.hh>
  2 +
  3 +QPDFPageObjectHelper::Members::~Members()
  4 +{
  5 +}
  6 +
  7 +QPDFPageObjectHelper::Members::Members()
  8 +{
  9 +}
  10 +
  11 +QPDFPageObjectHelper::QPDFPageObjectHelper(QPDFObjectHandle oh) :
  12 + QPDFObjectHelper(oh)
  13 +{
  14 +}
  15 +
  16 +std::map<std::string, QPDFObjectHandle>
  17 +QPDFPageObjectHelper::getPageImages()
  18 +{
  19 + return this->oh.getPageImages();
  20 +}
  21 +
  22 +std::vector<QPDFObjectHandle>
  23 +QPDFPageObjectHelper::getPageContents()
  24 +{
  25 + return this->oh.getPageContents();
  26 +}
  27 +
  28 +void
  29 +QPDFPageObjectHelper::addPageContents(QPDFObjectHandle contents, bool first)
  30 +{
  31 + this->oh.addPageContents(contents, first);
  32 +}
  33 +
  34 +void
  35 +QPDFPageObjectHelper::rotatePage(int angle, bool relative)
  36 +{
  37 + this->oh.rotatePage(angle, relative);
  38 +}
  39 +
  40 +void
  41 +QPDFPageObjectHelper::coalesceContentStreams()
  42 +{
  43 + this->oh.coalesceContentStreams();
  44 +}
  45 +
  46 +void
  47 +QPDFPageObjectHelper::parsePageContents(
  48 + QPDFObjectHandle::ParserCallbacks* callbacks)
  49 +{
  50 + this->oh.parsePageContents(callbacks);
  51 +}
  52 +
  53 +void
  54 +QPDFPageObjectHelper::filterPageContents(
  55 + QPDFObjectHandle::TokenFilter* filter,
  56 + Pipeline* next)
  57 +{
  58 + this->oh.filterPageContents(filter, next);
  59 +}
  60 +
  61 +void
  62 +QPDFPageObjectHelper::pipePageContents(Pipeline* p)
  63 +{
  64 + this->oh.pipePageContents(p);
  65 +}
  66 +
  67 +void
  68 +QPDFPageObjectHelper::addContentTokenFilter(
  69 + PointerHolder<QPDFObjectHandle::TokenFilter> token_filter)
  70 +{
  71 + this->oh.addContentTokenFilter(token_filter);
  72 +}
libqpdf/build.mk
@@ -39,6 +39,8 @@ SRCS_libqpdf = \ @@ -39,6 +39,8 @@ SRCS_libqpdf = \
39 libqpdf/QPDFObjGen.cc \ 39 libqpdf/QPDFObjGen.cc \
40 libqpdf/QPDFObject.cc \ 40 libqpdf/QPDFObject.cc \
41 libqpdf/QPDFObjectHandle.cc \ 41 libqpdf/QPDFObjectHandle.cc \
  42 + libqpdf/QPDFPageDocumentHelper.cc \
  43 + libqpdf/QPDFPageObjectHelper.cc \
42 libqpdf/QPDFTokenizer.cc \ 44 libqpdf/QPDFTokenizer.cc \
43 libqpdf/QPDFWriter.cc \ 45 libqpdf/QPDFWriter.cc \
44 libqpdf/QPDFXRefEntry.cc \ 46 libqpdf/QPDFXRefEntry.cc \