### ----------------------------------------------------
### -- Gnome::Cairo
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman
### -- File: lib/Gnome/Cairo.rakumod
### ----------------------------------------------------
### -- Chunk 4 of 4
 current line width, line join, line cap, and dash settings. After C<stroke()>, the current path will be cleared from the cairo context. See C<set-line-width()>, C<set-line-join()>, C<cset-line-cap()>, C<set-dash()>, and C<stroke-preserve()>.

Note: Degenerate segments and sub-paths are treated specially and provide a useful result. These can result in two different situations:

=item Zero-length "on" segments set in C<set-dash()>. If the cap style is C<CAIRO_LINE_CAP_ROUND> or C<CAIRO_LINE_CAP_SQUARE> then these segments will be drawn as circular dots or squares respectively. In the case of C<CAIRO_LINE_CAP_SQUARE>, the orientation of the squares is determined by the direction of the underlying path.
=item A sub-path created by C<move-to()> followed by either a C<close-path()> or one or more calls to C<line-to()> to the same coordinate as the C<move-to()>. If the cap style is C<CAIRO_LINE_CAP_ROUND> then these sub-paths will be drawn as circular dots.

Note that in the case of C<CAIRO_LINE_CAP_SQUARE> a degenerate sub-path will not be drawn at all, (since the correct orientation is indeterminate).  In no case will a cap style of C<CAIRO_LINE_CAP_BUTT> cause anything to be drawn in the case of either degenerate segments or sub-paths.

  method stroke ( )

=end pod

method stroke ( ) {
  cairo_stroke(self._get-native-object-no-reffing)
}

