* Add Named Destinations to Catalog so that bookmarks and links can access
them.
The named destinations require access to page nodes, so created Pages object
that is made using PagesFactory (which contains the page-related code from
Catalog).
* Further implementation of destinations:
- Implement NamedDestinations in AnnotationProvider, so that we can look
up named destinations for annotations and turn them into explicit destinations.
Reused existing code inside BookmarksProvider to get destinations/actions.
- Added GoToE action
- According to the PDF reference, destinations are also required for
external destinations and hence for ExternalBookmarkNode. This allows us
to push up DocumentBookmarkNode.Destination to BookmarkNode.
* Implemented stateful appearance streams and integration test
* Added AppearanceStream to public API because it is used in the (public)
Annotation constructor
* After #552, must push down ExplicitDestination do DocumentBookmarkNode since it
does not apply to UriBookmarkNode.
* Added actions, which fits the PDF model better and works well with the
new bookmarks code (after PR #552)
* Rename Action to PdfAction + removed unused using in ActionProvider.cs
---------
Co-authored-by: mvantzet <mark@radialsg.com>
- Pass in the initial matrix to the annotation provider, so that it can return
the correct rectangles / quad points.
- Made a change / extensions to the Annotation class:
- ModifiedDate is now a DateTimeOffset instead of unparsed string.
If the string is invalid, ModifiedDate is set to the default value.
- Added lookup for the "appearance streams"; all the annotations should have
a "N" (normal) appearance, and optionally have a "R" (roll-over/hover)
and "D" (down/click) appearance. Did not expose the actual stream objects,
but added a flag indicating the existence of "R" / "D". At some point
we can consider doing something with the appearances.
- Changed signature of GetInitialMatrix / ContentStreamProcessor constructor
from PdfRectangle back to what it was earlier, namely MediaBox and CropBox,
to prevent accidentally mixing the two up in the caller.
The initial transformation matrix was incorrect, as it translated by the cropbox width/height
instead of by the cropbox left/bottom offsets. Also, it did not translate the results back into
the 1st quadrant so that (0,0) would (again) be the lower left corner origin for the cropped area.
Added unit tests in new file ContentStreamProcessorTests.
EFFECTIVE CHANGES:
- The coordinates used for letters etc. are different now for rotated and/or cropped pages,
but as those were not very consistent anyway this is probably OK.
- The Page Size (A4, A3, Custom, etc.), Width and Height are now determined by the CropBox,
not by the MediaBox; the CropBox ultimately determines what you see on screen and is printable.
If no cropbox is defined in the PDF, it is set to the MediaBox; so in that case it is
backwards compatible with the old code.
- The Page MediaBox and CropBox properties are no longer rotated according to Page.Rotation.
The Page Width and Height do take rotation into account (kept it backward compatible).