txt: ## dist_zef-dwarring-PDF-API6.md
  ## Chunk 1 of 3
  [[Raku PDF Project]](https://pdf-raku.github.io)
  / [PDF::API6](https://pdf-raku.github.io/PDF-API6)
  [![](https://travis-ci.org/pdf-raku/PDF-API6.svg?branch=master)](https://travis-ci.org/pdf-raku/PDF-API6)
  
  # PDF::API6 - A Raku PDF API
  
  * [NAME](#name)
  * [DESCRIPTION](#description)
  * [EXAMPLE](#example)
  * [DIFFERENCES BETWEEN PDF::API2 AND PDF::API6](#differences-between-pdfapi2-and-pdfapi6)
    * [PDF::API6](#pdfapi6)
    * [TODO](#todo)
  * [SYNOPSIS](#synopsis)
  * [SECTION I: Input/Output Methods (inherited from PDF)](#section-i-inputoutput-methods-inherited-from-pdf)
    * [Input/Output](#inputoutput)
      * [new](#new)
      * [open](#open)
      * [update](#update)
      * [save-as](#save-as)
      * [encrypt](#encrypt)
      * [is-encrypted](#is-encrypted)
    * [Serialization Methods](#serialization-methods)
      * [Str, Blob](#str-blob)
      * [ast](#ast)
  * [SECTION II: Content Methods (role PDF::Content::API)](#section-ii-content-methods-role-pdfcontentapi)
    * [Pages](#pages)
      * [page-count](#page-count)
      * [page](#page)
      * [iterate-pages](#iterate-pages)
      * [add-page](#add-page)
      * [delete-page](#delete-page)
    * [Page Methods](#page-methods)
      * [to-xobject](#to-xobject)
      * [images](#images)
      * [media-box, crop-box, trim-box, bleed-box, art-box, bleed](#media-box-crop-box-trim-box-bleed-box-art-box-bleed)
      * [rotate](#rotate)
    * [Graphics Constructor](#graphics-constructor)
      * [gfx](#gfx)
    * [Text Methods](#text-methods)
      * [text](#text)
      * [font, core-font](#font-core-font)
      * [text-position](#text-position)
      * [text-transform](#text-transform)
      * [base-coords](#base-coords)
      * [user-coords](#user-coords)
      * [print](#print)
      * [say](#say)
    * [Graphics Methods](#graphics-methods)
      * [graphics](#graphics)
      * [transform](#transform)
      * [paint](#paint)
    * [Image Methods](#image-methods)
      * [load-image](#load-image)
      * [do](#do)
    * [XObject Forms](#xobject-forms)
      * [xobject-form](#xobject-form)
    * [Patterns](#patterns)
      * [tiling-pattern](#tiling-pattern)
      * [use-pattern](#use-pattern)
    * [Low Level Graphics](#low-level-graphics)
    * [Basic Colors](#basic-colors)
      * [FillColor, FillAlpha](#fillcolor-fillalpha)
      * [StrokeColor, StrokeAlpha](#strokecolor-strokealpha)
      * [Named Colors](#named-colors)
      * [Text Modes](#text-modes)
    * [Rendering Methods](#rendering-methods)
      * [render: :&callback](#render-callback)
      * [html-canvas](#html-canvas)
    * [AcroForm Fields](#acroform-fields)
  * [SECTION III: PDF::API6 Specific Methods](#section-iii-pdfapi6-specific-methods)
    * [Metadata Methods](#metadata-methods)
      * [info](#info)
      * [xmp-metadata](#xmp-metadata)
    * [Settings Methods](#settings-methods)
      * [preferences](#preferences)
      * [version](#version)
    * [Color Management](#color-management)
      * [color-separation](#color-separation)
      * [color-devicen](#color-devicen)
    * [Interactive Features](#interactive-features)
      * [Outlines](#outlines)
      * [Page Labels](#page-labels)
      * [Annotations](#annotations)
      * [Named Destinations](#named-destinations)
    * [Tagged Content](#tagged-content)
      * [tag](#tag)
      * [mark](#mark)
  * [APPENDIX](#appendix)
    * [Appendix I: Graphics](#appendix-i-graphics)
      * [Graphics Variables](#graphics-variables)
      * [Graphic Operators](#graphic-operators)
      * [Graphics State](#graphics-state)
      * [Text Operators](#text-operators)
      * [Path Construction Operators](#path-construction-operators)
      * [Path Painting Operators](#path-painting-operators)
      * [Path Clipping](#path-clipping)
      * [Marked Content](#marked-content)
      * [Graphics Introspection Methods](#graphics-introspection-methods)
      * [Method current-point()](#method-current-point)
      * [Graphics Tracing](#graphics-tracing)
    * [Appendix II: Text Rendering Modes](#appendix-ii-text-rendering-modes)
    * [Appendix III: Module Overview](#appendix-iii-module-overview)
  
  # NAME
  
  PDF::API6 - Facilitates the creation and modification of PDF files
  
  # DESCRIPTION
  
  A Raku PDF module; reminiscent of Perl 5's PDF::API2.
  
  This module is a work in progress in replicating, or mapping the functionality of Perl 5's PDF::API2 tool-chain.
  
  # EXAMPLE
  
  ```
  use v6;
  use PDF::API6;
  use PDF::Page;
  use PDF::XObject::Image;
  use PDF::Content::FontObj;
  
  my PDF::API6 $pdf .= new;
  $pdf.media-box = [0, 0, 200, 100];
  my PDF::Page $page = $pdf.add-page;
  constant Padding = 10;
  
  $page.graphics: {
      enum <x0 y0 x1 y1>;
      my PDF::Content::FontObj $font = $pdf.core-font: :family<Helvetica>, :weight<bold>, :style<italic>;
      my @box = .say: 'Hello, world', :$font, :position[10, 10];
  
      my PDF::XObject::Image $img = .load-image: "t/images/lightbulb.png";
      .do: $img, :position[@box[x1] + Padding, 10];
  }
  
  $pdf.save-as: "tmp/hello-world.pdf";
  
  ```
  
  ![example.pdf](https://raw.githubusercontent.com/pdf-raku/PDF-API6/master/tmp/.previews/hello-world-001.png)
  
  # DIFFERENCES BETWEEN PDF::API2 AND PDF::API6
  
  ## PDF::API6
  
  * Has a Graphics State engine. This is based on the graphics operators and variables as described PDF 32000 chapter 8 "Graphics and the operators".
  * Supports the creation and manipulation of XObject Forms and Patterns.
  * Implements an Object Graph model for data access. A PDF file is modelled as an object tree of Dictionaries (Hashes) and Arrays that contain simpler
    values such as Integers, Reals and Strings.
  
  ## TODO
  
  PDF::API2 features that are not yet available in PDF::API6 include:
  
  * Images. PDF::API6 supports PNG, JPEG and GIF images
  
    * currently not supported are: TIFF and PNM images.
  * Fonts
  
    * Synthetic fonts are NYI (wanted: module PDF::Font::Synthetic)
  
  # SYNOPSIS
  
  ```
  use PDF::API6;
  # Create a blank PDF file
  my PDF::API6 $pdf .= new();
  
  # Open an existing PDF file
  my PDF::API6 $pdf .= open('some.pdf');
  my PDF::API6 $pdf .= new( :file<some.pdf> );
  
  # Add a blank page
  use PDF::Page;
  my PDF::Page $page = $pdf.add-page();
  
  # Retrieve an existing page
  use PDF::Page;
  my PDF::Page $page_2 = $pdf.page(2);
  
  # Set the default page size for all pages
  use PDF::Content::Page :PageSizes;
  $pdf.media-box = A4;
  
  # Set the size of a specific page
  use PDF::Content::Page :PageSizes;
  $page.media-box = Letter;
  
  # Set a landscape page-size
  use PDF::Content::Page :PageSizes, :&to-landscape;
  $page.media-box = to-landscape(Letter);
  
  # Use a standard PDF core font
  use PDF::Content::FontObj;
  constant FontObj = PDF::Content::FontObj;
  my FontObj $font = $pdf.core-font('Helvetica-Bold');
  $font = $pdf.core-font: :family<Helvetica>, :weight<Bold>;
  
  # Add an external TrueType font to the PDF
  # (requires PDF::Font::Loader module to be installed)
  use PDF::Font::Loader;
  $font = PDF::Font::Loader.load-font: :file</path/to/font.ttf>;
  # (requires both PDF::Font::Loader and FontConfig modules)
  $font = PDF::Font::Loader.load-font: :family<Vera>, :weight<Bold>;
  
  # Add some text to the page
  $page.text: {
      .font = $font, 20;
      .text-position = 200, 700;
      .say('Hello World!');
  }
  
  # Save the PDF
  $pdf.save-as('/path/to/new.pdf');
  
  ```
  
  # SECTION I: Input/Output Methods (inherited from PDF)
  
  ## Input/Output
  
  ### new
  
  Creates a new PDF object.
  
  ```
  my PDF::API6 $pdf .= new();
  #...
  dd $pdf.Str;
  $fh.write: $pdf.Blob;
  
  $pdf = PDF::API6.new();
  #...
  $pdf.save-as('our/new.pdf');
  
  ```
  
  ### open
  
  Opens an existing PDF or JSON file.
  
  ```
  my PDF::API6 $pdf .= open('our/old.pdf');
  #...
  $pdf.save-as('our/new.pdf');
  
  # open from a stream
  my PDF::API6 $pdf2 .= open($pdf.Blob);
  
  ```
  
  Open an encrypted document:
  
  ```
  PDF::API6.open( "enc.pdf", :password<sshh!> );
  
  ```
  
  Open a PDF, ignoring indices and stream lengths:
  
  ```
  PDF::API6.open( "damaged-or-edited.pdf", :repair );
  
  ```
  
  ### update
  
  In-place update of a PDF file
  
  ```
  my PDF::API6 $pdf .= open('our/to/be/updated.pdf');
  #...
  $pdf.update();
  
  ```
  
  ### save-as
  
  Save a new or updated PDF document to a file
  
  ```
  my PDF::API6 $pdf .= new;
  #...
  $pdf.save-as: 'our/new.pdf';
  
  ```
  
  The `:preserve` option (default True) keeps the original PDF structure, then applies incremental updates. This is generally faster and also ensures that digital signatures are not invalidated.
  
  ```
  PDF::API6 $pdf .= open("our/original.pdf");
  $pdf.save-as: 'our/updated.pdf', :!preserve;
  
  ```
  
  The `:rebuild` option (default False) rewrites the PDF. This may be useful, if there have been a substantial number of updates.
  
  The `:compress` option is used to ensure stream objects (which generally make up the bulk of a PDF) are compressed. This is useful when maximum compaction is needed.
  
  ```
  PDF::API6 $pdf .= open("our/original.pdf");
  $pdf.save-as: 'our/updated.pdf', :rebuild, :compress;
  
  ```
  
  The reverse flag, `:!compress` is useful when you want to optimise for human-readability of the output PDF. It will uncompress `Flate`, `LZW`, `ASCIIHex` and `ASCII85` encoded streams.
  
  The `:stream` option writes the PDF file progressively, starting as early as possible.
  
  A PDF file can also be saved as, and opened from an intermediate JSON representation, by saving to, or reading from, files with a `.json` extension
  
  ```
  PDF::API6 $pdf .= new;
  #...
  $pdf.save-as: 'our/ast.json';
  # ...
  $pdf.open: 'our/ast.json';
  
  ```
  
  ### encrypt
  
  Encrypt a PDF:
  
  ```
  $pdf.encrypt( :owner-pass<ssh1>, :user-pass<abc>, :aes );
  
  ```
  
  ### is-encrypted
  
  Check if document is encrypted
  
  ```
  if $pdf.is-encrypted { ... }
  
  ```
  
  ## Serialization Methods
  
  ### Str, Blob
  
  Return a binary representation of a PDF as a string, or binary Blob
  
  ```
  my Str $pdf-byte-string = $pdf.Str; # returns a string of latin-1 characters
  my blob8 $bytes = $pdf.Blob;         # returns a Blob[uint8]
  
  ```
  
  ### ast
  
  Return an AST tree representation of a PDF.
  
  ```
  use PDF::IO::Writer;
  my %cos = $pdf.ast;   # returns a nested Hash representation of the PDF
  # write it to a file
  my $pdf-byte-string = PDF::IO::Writer.new.write: |%cos;
  "/tmp/out.pdf".IO.spurt(:bin, $pdf-byte-string);
  
  ```
  
  # SECTION II: Content Methods (role PDF::Content::API)
  
  The methods in this section are performed by PDF::Lite and PDF::API6.
  
  ## Pages
  
  ### page-count
  
  ```
  my UInt $pages = $pdf.page-count;
  
  ```
  
  Returns the number of pages in a PDF.
  
  ### page
  
  ```
  use PDF::Page;
  my PDF::Page $second-page = $pdf.page(2);
  
  ```
  
  Returns the nth page from the PDF
  
  ### iterate-pages
  
  ```
  for $pdf.iterate-pages -> PDF::Page $page { ... }
  my PDF::Page @all-pages = $pdf.iterate-pages;
  my $page-iterator = $pdf.iterate-pages;
  $page-iterator.pull-one for ^$pdf.page-count;
  
  ```
  
  Returns an iterator that traverses all pages in sequence.
  
  ### add-page
  
  Synopsis: `$pdf.add-page($page-object?)`
  
  ```
  my PDF::Page page = $pdf.add-page;
  
  ```
  
  Adds a page to the end of a PDF. Creates a new blank page by default.
  
  ### delete-page
  
  Deletes a page, by page-number
  
  ```
  my PDF::Page $moved-page = $pdf.delete-page(2);
  # re-add the to the end of the PDF
  $pdf.add-page($moved-page);
  
  ```
  
  ## Page Methods
  
  ### to-xobject
  
  Converts a page to an [XObject Form](#xobject-forms).
  
  This is useful if you want to transpose the imported page somewhat differently onto a page (e.g. two-up, four-up, etc.).
  
  Example:
  
  ```
  use PDF::API6;
  use PDF::Page;
  use PDF::XObject;
  use PDF::Content;
  my PDF::API6 $old .= open('our/old.pdf');
  my PDF::API6 $pdf .= new;
  my PDF::Page $page = $pdf.add-page;
  my PDF::Content $gfx = $page.gfx;
  
  # Import first page from the old PDF
  my PDF::XObject $xo = $old.page(1).to-xobject;
  
  # Add it to the new PDF's first page at 1/2 scale
  my $width = $xo.width / 2;
  my $bottom = 5;
  my $left = 10;
  $gfx.do($xo, :position[$bottom, $left], :$width);
  
  $pdf.save-as('our/new.pdf');
  
  
  ```
  
  ### images
  
  Synopsis: `my PDF::XObject::Image @images = $gfx.images: :inline;`
  
  This method extracts image objects for a given page, or other graphical element:
  
  The `:inline` flag will check for any image objects in the graphical content stream.
  
  ### media-box, crop-box, trim-box, bleed-box, art-box, bleed
  
  A page has several different bounding boxes:
  
  * crop-box -- the region of the PDF that is displayed or printed
  * media-box -- width and height of the printed page
  * trim-box -- the intended dimensions of the finished page
  * bleed-box -- the region to which the page contents needs to be clipped when output in a production environment.
  * art-box -- for general use
  
  `bleed` is a convenience method for setting up or showing a bleed gutter area surrounding the trim-box. It should usually be set up after the trim box.
  
  Example:
  
  ```
  use PDF::API6;
  use PDF::Page;
  use PDF::Content::Page :PageSizes;
  sub postfix:<mm>(Numeric $v){ ($v * 2.83).round(1) };
  
  my PDF::API6 $pdf .= new;
  my PDF::Page $page = $pdf.add-page;
  
  # set-up Letter-size trim-box with symmetrical 3mm bleed
  
  $page.trim-box = Letter;
  $page.bleed = 3mm;
  ##  $page.bleed = 3mm, 3mm, 3mm, 3mm; # same as above
  say $page.bleed;     # (8 8 8 8)
  say $page.trim-box;  # [0 0 612 792]
  say $page.bleed-box; # [-8 -8 620 800]
  
  ```
  
  ### rotate
  
  ```
  $page.rotate = 90;
  
  ```
  
  Read/write accessor to rotate the page, clockwise. Angles must be multiples of 90 degrees.
  
  ## Graphics Constructor
  
  ### gfx
  
  Synopsis: `$page.gfx: :&render, :!strict, :trace, :comment`
  
  Options:
  - `:&render` install a rendering call-back (see [Rendering below](#rendering-methods))
  - `:!strict` turn off some warnings, regarding out-of-sequence operations,
  incorrect nesting or un-closed Save, Text or Marked content blocks.
  
  Debugging options:
  - `:trace` print debugging information to $\*ERR
  - `:comment` write explanatory comments into the content stream, including
  operator mnemonics and original un-encoded text. These may make it a bit
  easier for developers to interpret the content stream within the PDF. Note
  that setting both :comment`and`:trace` options will direct the trace output
  output to the content stream as comments.
  
  Graphics form the basis of PDF rendering and display. This includes text, images, graphics, colors and painting.
  
  Pages, XObject Forms and Tiling Patterns all have associated graphics. These can be accessed by the`.gfx` method.
  
  ```
  use v6;
  use PDF::API6;
  use PDF::Content;
  
  my PDF::API6 $pdf .= open("tmp/hello-world.pdf");
  # dump existing graphics on page 1
  my $page = $pdf.page(1);
  my PDF::Content $gfx = $page.gfx;
  dd $gfx.content-dump; # dump existing graphics operations
  
  # add some more text to the page
  $gfx.font = $pdf.core-font: :family<Courier>;
  $gfx.text: {
      .text-position = (10, 30);
      .say("Demo added text");
  }
  
  
  ```
  
  See also [Patterns](#patterns) and [XObject Forms](#xobject-forms) which also have associated graphics.
  
  ## Text Methods
  
  Text-blocks are designed to construct one or more paragraphs of
  text. The [print](#print) method can be used to add text to a line. The [say](#say) methods adds text then advances to the start of the next line.
  
  ```
  use PDF::API6;
  use PDF::Content::FontObj;
  use PDF::Page;
  
  my PDF::API6 $pdf .= new;
  my PDF::Content::FontObj $header-font = $pdf.core-font: :family<Helvetica>, :weight<bold>;
  my PDF::Content::FontObj $body-font = $pdf.core-font: :family<Helvetica>;
  
  my PDF::Page $page = $pdf.add-page;
  my @curpos;
  $page.gfx.graphics: -> $gfx {
      $gfx.text: {
          $gfx.say: 'My first novel', :position[10, 200], :font($header-font); # output a line
          $gfx.print: 'It was a dark and stormy', :font($body-font); # start a line
          $gfx.say: ' night.', :font($header-font); # finish it
          @curpos = $gfx.text-position.List; # save current position.
      }
  }
  
  ```
  
  There are a number of [text variables](#text-state-variables) (e.g. WordSpacing) and [graphics variables](#general-graphics---common-state-variables) (e.g. FillColor) that can be set to affect the appearance of the displayed text.
  
  Please note that text variables and `text-position` are scoped to a text block. You will need to set them up again when starting a new text block.
  
  ### text
  
  Synopsis: `$gfx.text: &block`
  
  This is a convenience method, that executes code in a text block. Text blocks
  cannot be nested. Nor can they contain a graphics block.
  
  ```
  $page.text: {
      .text-position = 30, 50;
      .WordSpacing = 5;
      .say "hi";
  }
  
  ```
  
  is equivalent to:
  
  ```
  given $page.gfx {
      .BeginText;
      .text-position = 30, 50;
      .WordSpacing = 5;
      .say "hi";
      .EndText;
  }
  
  ```
  
  Where `BeginText` and `EndText` are text graphics operators [1].
  
  The following should only be used within a text block:
  
  * text methods, such as: `font()`,`text-position()` and text-transform()
  * text state variables: CharSpacing, WordSpacing, HorizScaling, TextLeading, TextRender, TextRise [1].
  
  `print()` and `say()` can be used outside of a text block, but you
  need to at least pass a `:$font` option and will likely need a `:$text-position` method (if the text is not at 0, 0 in current user coordinates).
  
  [1] see [Appendix I: Graphics / Text Operators](#text-operators).
  
  ### font, core-font
  
  ```
  $gfx.font = $pdf.core-font( :family<Helvetica>, :weight<bold>, :style<italic> );
  $gfx.font = $pdf.core-font('Times-Bold');
  $gfx.font = $pdf.core-font('ZapfDingbats');
  
  ```
  
  Read/write accessor to set, or get the current font.
  
  Note: other fonts can be loaded via the PDF::Font::Loader module:
  
  ```
  use PDF::Font::Loader :load-font;
  $gfx.font = load-font( :file</usr/share/fonts/truetype/tlwg/Garuda-BoldOblique.ttf> );
  # Select a matching system font. This requires the FontConfig module
  # to also be installed.
  $gfx.font = load-font( :family<Garuda>, :weight<bold>, :slant<oblique> );
  
  ```
  
  See also [HarfBuzz::Subset](https://harfbuzz-raku.github.io/HarfBuzz-Subset-raku), which can be used to subset fonts, reducing the
  size of PDF files.
  
  ```
  use PDF::Font::Loader :load-font;
  use FontConfig;
  use HarfBuzz::Subset;
  $gfx.font = load-font( :file</usr/share/fonts/truetype/tlwg/Garuda-BoldOblique.ttf>, :subset );
  $gfx.font = load-font( :family<Garuda>, :weight<bold>, :slant<oblique>, :subset );
  
  ```
  
  ### text-position
  
  ```
  $page.text: {
      .text-position = 10,20;
      .say('text @10,20');
  }
  
  ```
  
  Gets or sets the current text output position. Origin `(0, 0)` is at the bottom left corner.
  
  ### text-transform
  
  Synopsis: `$gfx.text-transform: :$matrix, :translate[$x,$y], :rotate($rad), :scale[$s, $sy?], :skew[$x,y];`
  
  Applies text transforms, such as translation, rotation, scaling, and skew.
  
  ```
  $gfx.text-transform: :translate[110, 10], :rotate(.1);
  
  ```
  
  * Text transforms are applied after any [Graphics Transform](#transform).
  * This replaces any existing text positioning or transforms.
  
  ### base-coords
  
  Synopsis:
  
  ```
  my ($x-base, $y-base, ...) = $gfx.base-coords(
                             $x-trans, $y-trans, ...,
                             :$user=True,    # map to user default coordinates
                             :$text=False);  # un-map text matrix
  
  ```
  
  Options:
  
  * `:text` - Treat as a text position on the page, i.e. un-transform against the current `TextMatrix` before un-transforming against the graphics matrix (`CTM`).
  * `:!user` - Treat at a text position relative to current graphics, i.e. un-transform only the current `TextMatrix`
  
  This method maps transformed pairs of x-y coordinates back to original coordinates.
  
  ```
  $gfx.transform: :translate($x,$y), :scale(.8);
  my @image-region = $gfx.do($my-image, :align<middle>, :position[20, 30]);
  my @position-on-page = $gfx.base-coords(|@image-region);
  
  ```
  
  ### user-coords
  
  Synopsis:
  
  ```
  my ($x-trans, $y-trans, ...) = $gfx.user-coords(
                             $x-base, $y-base, ...,
                             :$user=True,    # map to user default coordinates
                             :$text=False);  # un-map text matrix
  
  ```
  
  This is the inverse function to `base-coords` and computes transformed coordinates from original coordinates.
  
  ### print
  
  ```
  $gfx.WordSpacing = 2; # add extra spacing between words
  my $font = $pdf.core-font( :family<Helvetica>, :weight<bold> );
  my $font-size = 16;
  my $text = "Hello.  Ting, ting-ting. Attention! … ATTENTION! ";
  
  my ($x0, $x1, $y1, $y1) = $gfx.print: $text, :$font, :$font-size, :width(120);
  
  note "text block has size {$x1 - $x0} X {$y1 - $y0};
  
  ```
  
  Synopsis: `my @rect = print( $text-str-or-chunks-or-box, :align<left|center|right>, :valign<top|center|bottom>, :baseline-shift<top|middle|bottom|alphabetic|ideographic|hanging>, :position[x, y], :$font, :$font-size, :$.WordSpacing, :$.CharSpacing, :$.HorizScaling, :$.TextRise :kern, :squish, :$leading, :$width, :$height, :shape, :direction<ltr|rtl>, :!bidi, :nl)`
  
  Renders a text string, or [Text Box](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Text/Box).
  
  The optional [Text::FriBidi](https://raku.land/zef:dwarring/Text::FriBidi) module is required when:
  
  * the `:direction<rlt>` option is being used
  * the input text contains [Unicode bidirectional control](https://www.w3.org/International/questions/qa-bidi-unicode-controls.en) (BiDi) characters and the `:!bidi` option has not been used to disable BiDi processing.
  
  ### say
  
  Takes the same parameters as `print`. Sets the final text position (`$.text-position`) to the start of the next line.
  
  ## Graphics Methods
  
  These methods are applicable to objects that perform the `PDF::Content::Canvas` role: `PDF::Page`, `PDF::XObject::Form`, and `PDF::Pattern::Tiling`
  
  ### graphics
  
  Synopsis: `$gfx.graphics: &block`
  
  This is a convenience method, that executes code in a nested Save/Restore block.
  
  ```
  $page.graphics: {
      .Rectangle(10,20,100,50);
      .Fill;
  }
  
  ```
  
  is equivalent to:
  
  ```
  given $page.gfx {
      .Save;
      .Rectangle(10,20,100,50);
      .Fill;
      .Restore;
  }
  
  ```
  
  ### transform
  
  Synopsis: `$gfx.transform: :$matrix, :translate[$x,$y], :rotate($rad), :scale[$s, $sy?], :skew[$x,y];`
  
  Applies a graphics transform, such as translation, rotation, scaling, etc.
  
  ```
  $gfx.transform: :rotate(pi/4), :scale(2);
  
  ```
  
  Unlike [Text Transforms](#text-transform), Graphics Transforms accumulate; and are applied in addition to any existing transforms.
  
  ### paint
  
  Synopsis: `$gfx.paint( &block?, :close, :stroke, :fill, :even-odd)`
  
  `paint` is a general purpose method for closing, stroking and filling shapes.
  
  `paint` takes an optional block which may contain operations
  to set up the graphics state and ends with one or more path
  construction operations:
  
  ```
  use PDF::Content::Color :rgb;
  # fill and stroke a colored rectangle
  
  $gfx.paint: :fill, :stroke, {
      .FillColor = rgb(.7, .7, .9);
      .StrokeColor = rgb(.9, .5, .5);
      .LineWidth = 2.5; # set stroking line-width
      .Rectangle(0, 20, 100, 250);
  }
  
  ```
  
  The graphics state is saved and restored if the optional block is provided. The above example is equivalent to:
  
  ```
  use PDF::Content::Color :rgb;
  given $gfx: {
      .Save;
      .FillColor = rgb(.7, .7, .9);
      .StrokeColor = rgb(.9, .5, .5);
      .LineWidth = 2.5; # set stroking line-width
      .Rectangle(0, 20, 100, 250);
      .FillStroke;
      .Restore;
  }
  
  ```
  
  ## Image Methods
  
  ### load-image
  
  Loads an image in a supported format (currently PNG, GIF and JPEG).
  
  ```
   my PDF::XObject::Image $img = $gfx.load-image("t/images/lightbulb.png");
   note "image has size {$img.width} X {$image.height}";
  
  ```
  
  ### do
  
  ```
  $gfx.do($img, :position[10, 20])
  
  ```
  
  Synopsis: `my Numeric @region[4] = $gfx.do( $xobject, $x = 0, $y = 0, :$width, :$height, :inline, :align<left center right> = 'left', :valign<top center bottom> = 'bottom')`
  
  Displays an XObject Image or Form.
  
  ## XObject Forms
  
  A Form is a graphical sub-element. Its usage is the same as an image.
  
  XObject form construction is similar to pages; both perform the
  PDF::Context::Graphics role, which provides methods such as
  `gfx`, `pre-gfx`, `graphics`, `text` and `render`.
  
  ### xobject-form
  
  This graphical method is used to create a new, empty form object:
  
  ```
  use v6;
  use PDF::API6;
  use PDF::Page;
  use PDF::XObject::Form;
  use PDF::Content::Color :rgb;
  
  my PDF::API6 $pdf .= new;
  my PDF::Page $page = $pdf.add-page;
  $page.media-box = [0, 0, 275, 100];
  
  # create a new XObject form of size 120 x 50
  my @BBox = [0, 0, 120, 50];
  my PDF::XObject::Form $form = $page.xobject-form: :@BBox;
  
  $form.graphics: {
      # color the entire form
      .FillColor = rgb(.9, .8, .8);
      .Rectangle: |@BBox;
      .paint: :fill, :stroke;
  }
  
  $form.text: {
      # add some sample text
      .font = $pdf.core-font('Helvetica');
      .text-position = 10, 10;
      .say: "Sample form";
  }
  
  # display the form a couple of times
  $page.graphics: {
      .transform: :translate(10, 10);
      .do($form);
      .transform: :translate(130, 0), :rotate(.1);
      .do($form);
  }
  
  $pdf.save-as: "tmp/sample-form.pdf";
  
  ```
  
  ![example.pdf](https://raw.githubusercontent.com/pdf-raku/PDF-API6/master/tmp/.previews/sample-form-001.png)
  
  ## Patterns
  
  A Pattern is a graphical object. Its construction is similar to a form; its usage is the same as a color.
  
  ```
  use PDF::API6;
  use PDF::Pattern::Tiling;
  use PDF::Content::Color :rgb;
  
  my PDF::API6 $pdf .= new;
  $pdf.media-box = [0, 0, 250, 100];
  my $page = $pdf.add-page;
  
  $page.graphics: -> $gfx {
      # create a new tiling pattern
      my PDF::Pattern::Tiling $pattern = $page.tiling-pattern(:BBox[0, 0, 25, 25], );
      $pattern.graphics: {
          .FillColor = rgb(.7, .7, .9);
          .Rectangle(|$pattern<BBox>);
          .Fill;
          my $img = .load-image("t/images/lightbulb.png");
          .do($img, :position[5, 5] );
      }
      # set our pattern as the fill color
      $gfx.StrokeColor = rgb(.3, .3, .9);
      $gfx.StrokeAlpha = .5;
      $gfx.FillColor = $gfx.use-pattern($pattern);
  
      $gfx.FillAlpha = .6; # semitransparent
      # create a couple of overlapping semi-transparent filled rectangles
      $gfx.Rectangle(30, 30, 110, 50);
      $gfx.paint: :fill, :stroke;
  
      $gfx.transform: :translate[50, 0], :rotate(.25);
      $gfx.Rectangle(30, 2, 110, 50);
      $gfx.paint: :fill, :stroke;
  }
  $pdf.save-as: "tmp/patterns.pdf";
  
  ```
  
  ![patterns.pdf](https://raw.githubusercontent.com/pdf-raku/PDF-API6/master/tmp/.previews/patterns-001.png)
  
  Patterns are typically used to achieve textured colors or tiling effects.
  
  ### tiling-pattern
  
  Synopsis: `my PDF::Pattern::Tiling $pattern = $gfx.tiling-pattern( :@BBox, :@Matrix, :$XStep, :$YStep, :$group = True)`
  
  Creates a new empty tiling pattern.
  
  ### use-pattern
  
  Synopsis: `$gfx.FillColor = $gfx.use-pattern($pattern)`
  
  Use a pattern; registering it as graphics resource. This method should be used to place the pattern after it has been fully constructed.
  
  ## Low Level Graphics
  
  PDF::API6 fully supports the PDF graphics instruction set, both for reading and
  writing PDF files. Direct calls to instructions are camel-cased, such as:
  
  ```
  $gfx.TextMove(10,20);
  
  ```
  
  It is also possible to directly call the TextMove operator 'Td':
  
  ```
  use PDF::Content::Ops :OpCode
  $gfx.op(OpCode::TextMove, 10,20);
  $gfx.op('Td', 10,20);  # TextMove
  
  ```
  
  A number of graphics variables are tracked as the instructions are executed. For example,
  to set the line-width for stroking operations:
  
  ```
  $gfx.LineWidth = 2.5;
  
  ```
  
  This is equivalent to:
  
  ```
  $gfx.SetLineWidth(2.5)
       unless $gfx.LineWidth == 2.5;
  
  ```
  
  The `Save` and `Restore` operators may be used to save and restore graphics variables.
  
  ```
  $gfx.LineWidth = 1.5;
  $gfx.Save;
  $gfx.LineWidth = 2.5;
  #...
  $gfx.Restore;
  say $gfx.LineWidth; # 1.5
  
  ```
  
  The `graphics` method simply adds `Save` and `Restore` operators
  
  ```
  $gfx.LineWidth = 1.5;
  $gfx.graphics: {
      .LineWidth = 2.5;
      #...
  }
  say $gfx.LineWidth; # 1.5
  
  ```
  
  ## Basic Colors
  
  The PDF Model maintains two separate color states; for filling and stroking.
  
  They are applicable to general graphics as well as displayed text.
  
  ### FillColor, FillAlpha
  
  To set an RGB color for filling, or for displaying text:
  
  ```
  $gfx.FillColorSpace = 'DeviceRGB';
  $gfx.FillColorN = [1.0, .5, .5];
  
  ```
  
  Alternatives:
  
  ```
  $gfx.FillColor = :DeviceRGB[1.0, .5, .5];
  
  use PDF::Content::Color :rgb;
  $gfx.FillColor = rgb(1.0, .5, .5);
  
  ```
  
  There are also Gray and CMYK color-spaces
  
  ```
  $gfx.FillColor = :DeviceGray[.7];
  $gfx.FillColor = :DeviceCMYK[.3, .2, .2, .15];
  
  use PDF::Content::Color :gray, :cmyk;
  $gfx.FillColor = gray(.7);
  $gfx.FillColor = cmyk(.3, .2, .2, .15);
  
  ```
  
  Also settable is the `FillAlpha`. This is a value between 0