sub cairo_stroke (
  cairo_t $cr
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:stroke-extents:
=begin pod
=head2 stroke-extents

Computes a bounding box in user coordinates covering the area that would be affected, (the "inked" area), by a C<stroke()> operation given the current path and stroke parameters. If the current path is empty, returns an empty rectangle ((0,0), (0,0)). Surface dimensions and clipping are not taken into account.

Note that if the line width is set to exactly zero, then C<stroke-extents()> will return an empty rectangle. Contrast with C<path-extents()> which can be used to compute the non-empty bounds as the line width approaches zero.

Note that C<stroke-extents()> must necessarily do more work to compute the precise inked areas in light of the stroke parameters, so C<path-extents()> may be more desirable for sake of performance if non-inked path extents are desired.  See C<stroke()>, C<set-line-width()>, C<set-line-join()>, C<set-line-cap()>, C<set-dash()>, and C<stroke-preserve()>.

  method stroke-extents ( --> List )

List returns;
=item Num; left of the resulting extents
=item Num; top of the resulting extents
=item Num; right of the resulting extents
=item Num; bottom of the resulting extents
=end pod

method stroke-extents ( --> List ) {

  my gdouble $x1;
  my gdouble $y1;
  my gdouble $x2;
  my gdouble $y2;

  cairo_stroke_extents(
    self._get-native-object-no-reffing, $x1, $y1, $x2, $y2
  );

  ( $x1.Num, $y1.Num, $x2.Num, $y2.Num)
}

sub cairo_stroke_extents (
  cairo_t $cr, gdouble $x1 is rw, gdouble $y1 is rw, gdouble $x2 is rw, gdouble $y2 is rw
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:stroke-preserve:
=begin pod
=head2 stroke-preserve

A drawing operator that strokes the current path according to the current line width, line join, line cap, and dash settings. Unlike C<stroke()>, C<stroke-preserve()> preserves the path within the cairo context.

See C<set-line-width()>, C<set-line-join()>, C<set-line-cap()>, C<set-dash()>, and C<stroke-preserve()>.

  method stroke-preserve ( )

=end pod

method stroke-preserve ( ) {
  cairo_stroke_preserve(self._get-native-object-no-reffing)
}

sub cairo_stroke_preserve (
  cairo_t $cr
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:tag-begin:
=begin pod
=head2 tag-begin

Marks the beginning of the I<t$ag-name> structure. Call C<tag-end()> with the same I<$tag-name> to mark the end of the structure.

The C<$attributes> string is of the form "key1=value2 key2=value2 ...". Values may be boolean (true/false or 1/0), integer, float, string, or an array. String values are enclosed in single quotes ('). Single quotes and backslashes inside the string should be escaped with a backslash. Boolean values may be set to true by only specifying the key. E.g. the attribute string "key" is the equivalent to "key=true". Arrays are enclosed in '[]'. E.g. "rect=[1.2 4.3 2.0 3.0]".

If no attributes are required, I<attributes> can be an empty string or NULL. Invalid nesting of tags or invalid attributes will cause this context to shutdown with a status of C<CAIRO_STATUS_TAG_ERROR>.

For example;

  with $cairo {
    .tag-begin( CAIRO_TAG_LINK, "uri='https://cairographics.org'");
    .move-to( 50, 50);
    .show-text('This is a link to the cairo website.');
    .tag-end(CAIRO_TAG_LINK);
  }

See C<tag-end()>.

  method tag-begin ( Str $tag_name, Str $attributes )

=item $tag-name; The tag name. This can only be one of C<CAIRO_TAG_LINK> or C<CAIRO_TAG_DEST>.
=item $attributes; tag attributes.
=end pod

constant CAIRO_TAG_LINK is export = 'Link';
constant CAIRO_TAG_DEST is export = 'cairo.dest';

method tag-begin ( Str $tag_name, Str $attributes ) {
  cairo_tag_begin( self._get-native-object-no-reffing, $tag_name, $attributes)
}

sub cairo_tag_begin (
  cairo_t $cr, gchar-ptr $tag_name, gchar-ptr $attributes
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:tag-end:
=begin pod
=head2 tag-end

Marks the end of the I<tag_name> structure.  Invalid nesting of tags will cause this context to shutdown with a status of C<CAIRO_STATUS_TAG_ERROR>.  See C<tag-begin()>.

  method tag-end ( Str $tag_name )

=item $tag_name; tag name. This can only be one of C<CAIRO_TAG_LINK> or C<CAIRO_TAG_DEST>.
=end pod

method tag-end ( Str $tag_name ) {
  cairo_tag_end( self._get-native-object-no-reffing, $tag_name)
}

sub cairo_tag_end (
  cairo_t $cr, gchar-ptr $tag_name
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:4:text-extents:
=begin pod
=head2 text-extents

Gets the extents for a string of text. The extents describe a user-space rectangle that encloses the "inked" portion of the text, (as it would be drawn by C<show-text()>). Additionally, the x_advance and y_advance values indicate the amount by which the current point would be advanced by C<show-text()>.

Note that whitespace characters do not directly contribute to the size of the rectangle (extents.width and extents.height). They do contribute indirectly by changing the position of non-whitespace characters. In particular, trailing whitespace characters are likely to not affect the size of the rectangle, though they will affect the x_advance and y_advance values.

  method text-extents ( Str $utf-string --> cairo_text_extents_t )

=item $utf8;
=item cairo_text_extents_t $extents; a NUL-terminated string of text encoded in UTF-8, or C<Any>
=end pod

method text-extents ( Str $utf-string --> cairo_text_extents_t ) {
  my cairo_text_extents_t $extents .= new;
  cairo_text_extents(
    self._get-native-object-no-reffing, $utf-string, $extents
  );

  $extents
}

sub cairo_text_extents (
  cairo_t $cr, gchar-ptr $utf-string, cairo_text_extents_t $extents is rw
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:text-path:
=begin pod
=head2 text-path

Adds closed paths for text to the current path.

The generated path if filled, achieves an effect similar to that of C<show-text()>.

Text conversion and positioning is done similar to C<show-text()>.

Like C<show-text()>, After this call the current point is moved to the origin of where the next glyph would be placed in this same progression.

That is, the current point will be at the origin of the final glyph offset by its advance values. This allows for chaining multiple calls to to C<text-path()> without having to set current point in between.

Note: The C<text-path()> function call is part of what the cairo designers call the "toy" text API. It is convenient for short demos and simple programs, but it is not expected to be adequate for serious text-using applications. See C<glyph-path()> for the "real" text path API in cairo.

  method text-path ( Str $utf8 )

=item $utf8; a string of text encoded in UTF-8.
=end pod

method text-path ( Str $utf8 ) {
  cairo_text_path( self._get-native-object-no-reffing, $utf8)
}

sub cairo_text_path (
  cairo_t $cr, gchar-ptr $utf8
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:transform:
=begin pod
=head2 transform

Modifies the current transformation matrix (CTM) by applying I<matrix> as an additional transformation. The new transformation of user space takes place after any existing transformation.

  method transform ( cairo_matrix_t $matrix )

=item $matrix; a transformation to be applied to the user-space axes
=end pod

method transform ( cairo_matrix_t $matrix ) {
  cairo_transform( self._get-native-object-no-reffing, $matrix)
}

sub cairo_transform (
  cairo_t $cr, cairo_matrix_t $matrix
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:translate:
=begin pod
=head2 translate

Modifies the current transformation matrix (CTM) by translating the user-space origin by (I<tx>, I<ty>). This offset is interpreted as a user-space coordinate according to the CTM in place before the new call to C<translate()>. In other words, the translation of the user-space origin takes place after any existing transformation.

  method translate ( Num() $tx, Num() $ty )

=item $tx; amount to translate in the X direction
=item $ty; amount to translate in the Y direction
=end pod

method translate ( Num() $tx, Num() $ty ) {
  cairo_translate( self._get-native-object-no-reffing, $tx, $ty)
}

sub cairo_translate (
  cairo_t $cr, gdouble $tx, gdouble $ty
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:user-to-device:
=begin pod
=head2 user-to-device

Transform a coordinate from user space to device space by multiplying the given point by the current transformation matrix (CTM).

  method user-to-device ( Num() $x is rw, Num() $y is rw )

=item $x; X value of coordinate
=item $y; Y value of coordinate
=end pod

method user-to-device ( Num() $x is rw, Num() $y is rw ) {
  my gdouble $xx = $x;
  my gdouble $yy = $y;
  cairo_user_to_device( self._get-native-object-no-reffing, $xx, $yy);
  $x = $xx;
  $y = $yy;
}

sub cairo_user_to_device (
  cairo_t $cr, gdouble $x is rw, gdouble $y is rw
) is native(&cairo-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:user-to-device-distance:
=begin pod
=head2 user-to-device-distance

Transform a distance vector from user space to device space. This function is similar to C<user-to-device()> except that the translation components of the CTM will be ignored when transforming (I<dx>,I<dy>).

  method user-to-device-distance ( Num() $dx is rw, Num() $dy is rw )

=item $dx; X component of a distance vector
=item $dy; Y component of a distance vector
=end pod

method user-to-device-distance ( Num() $x is rw, Num() $y is rw ) {
  my gdouble $xx = $x;
  my gdouble $yy = $y;
  cairo_user_to_device_distance( self._get-native-object-no-reffing, $xx, $yy);
  $x = $xx;
  $y = $yy;
}

sub cairo_user_to_device_distance (
  cairo_t $cr, gdouble $dx is rw, gdouble $dy is rw
) is native(&cairo-lib)
  { * }


