### ----------------------------------------------------
### -- PDF::API6
### -- Licenses: Artistic-2.0
### -- Authors: David Warring
### -- File: README.md
### ----------------------------------------------------
### -- Chunk 2 of 3
aku
$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:
```raku
$gfx.FillColorSpace = 'DeviceRGB';
$gfx.FillColorN = [1.0, .5, .5];
```
Alternatives:
```raku
$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
```raku
$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.0 (fully transparent) and
1.0 (fully opaque).

Note that `FillAlpha` can also be used to draw semi-transparent images:
```raku
$gfx.FillAlpha = .3;  # make the fill color semi-transparent
$gfx.Rectangle(10,10,50,75);
$gfx.Fill; # fill, semi-transparently
$gfx.do($image, 20,20);  # overlay image, semi-transparently
```
### StrokeColor, StrokeAlpha

These are identical to `FillColor`, and `FillAlpha`, except that they are applied to stroking colors:
```raku
# draw a semi-transparent rectangle with red border
use PDF::Content::Color :rgb;
$gfx.StrokeAlpha = .5;  # make the stroke color semi-transparent
$gfx.StrokeColor = rgb(.9, .1, .1);
$gfx.Rectangle(10,10,50,75);
$gfx.Stroke;
```
### Named Colors

The PDF::Content::Color `:ColorName` and `color` exports provide a selection of built in named colors.

-  Aqua, Black, Blue, Fuchsia, Gray, Green, Lime, Maroon Navy, Olive Orange, Purple,
   Red, Silver, Teal, Yellow, Cyan, Magenta

A wider selection of named colors is available via the `Color::Named` module.
```raku
use PDF::Content::Color :ColorName, :color;
use Color::Named;
$gfx.FillColor = color Blue; # a PDF::Content named color
$gfx.StrokeColor = color Color::Named.new( :name<azure> );
```
### Text Modes

By default text is drawn solidly using the current fill color. There are other text rendering modes that alter how text is stroked and filled. For example, the FillOutLineText rendering mode strokes the text using the current StrokeColor to a thickness determined by the current LineWidth then fills it using the current FillColor.

Setting the same `FillColor` and `StrokeColor` with `TextMode::OutlineText`
artificially increasing the font weight by `LineWidth`.

```Raku
use v6;
use PDF::API6;
use PDF::Content::Color :ColorName, :color;
use PDF::Content::Ops :TextMode;

my PDF::API6 $pdf .= new;
$pdf.media-box = [0, 0, 200, 100];
my PDF::Page $page = $pdf.add-page;
my $font = $pdf.core-font( :family<Helvetica> );

$page.graphics: {
    .text: {
        .font = $font, 20;
        .FillColor = color Blue;
        .StrokeColor = color Red;
        .LineWidth = .6;

        .text-position = 10, 75;
        .say: "Filled/Solid";

        .TextRender = TextMode::OutlineText;
        .say: "Outlined";

        .TextRender = TextMode::FillOutlineText;
        .say: "Filled/Stroked";

        .StrokeColor = .FillColor;
        .LineWidth = 1;
        .say: "Bolded Text";
    }
}

$pdf.save-as: "tmp/text-render-modes.pdf";
```

![example.pdf](https://raw.githubusercontent.com/pdf-raku/PDF-API6/master/tmp/.previews/text-render-modes-001.png)

See [Appendix II: Enumerations - Text Rendering Modes](#text-rendering-modes)

## Rendering Methods

### render: :&callback 

This method is used to process graphics; normally after installing
callbacks. Callback invocations have access to the graphics state via
the `$*gfx` dynamic variable.

```Raku
use PDF::API6;
use PDF::Content;
use PDF::Content::Ops :OpCode;
use PDF::Page;
my PDF::API6 $pdf .= open: "t/basic.pdf";
my PDF::Page $page = $pdf.page: 1;

my sub callback($op, *@args) {
   given $op {
       when TextMove|TextMoveSet|SetTextMatrix {
           note "Text matrix updated by $op to {$*gfx.TextMatrix}";
       }
   }
}

my PDF::Content $gfx = $page.render( :&callback);
```

### html-canvas

The optional [HTML::Canvas::To::PDF](https://pdf-raku.github.io/HTML-Canvas-To-PDF-raku/) module needs to be installed before using this method. It adds a rendering back-end to enable HTML5 Canvas like graphics construction on Pages or XObject Forms (which perform the PDF::Content::Canvas role).

In this mode, fonts are registered via [CSS:Font::Descriptor](https://css-raku.github.io/CSS-Properties-raku/CSS/Font/Descriptor) objects.

```
use PDF::API6;
use PDF::Content::Canvas;
use CSS::Font::Descriptor;

my PDF::API6 $pdf .= new;
my PDF::Content::Canvas $page = $pdf.add-page;
my CSS::Font::Descriptor $arial .= new: :font-family<arial>, :src<url(resources/font/FreeMono.ttf)>;
$page.html-canvas: :font-face[$arial], {
    .beginPath();
    .arc(95, 50, 40, 0, 2 * pi);
    .stroke();
    .font = "30px Arial";
    .fillText("Hello World", 10, 50);
}

$pdf.save-as: "tmp/html-canvas.pdf";
```

## AcroForm Fields

PDF::API6 has some experimental abilities to read and manipulate AcroFields.

The individual fields are returned as PDF::Field sub-roles (see PDF::Class).

Displayed fields are also a subclass of PDF::Annot, most commonly PDF::Annot::Widget.
```Raku
use PDF::API6;
use PDF::Field;
use PDF::Field::Button;
use PDF::Field::Choice;
use PDF::Field::Text;
use PDF::Field::Signature;
use PDF::Annot::Widget;

my PDF::API6 $pdf .= open: "t/pdf/OoPdfFormExample.pdf";
my PDF::Field @fields = $pdf.fields;
# display field names and values
for @fields -> $field {
    my $field-type = do given $field {
       when PDF::Field::Button { 'button' }
       when PDF::Field::Choice { 'button' }
       when PDF::Field::Text   { 'text' }
       when PDF::Field::Signature   { 'signature' }
       default { 'unknown' }
    }
    my $annot-type = do given $field {
       when PDF::Annot::Widget {'widget'}
       when PDF::Annot {'annot'}
       default {'hidden'}
    }
    say "{$field.key}: {$field.value} is of type $field-type $annot-type";
}
```

- The `fields` method returns all fields in the PDF as an array.
- The `fields-hash` method returns fields hashed on each fields `.key()` value

There are also PDF::Page `fields`, and `fields-hash` methods that return all fields on a given page.
```raku
my PDF::API6 $pdf .= open: "my-form.pdf";
my PDF::Field @page-1-fields = $pdf.page(1).fields;
```
More work needs to be done in PDF::Class to fully support all possible field types;

# SECTION III: PDF::API6 Specific Methods

## Metadata Methods

### info
```raku
use PDF::Info;
my PDF::Info $info := $pdf.info;
```
Gets/sets the info for the document
```raku
$pdf.info.Title = 'Some Publication';
```
Standard `Info` fields include: `Title`, `Author`, `Subject`, `Keywords`, `Creator`, `Producer`, `CreationDate` and `ModDate`.

### xmp-metadata

    Str $xml = $pdf.xmp-metadata;

Gets/sets the XMP XML data stream.

Example:
```raku
my $xml = q:to<EOT>;
    <?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
    <?adobe-xap-filters esc="CRLF"?>
    <x:xmpmeta
      xmlns:x='adobe:ns:meta/'
      x:xmptk='XMP toolkit 2.9.1-14, framework 1.6'>
        <rdf:RDF
          xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
          xmlns:iX='http://ns.adobe.com/iX/1.0/'>
            <rdf:Description
              rdf:about='uuid:b8659d3a-369e-11d9-b951-000393c97fd8'
              xmlns:pdf='http://ns.adobe.com/pdf/1.3/'
              pdf:Producer='Raku PDF::API6 version 0.0.1'></rdf:Description>
            </rdf:Description>
        </rdf:RDF>
    </x:xmpmeta>
    <?xpacket end='w'?>
    EOT

$pdf.xmp-metadata = $xml
```

## Settings Methods

### preferences
```raku
use PDF::Destination :Fit;
given $pdf.preferences {
    .HideToolBar = True;
    .OpenAction = $pdf.destination( :page(2), :fit(FitWindow) );
}
```
Controls viewing preferences for the PDF. Options are:

#### `$prefs.PageMode = 'FullScreen'`

Full-screen mode, with no menu bar, window controls, or any other window visible.

#### `$prefs.PageMode = 'UseThumbs'`

Thumbnail images visible.

#### `$prefs.PageMode = 'UseOutlines'`

Make document outlines visible.

#### `$prefs.PageLayout = 'SinglePage'`

Display one page at a time.

#### `$prefs.PageLayout = 'OneColumn'`

Display the pages in one column.

#### `$prefs.PageLayout = 'TwoColumnLeft'`

Display the pages in two columns, with odd numbered pages on the left.

#### `$prefs.PageLayout = 'TwoColumnRight'`

Display the pages in two columns, with odd numbered pages on the right.

#### `$prefs.direction = 'r2l';`

The predominant reading order for text:

- `l2r` Left to right

- `r2l` Right to left (vertical writing systems, such as Chinese, Japanese, and Korean)


#### `$prefs.HideToolbar = True`

Specifying whether to hide tool bars.

#### `$prefs.HideMenubar = True`

Specifying whether to hide menu bars.

#### `$prefs.WindowUI = True`

Specifying whether to hide user interface elements.

#### `$prefs.CenterWindow = True`

Specifying whether to position the document's window in the center of the screen.

#### `$prefs.DisplayDocTitle = True`

Specifying whether the window's title bar should display the
document title taken from the Title entry of the document information
dictionary.

#### `$prefs.after-fullscreen = 'UseThumbs'`

Thumbnail images visible after Full-screen mode.

#### `$prefs.after-fullscreen = 'UseOutlines'`

Document outline visible after Full-screen mode.

#### `$prefs.PrintScaling = 'None'`

Set the default print setting for page scaling to none.

#### `$prefs.Duplex = 'Simplex'`

Print single-sided by default.

#### `$prefs.Duplex = 'DuplexFlipShortEdge'`

Print duplex by default and flip on the short edge of the sheet.

#### `$prefs.Duplex = 'DuplexFlipLongEdge'`

Print duplex by default and flip on the long edge of the sheet.

#### `$prefs.OpenAction = $pdf.destination( :$page, :fit(FitWindow));

Specifying the page (either a page number or a page object) to be
displayed by a PDF viewer, plus one of the following options:

#### `destination()` Options:

##### `:fit(FitWindow)`

Display the page designated by page, with its contents magnified just
enough to fit the entire page within the window both horizontally and
vertically. If the required horizontal and vertical magnification
factors are different, use the smaller of the two, centering the page
within the window in the other dimension.

##### `:fit(FitHoriz), :$top`

Display the page designated by page, with the vertical coordinate top
positioned at the top edge of the window and the contents of the page
magnified just enough to fit the entire width of the page within the
window.

##### `:fit(FitVert), :$left`

Display the page designated by page, with the horizontal coordinate
left positioned at the left edge of the window and the contents of the
page magnified just enough to fit the entire height of the page within
the window.

##### `:fit(FitRect), :$left, :$bottom, :$right, :$top`

Display the page designated by page, with its contents magnified just
enough to fit the rectangle specified by the coordinates left, bottom,
right, and top entirely within the window both horizontally and
vertically. If the required horizontal and vertical magnification
factors are different, use the smaller of the two, centering the
rectangle within the window in the other dimension.

##### `:fit(FitBoxHoriz), :$top`

Display the page designated by page, with its contents magnified just
enough to fit its bounding box entirely within the window both
horizontally and vertically. If the required horizontal and vertical
magnification factors are different, use the smaller of the two,
centering the bounding box within the window in the other dimension.

##### `:fit(FitBox)`

Display the page designated by page, with the vertical coordinate top
positioned at the top edge of the window and the contents of the page
magnified just enough to fit the entire width of its bounding box
within the window.

##### `:fit(FitBoxVert), :$left`

Display the page designated by page, with the horizontal coordinate
left positioned at the left edge of the window and the contents of the
page magnified just enough to fit the entire height of its bounding
box within the window.

##### `:fit(FitXYZoom), :$left, :$top, :$zoom`

Display the page designated by page, with the coordinates (left, top)
positioned at the top-left corner of the window and the contents of
the page magnified by the factor zoom. A zero (0) value for any of the
parameters left, top, or zoom specifies that the current value of that
parameter is to be retained unchanged.

see also [examples/pdf-preferences.raku](examples/pdf-preferences.raku)

### version

    $pdf.version = v1.5;

Get or set the PDF Version

## Color Management

### color-separation
```Raku
use PDF::API6;
use PDF::Content::Color :color;
use PDF::ColorSpace::Separation;
constant CS = PDF::ColorSpace::Separation;
my PDF::API6 $pdf .= new;
$pdf.add-page.graphics: -> $gfx {
    my CS $c = $pdf.color-separation('Cyan',    color '%f000');
    my CS $m = $pdf.color-separation('Magenta', color '%0f00');
    my CS $y = $pdf.color-separation('Yellow',  color '%00f0');
    my CS $k = $pdf.color-separation('Black',   color '%000f');

    # use a separation color directly
    my CS $pms023 = $pdf.color-separation('PANTONE 032CV', color '%0ff0');
    $gfx.FillColor = $pms023 => .75;
}
```
### color-devicen
```raku
# create a DeviceN color-space for color mixing
use PDF::ColorSpace::DeviceN;
my PDF::ColorSpace::DeviceN $color-mix = $pdf.color-devicen( [ $c, $m, $y, $k, $pms023 ] );
# apply it
$gfx.FillColor = $color-mix => [0, 0, 0, .25, .75];
```
The current version of PDF::API6 only supports CMYK separations as DeviceN
components.

## Interactive Features

### Outlines

Outlines (or bookmarks) are commonly used by viewers for navigation of PDF documents.

For example, the following sets up a simple table-of-contents that will typically appear
in the navigation pane of a PDF viewer.

```Raku
use PDF::API6;
my PDF::API6 $pdf .= new;
$pdf.add-page for 1 .. 7;
use PDF::Destination :Fit;

sub dest(|c) { :Dest($pdf.destination(|c)) }

$pdf.outlines.kids = [
          %( :Title('1. Purpose of this Document'), dest(:page(1))),
          %( :Title('2. Pre-requisites'),           dest(:page(2))),
          %( :Title('3. Compiler Speed-up'),        dest(:page(3))),
          %( :Title('4. Recompiling the Kernel for Modules'), dest(:page(4)),
             :kids[
                %( :Title('5.1. Configuring Debian or RedHat for Modules'),
                   dest(:page(5), :fit(FitXYZoom), :top(798)) ),
                %( :Title('5.2. Configuring Slackware for Modules'),
                   dest(:page(5), :fit(FitXYZoom), :top(400)) ),
                %( :Title('5.3. Configuring Other Distributions for Module'),
                   dest(:page(5), :fit(FitXYZoom), :top(200)) ),
             ],
           ),
          %( :Title('Appendix'), dest(:page(7))),
         ];

```

See also: `pdf-toc.raku`, installed with PDF::Class. This can be used to view the outlines for a PDF.

### Page Labels

Get or sets page numbers to identify each page number, for display or printing:

page-labels is an array of ascending integer indexes. Each is followed by a page numbering scheme. For example
```raku
constant PageLabel = PDF::API6::PageLabel;
$pdf.page-labels = 0  => 'i',   # Roman lowercase: i, ii, iii, ...
                   4  => '1',   # Plain Decimal Numbering: 1, 2, 3, ...
                  32  => 'A-1', # Decimal: A-1, A-2, ...
                  36  => 'B-1', # Decimal: B-1, B-2, ...
                  # equivalent to 'C-1'
                  40  => { :numbering-style(PageLabel::RomanUpper), :start(1), :prefix<C-> };
```
### Annotations

An annotation associates a 'clickable' region on a page with an object such as a text note, destination page or URI. PDF::API6 currently supports a small number of commonly used annotations:

- Links
  - pages within the PDF
  - pages from another other PDF files
  - external URIs
- File Attachments
- Text Annotations (or "sticky notes")

Synopsis:
```raku
use PDF::Annot::Link;
use PDF::Annot::FileAttachment;
use PDF::Annot::Text;

my PDF::Annot::Link $page-link = $pdf.annotation: :$page, :$action, |%props;
my PDF::Annot::Link $dest-link = $pdf.annotation: :$page, :$destination, |%props;
my PDF::Annot::FileAttachment $attachment = $pdf.annotation: :$page, :$attachment, :icon-name<Paperclip|GraphPushPin>, :$text-label, |%props;
my PDF::Annot::Text $sticky-note = $pdf.annotation: :$page, :$content, :$Open, |%props;
```
Where:

    %props {              # common annotation options
        :@color,          # color for the annotation 3 values
                          # (rgb), 1 value (gray) or 4 values (cmyk)
        :@rect, :$text,   # rectangle or text to print and highlight
        :$border-style,   # style the annotation border
    }

Examples:

```Raku
use v6;
use PDF::API6;
use PDF::Destination :Fit;
use PDF::Annot::Link;
use PDF::Content::Color :ColorName;
use PDF::Border :BorderStyle;
use PDF::Annot::Text;
use PDF::Filespec;
use PDF::Content;

my PDF::API6 $pdf .= new;

$pdf.add-page for 1 .. 2;

sub dest(|c) { :Dest($pdf.destination(|c)) }
sub action(|c) { :action($pdf.action(|c)) }

my PDF::Content $gfx = $pdf.page(1).gfx;
$gfx.text: {
    .font = $pdf.core-font: 'Times-Roman';

    #-- create a link from a region on Page 1 to Page 2 --
    .text-position = 377, 545;
    my PDF::Annot::Link $link = $pdf.annotation(
                     :page(1),
                     :text("see page 2"),
                     |dest(:page(2)),
                     :color(Blue),
                 );

    #-- Link to an URI --
    .text-position = 377, 515;
    $link = $pdf.annotation(
                     :page(1),
                     :text("Raku"),
                     |action(:uri<https://raku.org>),
                     :color(Orange),
                 );

    #-- Link to a Page in another PDF --

    # display the annotation with a 2pt dashed border
    my $border-style = {
        :width(2),  # 2 point width
        # 3 point dashes, alternating with 2-point gaps
        :style(BorderStyle::Dashed),
        :dash-pattern[3, 2],
    };

    .text-position = 377, 485;
    $link = $pdf.annotation(
                     :page(1),
                     :text("Example PDF Form"),
                     |action(
                         :file<../t/pdf/OoPdfFormExample.pdf>,
                         :page(1), :fit(FitXYZoom), :top(400),
                     ),
                     :color(Green),
                     :$border-style,
                 );
}

#-- Create a Text annotation --
my Str $content = q:to<END-QUOTE>;
    To be, or not to be: that is the question: Whether 'tis
    nobler in the mind to suffer the slings and arrows of
    outrageous fortune, or to take arms against a sea of
    troubles, and by opposing end them?
END-QUOTE

my PDF::Annot::Text $note = $pdf.annotation(
             :page(1),
             :$content,
             :rect[ 377, 455, 455, 467 ],
             :color[0, 0, 1],
         );

#--  Add a File Attachment annotation
my PDF::Filespec $attachment = $pdf.attachment("t/images/lightbulb.png");
$content = 'Click on the paperclip to see an image as an example image attachment';
$pdf.annotation(
             :page(1),
             :$attachment,
             :text-label("Light Bulb"),
             :$content,
             :icon-name<Paperclip>,
             :rect[ 377, 395, 425, 412 ],
         );

```

### Named Destinations

The `destination()` method (above), also accepts an optional `:$name` argument.

This causes the PDF to keep a table that maps names to destinations. So for example:

    ```
    $pdf.destination: :page(99), :name<appendix-i-graphics>;
    $pdf.save-as: "doc.pdf";
    ```

Is enough to create a named declaration. This may have several benefits in browsers and other third-party software:

- major browsers support opening PDF's to named declarations. For example, opening url "file://doc.pdf#appendix-i-graphics" will open the PDF at page 99.

- PDF::API6 can then also locate pages by name: `$pdf.open("doc.pdf").page('appendix-i-graphics')` will open page 99.

Note that destinations can be combined with link annotations to create
links that are both internally and externally accessible.

```
    .text-position = 377, 545;
    my PDF::Annot::Link $link = $pdf.annotation(
                     :page(1), # linking from page 1 [this could also be a name]
                     :text("see Appendix I - graphics"),
                     :destination(:page(99), :name<appendix-i-graphics>),
                     :color(Blue),
                 );

```
## Tagged Content

PDF::API6 has some basic ability to tag graphical content.

See also the [PDF::Tags](https://pdf-raku.github.io/PDF-Tags-raku/) module,
which can be used with this module and provides more functionality.

### tag

    my PDF::Content::Tag $tag = $gfx.tag($tag-name, &block?, *%attrs);
    $gfx.tag: 'Span', {
        .print: 'Hasta la vista.';
    }, :Lang<es-MX>;

Create a local tag in a content stream, if a code block is given. The block is
marked, otherwise a marked point is made in the content stream.

### mark

    my PDF::Content::Tag $mark = $gfx.mark($tag-name, &block?, *%attrs);
    say $mark.mcid;

Similar to the `tag` method, but allocates a marked content identifier (MCID)
for marked content that forms part of a document's logical structure.

See also the [PDF::Tags](https://pdf-raku.github.io/PDF-Tags-raku/) module, which
can be used in conjunction with [this module](https://pdf-raku.github.io/PDF-API6)
to create Tagged PDF for accessibility and other purposes:

```raku
use PDF::Tags;
use PDF::Tags::Elem;
use PDF::API6;

my PDF::API6 $pdf .= new;
my PDF::Tags $tags .= create: :$pdf;
# create the document root
my PDF::Tags::Elem $doc = $tags.Document;

my $page = $pdf.add-page;
my $header-font = $page.core-font: :family<Helvetica>, :weight<bold>;
my $body-font = $page.core-font: :family<Helvetica>;

$pdf.add-page; # blank second page, as a target

$page.graphics: -> $gfx {

    $doc.Header1: $gfx, {
        .say('Sample tagged level-1 header',
             :font($header-font),
             :font-size(15),
             :position[50, 120]);
    };

    $doc.Paragraph: $gfx, {
        .say('Sample tagged paragraph', :position[50, 100], :font($body-font), :font-size(12));
    };
}

$pdf-save-as: "tmp/tagged.pdf";
```

# APPENDIX

## Appendix I: Graphics

The PDF standard defines a state machine for rendering graphics. There are
a set of graphics operations that are used to construct content, or affect the
graphics state. These are short codes that appear in a content stream (e.g. 'cm'). [PDF::Content](https://pdf-raku.github.io/PDF-Content-raku/PDF/Content/Ops) implements a graphics engine that can execute these operations and maintain graphics state.

The graphics operations and variables accessors are mapped to (camel-cased) mnemonics that can be executed as methods on the [PDF::Content](https://pdf-raku.github.io/PDF-Content-raku//PDF/Content/Ops) `$gfx` object.

For example 'cm' is mapped to the `ConcatMatrix` mnemonic. Its takes a matrix array as an argument and updates the `CTM` graphics state variable.

Graphics are used to construct page content, as well as Form XObjects and Tiling Patterns.

Graphics operations and variables sometimes need to be used directly. In particular,

- [Text State Variables](#text-state-variables) - for advanced text effects
- [General Graphics](#general-graphics---common-state-variables) - for lines and colors
- [Path Construction Operands](#path-construction-operators) - for drawing curves and lines

There are some nesting and sequencing rules for operations, including:

- There are three types of block structures, [graphics](#graphics), [text](#text) and [marked content](#marked-content).
- [Text blocks](#text) don't nest, or contain graphics blocks.
- [Text state variables](#text-state-variables) should only be used in a [text block](#text) and are scoped to it.
- Other Graphics state variables should be used in a [graphics block](#graphics) (possibly nested) and are scoped to the innermost graphics block.
- [Font](#font-core-font) and [text position](#text-position) should be set before rendering text.
- A sequence of [path construction operands](#path-construction-operators) should be followed by a [path painting operand](#path-painting-operators).

PDF::Content will warn if there are any problems with operator sequencing or block structure.

### Graphics Variables

#### Text State Variables

These are scoped to text blocks and influence the appearance
and layout of text.

Accessor | Code | Description | Default | Example Setters | Notes
-------- | ------ | ----------- | ------- | ------- | ---
TextMatrix | Tm | Text transformation matrix | [1,0,0,1,0,0] | `.TextMatrix = :scale(1.5);` | [1]
CharSpacing | Tc | Character spacing adjustment | 0.0 | `.CharSpacing = 1.0`
WordSpacing | Tw | Word spacing adjustment | 0.0 | `.WordSpacing = 2.5`
HorizScaling | Th | Horizontal scaling (percent) | 100 | `.HorizScaling = 150`
TextLeading | Tl | Text line height | 0.0 | `.TextLeading = 12;`
Font | [Tf, Tfs] | Text font and size | | `.font = [ $pdf.core-font( :family<Helvetica> ), 12 ]` | [2]
TextRender | Tmode | Text rendering mode | 0 | `.TextRender = TextMode::OutlineText` | [3]
TextRise | Trise | Text rise | 0.0 | `.TextRise = 3`

[1] See also the [text-transform](#text-transform) method

[2] See also the [font](#font-core-font) method.

[3] See [Appendix II: Enumerations - Text Rendering Modes](#text-rendering-modes)

#### General Graphics - Common State Variables

These variables affect the appearance of lines and set stroke and fill colors

Accessor | Code | Description | Default | Example Setters | Notes
-------- | ------ | ----------- | ------- | ------- | ---
CTM |  | The current transformation matrix | [1,0,0,1,0,0] | `.ConcatMatrix: :scale(1.5);` | [1]
DashPattern | D |  A description of the dash pattern to be used when paths are stroked | solid | `.DashPattern = [[3, 5], 6];`
FillAlpha | ca | The constant shape or constant opacity value to be used for other painting operations | 1.0 | `.FillAlpha = 0.25`
FillColor| | current fill color-space and color | :DeviceGray[0.0] | `.FillColor = :DeviceCMYK[.7,.2,.2,.1]`
LineCap  |  LC | A code specifying the shape of the endpoints for any open path that is stroked | 0 (butt) | `.LineCap = LineCaps::RoundCaps;` | [2]
LineJoin | LJ | A code specifying the shape of joints between connected segments of a stroked path | 0 (miter) | `.LineJoin = LineJoin::RoundJoin` | [3]
LineWidth | w | Stroke line-width | 1.0 | `.LineWidth = 2.5`
StrokeAlpha | CA | The constant shape or constant opacity value to be used when paths are stroked | 1.0 | `.StrokeAlpha = 0.5;`
StrokeColor| | current stroke color-space and color | :DeviceGray[0.0] | `.StrokeColor = :DeviceRGB[.7,.2,.2]`

[1] See also the [transform](#transform) method

[2] See [Line Cap Enumerations](#line-cap-enumerations)

[3] See [Line Join Enumerations](#line-join-enumerations)


#### General Graphics - Advanced State Variables

Accessor | Code | Description | Default
-------- | ------ | ----------- | -------
AlphaSource | AIS | A flag specifying whether the current soft mask and alpha constant parameters are interpreted as shape values or opacity values. This flag also governs the interpretation of the SMask entry | false |
BlackGenerationFunction | BG2 | A function that calculates the level of the black colour component to use when converting RGB colours to CMYK
BlendMode | BM | The current blend mode to be used in the transparent imaging model |
Flatness | FT | The precision with which curves are rendered on the output device. The value of this parameter gives the maximum error tolerance, measured in output device pixels; smaller numbers give smoother curves at the expense of more computation | 1.0 
Halftone | HT |  A halftone screen for gray and colour rendering
MiterLimit | ML | number The maximum length of mitered line joins for stroked paths |
OverPrintMode | OPM | A flag specifying whether painting in one set of colorants should cause the corresponding areas of other colorants to be erased or left unchanged | false
OverPrintPaint | OP | A code specifying whether a colour component value of 0 in a DeviceCMYK colour space should erase that component (0) or leave it unchanged (1) when overprinting | 0
OverPrintStroke | OP | " | 0
RenderingIntent | RI | The rendering intent to be used when converting CIE-based colours to device colours | RelativeColorimetric
SmoothnessTolerance | ST | The precision with which colour gradients are to be rendered on the output device. The value of this parameter (0 to 1.0) gives the maximum error tolerance, expressed as a fraction of the range of each colour component; smaller numbers give smoother colour transitions at the expense of more computation and memory use.
SoftMask | SMask | A soft-mask dictionary specifying the mask shape or mask opacity values to be used in the transparent imaging model, or the name: None | None
StrokeAdjust | SA | A flag specifying whether to compensate for possible rasterization effects when stroking a path with a line | false
TransferFunction | TR2 |  A function that adjusts device gray or colour component levels to compensate for nonlinear response in a particular output device
UndercolorRemovalFunction | UCR2 | A function that calculates the reduction in the levels of the cyan, magenta, and yellow colour components to compensate for the amount of black added by black generation

### Graphic Operators

#### Color Operators

Low level setters for [FillColor](#fillcolor-fillalpha) and [StrokeColor](#strokecolor-strokealpha).

Method | Code | Description
--- | --- | ---
SetStrokeColorSpace(name) | CS | Set the current space to use for stroking operations. This can be a standard name, such as 'DeviceGray', 'DeviceRGB', 'DeviceCMYK', or a name declared in the parent's Resource<ColorSpace> dictionary.
SetStrokeColorSpace(name) | cs | Same but for non-stroking operations.
SetStrokeColor(c1, ..., cn) | SC | Set the colours to use for stroking operations in a device. The number of operands required and their interpretation depends on the current stroking colour space: DeviceGray, CalGray, and Indexed colour spaces, have one operand. DeviceRGB, CalRGB, and Lab