pod::Pr...rawable(3)

๐Ÿ“ฆ
version 1.74000 ยท 5 versions
, in opensuse-leap 16.0

๐Ÿ’– NAME ๐Ÿ’–

Prima::Drawable โ€” generic 2-D graphic interface.

Okay so this is the pod::Pr...rawable(3) manual page from User Contributed Perl Documentation, and yes bestie, that header is giving truncated-iconic, but the actual main character is Prima::Drawable.


๐ŸŒธ SYNOPSIS ๐ŸŒธ

if ( $object-> isa('Prima::Drawable')) {
     $object-> begin_paint;
     $object-> color( cl::Black);
     $object-> line( 100, 100, 200, 200);
     $object-> ellipse( 100, 100, 200, 200);
     $object-> end_paint;
}

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

Prima::Drawable is a descendant of the Prima::Component class. It gives you access to the system graphic context and the canvas through its methods and properties. The Prima::Drawable descendants โ€” Prima::Widget, Prima::Image, Prima::DeviceBitmap, and Prima::Printer โ€” are backed by system-dependent routines that allow drawing and painting on the system objects. Slay.


โœจ USAGE โœจ

Prima::Drawable, along with its ancestors Prima::Component and Prima::Object, is never used directly, because the Prima::Drawable class by itself provides only the interface. It gives you a three-state object access: when drawing and painting are enabled, when those are disabled, and the information acquisition state.

By default, the object is created in a paint-disabled state. To switch to the enabled state, the begin_paint() method is used. Once you're in the enabled state, the object's drawing and painting methods apply to the system canvas. To return to the disabled state, you call end_paint(). The information state can be managed with the begin_paint_info() and end_paint_info() method pair. An object cannot be triggered from the information state to the enabled state (and vice versa) directly. No cap.

๐ŸŽจ Graphic context and canvas ๐ŸŽจ

The graphic context is the set of variables that control how exactly graphic primitives are rendered. Examples of those variables are color, font, line width, etc. Another term used here is canvas โ€” the graphic area of a certain extent, connected to the Prima object, where the drawing and painting methods are used.

In all three states, a graphic context is allowed to be modified, but in different ways. In the disabled state, a graphic context value is saved as a template; when an object enters the information or the enabled state, all values are preserved, but when the object is back to the disabled state, the graphic context is restored to the values last assigned before entering the enabled state. The code example below illustrates the idea:

$d = Prima::Drawable-> create;
$d-> lineWidth( 5);
$d-> begin_paint_info;
# lineWidth is 5 here
$d-> lineWidth( 1);
# lineWidth is 1
$d-> end_paint_info;
# lineWidth is 5 again
Note: ::region and ::clipRect properties are exceptions. They cannot be used in the disabled state. The values of these properties, as well as the property ::matrix, are neither recorded nor used as a template.

That is, in the disabled state any Drawable maintains only the graphic context values. To draw on a canvas, the object must enter the enabled state by calling begin_paint(). This function can be unsuccessful because the object binds with system resources during this stage, and allocation of those may fail. Only after the enabled state is entered, the canvas is accessible:

$d = Prima::Image-> create( width => 100, height => 100);
if ( $d-> begin_paint) {
   $d-> color( cl::Black);
   $d-> bar( 0, 0, $d-> size);
   $d-> color( cl::White);
   $d-> fill_ellipse( $d-> width / 2, $d-> height / 2, 30, 30);
   $d-> end_paint;
} else {
   die "can't draw on image:$@";
}

Different objects are mapped to different types of canvases โ€” Prima::Image canvas retains its content after end_paint(), Prima::Widget maps it to some screen area, whose content is more transitory, etc.

The information state is the same as the enabled state, but the changes to the canvas are not visible. Its sole purpose is to read, not to write information. Because begin_paint() requires some amount of system resources, there is a chance that a resource request can fail, for any reason. begin_paint_info() requires some resources as well, but usually much less, and therefore if only information is desired, it is usually faster and cheaper to obtain it inside the information state. A notable example is the get_text_width() method, which returns the length of a text string in pixels. It works in both enabled and information states, but this code:

$d = Prima::Image-> create( width => 10000, height => 10000);
$d-> begin_paint;
$x = $d-> get_text_width('A');
$d-> end_paint;

is much more expensive than:

$d = Prima::Image-> create( width => 10000, height => 10000);
$d-> begin_paint_info;
$x = $d-> get_text_width('A');
$d-> end_paint_info;

for the obvious reasons. ๐Ÿ’ธ

It must be noted that some information methods like get_text_width() work even under the disabled state; the object is switched to the information state implicitly if it is necessary.

See also: graphic_context.

๐ŸŒˆ Color space ๐ŸŒˆ

Graphic context and canvas operations rely completely on a system implementation. The internal canvas color representation is therefore system-specific, and usually could not be described in Prima definitions. Often the only information available about color space is its color depth.

Therefore all color manipulations, including dithering and antialiasing, are subject to system implementation, and can not be controlled from perl code. When a property is set on the object in the disabled state, it is recorded verbatim; color properties are no exception. After the object switches to the enabled state, a color value is translated to the system color representation, which might be different from Prima's. For example, if the display color depth is 15 bits, 5 bits for every component, then the white color value 0xffffff is mapped to:

11111000 11111000 11111000
--R----- --G----- --B-----

that equals to 0xf8f8f8, not 0xffffff (see Prima::gp-problems for inevident graphic issues discussion).

The Prima::Drawable color format is RRGGBB, with each component resolution of 8 bits, thus allowing 2^24 color combinations. If the device color space depth is different, the color is truncated or expanded automatically. In case the device color depth is insufficient, dithering algorithms may apply.

Note: not only color properties but all graphic context properties allow all possible values in the disabled state, which are translated into system-allowed values when entering the enabled and the information states. This feature can be used to test if a graphic device is capable of performing certain operations (for example, if it supports raster operations โ€” the printers usually do not). Example:
$d-> begin_paint;
$d-> rop( rop::Or);
if ( $d-> rop != rop::Or) { # this assertion is always false without
   ...                      # begin_paint/end_paint brackets
}
$d-> end_paint;

There are two color properties on each drawable โ€” ::color and ::backColor. The values they operate on are unsigned integers in the discussed-above RRGGBB 24-bit format, however, the toolkit defines some mnemonic color constants as well:

cl::Black
cl::Blue
cl::Green
cl::Cyan
cl::Red
cl::Magenta
cl::Brown
cl::LightGray
cl::DarkGray
cl::LightBlue
cl::LightGreen
cl::LightCyan
cl::LightRed
cl::LightMagenta
cl::Yellow
cl::White
cl::Gray

It is not unlikely that if a device's color depth is insufficient, the primitives could be drawn with dithered or incorrect colors. This usually happens on paletted displays, with 256 or fewer colors.

There exist two methods that facilitate the correct color representation. The first way is to get as much information as possible about the device. The methods get_nearest_color() and get_physical_palette() provide a possibility to avoid mixed colors drawing by obtaining indirect information about solid colors supported by a device. Another method is to use the ::palette property. It works by inserting the colors into the system palette, so if an application knows the colors it needs beforehand, it can employ this method โ€” however, this might result in a system palette flash when a window focus toggles.

Both of these methods are applicable both with drawing routines and image output. An application that desires to display an image with the least distortion is advised to export its palette to an output device because images usually are not subject to automatic dithering algorithms. The Prima::ImageViewer module employs this scheme. ๐ŸŽ€

โœจ Antialiasing and alpha โœจ

If the system has the capability for antialiased drawing and alpha rendering, Prima can use it. The render mode can be turned on by calling:

$drawable->antialias(1)

which turns on the following effects:

  • All primitives except images, pixel, and bar_alpha can be plotted with antialiased edges (text is always antialiased when possible).
  • Graphic coordinates are then used as floating point numbers, not integers. That means that, for example, a call
$drawable->rectangle(5.3, 5.3, 10, 10)

that had its coordinates automatically rounded to (5,5,10,10), now will render the primitive with subpixel precision, where its two edges will be divided between pixels 5 and 6, by using half-tones.

Another note on the rounding of coordinates: historically almost all Prima pixel coordinates were integers, and implicit rounding of the passed numbers was done using the int function, i e int(0.7)=0 and int(-0.7)=0. This was later changed, breaking some backward compatibility, and now the rounding function is a more robust R = floor(x + 0.5), where R(0.7) = 1 and R(-0.7) = -1.

  • The coordinate offset (0,0) moves to the ephemeral point between screen pixels (0,0), (-1,0), (-1,-1), (0,-1), which in turn leads to different results when plotting closed shapes. F.ex. an ellipse with a diameter of 3 pixels looks like this:
                 Origin of the coordinate grid (0,0)

               ^                          ^
               |                          |
           .   |____   .              .   -   .   .
               |XXX|                      |
               |XXX|                      |
         --|---|---|--->            --|---X---|--->
               |                          |
               |                          |
           .   -   .   .              .   -   .   .
               |                          |

          antialias(0)               antialias(1)

                Ellipse with a diameter of 3 pixels

okay so picture this, bestie โ€” two lilโ€™ circles, one without antialiasing and one with it:

                          ^                          ^
                          |XXX                      X|X
                      .   |XXX.   .              . XX-XX .   .
                       XXX|XXX XXX                XXX|XXX
                       XXX|XXX XXX              X XXX|XXX X
                    --|---|---|--->            --|---|---|.-->
                          |XXX                  X XXX|XXX X
                          |XXX                    XXX|XXX
                      .   -   .   .              . XX-XX .   .
                          |                         X|X
                          |                          |

                     antialias(0)               antialias(1)

and that is why if you need to draw a robust graphic routine that would have more or less identical results in both antialiasing modes, the closed shapes may need to decrease the diameter by 1 pixel when the antialiasing mode is set. ๐Ÿ’…

For the cases where the system does not support antialiasing, Prima provides the Prima::Drawable::Antialias emulation class, available through the new_aa_surface call. โœจ

To see if alpha and antialiasing are supported on the system, check the sv::Antialias value. To see if a particular drawable supports alpha layering, check the can_draw_alpha method. ๐Ÿซถ

okay so heads up, bestie: in the render mode, all painting operations treat the alpha channel differently, which can have a dramatic difference on layered surfaces. In the normal mode, the alpha channel is completely ignored, and using normal mode paints on a layered widget always produces a translucent window because the alpha value will always be 0, and the color bits are assumed to be already premultiplied. In the render mode, the alpha channel is addressed by the alpha property when drawing primitives, or in the mask property when drawing icons (again, drawing images and non-layered bitmaps assumes alpha = 0). The same is valid for fill pattern images and fill pattern icons. ๐Ÿ’€

๐Ÿ–ค Monochrome bitmaps ๐Ÿ–ค

Prima has special rules when drawing a monochrome Prima::DeviceBitmap. Such objects donโ€™t possess an inherent color palette, and by definition are bitmaps with only two pixel values present, 0s and 1s. When a monochrome bitmap is drawn, 0s are painted using the color value of the target canvas color property, and 1s using the backColor value. ๐Ÿ–ค

That means that the following code

$bitmap-> color(0);
$bitmap-> line(0,0,100,100);
$target-> color(cl::Green);
$target-> put_image(0,0,$bitmap);

produces a green line on $target. ๐ŸŒˆ

When using monochrome bitmaps for logical operations, note that the target colors should not be explicit 0 and 0xffffff, nor cl::Black and cl::White, but cl::Clear and cl::Set instead. The reason is that on paletted displays, the system palette may not necessarily contain the white color under palette index (2^ScreenDepth-1). cl::Set thus signals that the value should be "all ones", no matter what color it represents because it will be used for logical operations. ๐Ÿ‘‘

๐ŸŽ€ Fonts ๐ŸŽ€

Prima maintains its own font naming convention which usually does not conform to the systemโ€™s. Since Primaโ€™s goal is interoperability, it might be so that some system fonts would not be accessible from within the toolkit. ๐Ÿ˜ญ

Prima::Drawable provides property ::font that accepts/returns a hash, that represents the state of a font in the system graphic context. The font hash keys that are acceptable on the set-call are: ๐ŸŽ€

  • name โ€” The font name string. If there is no such font, a default font name is used. To select the default font, a 'Default' string can be passed with the same result ( unless the system has a font named 'Default', of course).
  • height โ€” An integer value from 1 to MAX_INT. Specifies the desired extent of a font glyph between descent and ascent lines in pixels.
  • size โ€” An integer value from 1 to MAX_INT. Specifies the desired extent of a font glyph between descent and internal leading lines in points. The relation between size and height is
            height - internal_leading
  size =  --------------------------- * 72.27
                 resolution

That differs from some other system representations: Win32, for example, rounds 72.27 constant to 72. ๐Ÿ˜ฎ

  • width โ€” An integer value from 0 to MAX_INT. If greater than 0, specifies the desired extent of a font glyph width in pixels. If 0, sets the default ( designed ) width corresponding to the font size or height.
  • style โ€” A combination of fs:: ( font style ) constants. The constants
fs::Normal
fs::Bold
fs::Thin
fs::Italic
fs::Underlined
fs::StruckOut
fs::Outline

can be OR-ed together to express the font style. fs::Normal equals 0 and is usually never used. If some styles are not supported by a system-dependent font subsystem, they are ignored.

  • pitch โ€” One of three constants:
fp::Default
fp::Fixed
fp::Variable

fp::Default specifies no interest in the font pitch selection. fp::Fixed is set when a monospaced (all glyphs are of the same width) font is desired. fp::Variable pitch specifies a font with different glyph widths. This key is of the highest priority; all other keys may be altered for the consistency of the pitch key.

  • vector โ€” One of three constants:
fv::Default
fv::Bitmap
fv::Outline

fv::Default specifies no interest in the font type selection, fv::Bitmap sets the priority for the bitmap fonts, and fv::Outline for the vector fonts.

Additionally, font entries returned from the fonts method may set the vector field to fv::ScalableBitmap, to distinguish a bitmap font face that comes with predefined bitmap sets from a scalable font. ๐Ÿฆ‹

  • direction โ€” A counter-clockwise rotation angle - 0 is default, 90 is pi/2, 180 is pi, etc. If a font cannot be rotated, it is usually substituted with the one that can.
  • encoding โ€” A string value, one of the strings returned by Prima::Application::font_encodings. Selects the desired font encoding; if empty, picks the first matched encoding, preferably the locale set up by the user.

The encodings provided by different systems are different; in addition, the only encodings are recognizable by the system, that are represented by at least one font in the system.

Unix systems and the toolkit PostScript interface usually provide the following encodings:

iso8859-1
iso8859-2
... other iso8859 ...
fontspecific

Win32 returns the literal strings like

Western
Baltic
Cyrillic
Hebrew
Symbol

A hash that ::font returns, is a tied hash, whose keys are also available as separate properties. For example,

$x = $d-> font-> {style};

is equivalent to

$x = $d-> font-> style;

While the latter gives nothing but the arguable coding convenience, its usage in set-call is much more usable:

$d-> font-> style( fs::Bold);

instead of

my %temp = %{$d-> font};
$temp{ style} = fs::Bold;
$d-> font( \%temp);

The properties of a font-tied hash are also accessible through the set() call, like in Prima::Object:

$d-> font-> style( fs::Bold);
$d-> font-> width( 10);

is an equivalent to

$d-> font-> set(
   style => fs::Bold,
   width => 10,
);

When get-called, the ::font property returns a hash where more entries than those described above can be found. These keys are read-only, their values are ignored if passed to ::font in a set-call. ๐Ÿซถ

To query the full list of fonts available to a graphic device, the ::fonts method is used. This method is not present in the Prima::Drawable namespace; it can be found in two built-in class instances, Prima::Application and Prima::Printer. ๐Ÿ‘‘

Prima::Application::fonts returns metrics for the fonts available to the screen device, while Prima::Printer::fonts ( or its substitute Prima::PS::Printer ) returns fonts for the printing device. The result of this method is an array of font metrics, fully analogous to these returned by the Prima::Drawable::font method. โœจ

the read-only extras ๐Ÿ‘€ โ€” when you get-call ::font, you also get these keys, and they are read-only, so do not try to set them, bestie:

  • family โ€” A string with font family name. The family is a secondary string key, used for distinguishing between fonts with the same name but of different vendors ( for example, Adobe Courier and Microsoft Courier).
  • ascent โ€” Number of pixels between a glyph baseline and descent line.
  • descent โ€” Number of pixels between a glyph baseline and descent line.
  • internalLeading โ€” Number of pixels between ascent and internal leading lines. Negative if the ascent line is below the internal leading line.
  • externalLeading โ€” Number of pixels between ascent and external leading lines. Negative if the ascent line is above the external leading line.
                     ------------- external leading line

                $    ------------- ascent line
               $ $
                     ------------- internal leading line
                $
               $$$
              $   $
             $     $       $
             $$$$$$$    $$$
             $     $   $   $
             $     $   $   $
             $     $    $$$   ---- baseline
                           $
                            $
                            $
                        $$$$  ---- descent line
  • weight โ€” Font designed weight. Can be one of
fw::UltraLight
fw::ExtraLight
fw::Light
fw::SemiLight
fw::Medium
fw::SemiBold
fw::Bold
fw::ExtraBold
fw::UltraBold

constants.

  • maximalWidth โ€” The maximal extent of a glyph in pixels. Equals to width in monospaced fonts.
  • xDeviceRes โ€” Designed horizontal font resolution in dpi.
  • yDeviceRes โ€” Designed vertical font resolution in dpi.
  • firstChar โ€” Index of the first glyph present in a font.
  • lastChar โ€” Index of the last glyph present in a font.
  • breakChar โ€” Index of the default character used to divide words. In a typical Western language font it is 32, the ASCII space character.
  • defaultChar โ€” Index of a glyph that is drawn instead of a nonexistent glyph if its index is passed to the text drawing routines.
  • underlinePosition โ€” Position below baseline where to draw underscore line, in pixels. Is negative.
  • underlineThickness โ€” Pixel width of the underscore line

๐ŸŽ€ Font ABC metrics ๐ŸŽ€

Okay so besides those characteristics, every font glyph has an ABC metric โ€” three integer values that describe the horizontal extents of a glyph's black part relative to the glyph extent. It's giving geometry class but make it glyph:

    .  .     .  .      .  .        .  .
    .  .     $$$.      .  .        .  .
    .  .   $$.  $      .  .        .  .
    .  .   $$.  .      .  .     $$ .  .
    . $$$$$$$$$$.      .  .$$$$$   .  .
    .  .  $$ .  .      .  $    $$  .  .
    .  . $$  .  .      .  .$$$$$   .  .
    .  . $$  .  .      .  .    $$  .  .
    .  .$$   .  .      .  . $$$ $$$.  .
    $$ .$$   .  .      .  $       $$  .
    .$$$     .  .      .  .$$$$$$$$.  .
    .  .     .  .      .  .        .  .
    <A>.     .<C>      <A>.        .<C>
    .<-.--B--.->.      .  .<--B--->.  .

      A = -3                A = 3
      B = 13                B = 10
      C = -3                C = 3

So A and C are negative if a glyph "hangs" over its neighbors, like in the picture on the left. A and C values are positive if a glyph contains empty space in front of or behind the neighbor glyphs, like in the picture on the right. And as you can see, B is the width of a glyph's black part. No cap.

ABC metrics are returned by the get_font_abc() method.

The corresponding vertical metrics, called DEF metrics, are returned by the get_font_def() method. ๐Ÿฆ‹

๐Ÿ”ฅ Raster operations ๐Ÿ”ฅ

The Prima::Drawable class has two raster operation properties: ::rop and ::rop2. These define how the graphic primitives are plotted. ::rop deals with the foreground color drawing, and ::rop2 with the background. Main character energy for pixels, honestly.

๐ŸŒˆ Universal ROPs ๐ŸŒˆ

The toolkit defines the following operations:

rop::Blackness      #   = 0
rop::NotOr          #   = !(src | dest)
rop::NotSrcAnd      #  &= !src
rop::NotPut         #   = !src
rop::NotDestAnd     #   = !dest & src
rop::Invert         #   = !dest
rop::XorPut         #  ^= src
rop::NotAnd         #   = !(src & dest)
rop::AndPut         #  &= src
rop::NotXor         #   = !(src ^ dest)
rop::NotSrcXor      #     alias for rop::NotXor
rop::NotDestXor     #     alias for rop::NotXor
rop::NoOper         #   = dest
rop::NotSrcOr       #  |= !src
rop::CopyPut        #   = src
rop::NotDestOr      #   = !dest | src
rop::OrPut          #  |= src
rop::Whiteness      #   = 1

Usually, however, graphic devices support only a small part of the above set, limiting ::rop to the most important operations: Copy, And, Or, Xor, NoOp. ::rop2 is usually even more restricted, and supports only Copy and NoOp.

The raster operations apply to all graphic primitives except SetPixel.

Note for layering: using layered images and device bitmaps with put_image and stretch_image can only use rop::SrcCopy and rop::Blend raster operations on OS-provided surfaces. See more on rop::Blend below.

Also, the rop::AlphaCopy operation is available for accessing alpha bits only. When used, the source image is treated as an alpha mask, and therefore it has to be grayscale. It can be used to apply the alpha bits independently, without the need to construct an Icon object. Iconic.

๐Ÿ’… rop::Blend ๐Ÿ’…

rop::Blend is the same as rop::SrcOver except the source pixels are assumed to be already premultiplied with the source alpha. This is the default raster operation when drawing with 8-bit icon masks or on layered surfaces, and it reflects the expectation of the OS that images come premultiplied.

This is the only blending operator supported on the widgets and bitmaps, and it is advised to premultiply image pixels before drawing images using it with a call to the Image.premultiply_alpha method. The core image drawing supports this operator in case these premultiplied images are to be used not only on native surfaces but also on Prima images.

๐Ÿซถ Default raster operations ๐Ÿซถ

The put_image, stretch_image, and put_image_indirect methods are allowed to be called without explicitly specifying the ROP to be used. In this case, the default ROP, that depends on the source drawable, will be used. In the majority of cases the default ROP is rop::CopyPut, however, when drawing using layered device bitmaps and icons with 8-bit alpha masks, rop::Blend is used instead. This is a sort of a DWIM behavior.

This effect is achieved by translating the rop::Default constant via the get_effective_rop method, that can be used to detect what is the preferred raster operation for a source drawable. rop::Default can only be used in the aforementioned there methods, not in the rop property, not anywhere else. Yep โ€” only there. Not anywhere else. Periodt.

โญ Additional ROPs โญ

Prima core imaging supports extra features for compositing images outside the begin_paint/end_paint brackets. It supports the following 12+1 Porter-Duff operators and some selected Photoshop blend operators:

rop::Blend
rop::Clear            rop::Add
rop::Xor              rop::Multiply
rop::SrcOver          rop::Screen
rop::DstOver          rop::Overlay
rop::SrcCopy          rop::Darken
rop::DstCopy          rop::Lighten
rop::SrcIn            rop::ColorDodge
rop::DstIn            rop::ColorBurn
rop::SrcOut           rop::HardLight
rop::DstOut           rop::SoftLight
rop::SrcAtop          rop::Difference
rop::DstAtop          rop::Exclusion

๐Ÿ“ Transparency control ๐Ÿ“

There is defined a set of constants to apply a constant source and destination alpha to when there is no alpha channel available:

rop::SrcAlpha
rop::SrcAlphaShift
rop::DstAlpha
rop::DstAlphaShift

Combine the rop constant using this formula:

$rop = rop::XXX |
   rop::SrcAlpha | ( $src_alpha << rop::SrcAlphaShift ) |
   rop::DstAlpha | ( $dst_alpha << rop::DstAlphaShift )

or by calling rop::alpha($rop, [ $src_alpha, [ $dst_alpha ]]) that does the same.

Also, the function rop::blend($alpha) creates a rop constant for the simple blending of two images by the following formula:

$dst = ( $src * $alpha + $dst * ( 255 - $alpha ) ) / 255

rop::alpha also can be used for drawing on images outside begin_paint/end_paint with all Porter-Duff and Photoshop raster operators:

$image->rop( rop::alpha( rop::SrcOver, 128 ));
$image->ellipse( 5, 5, 5, 5 );

Note that when the raster operation is set to rop::SrcOver, the fully identical effect can be achieved by

$image->alpha(128);
$image->ellipse( 5, 5, 5, 5 );

as well, in a DWIM fashion. The only corner case here is when $image->alpha is 255; add the rop flags rop::DstAlpha | ( 255 < rop::DstAlphaShift ) to make sure that blending is selected. The corner case happens because the values of the Porter-Duff and bitwise rops clash, as the design was to make the values of rop::CopyPut and rop::Blend to be the same to serve as a sensible default. This may be resolved in future.

When used with icons, their source and/or destination alpha channels are additionally multiplied by these values.

๐ŸŒธ rop::ConstantColor ๐ŸŒธ

This bit is used when the alpha is defined but the main bits aren't. In this case, the main bits are filled from the destination's image color, and the source image is treated as the source alpha channel. The following code applies a solid green shade with a mask loaded from a file.

$src->load('8-bit gray mask.png');
$dst->color(cl::LightGreen);
$dst->put_image( 0,0,$src,rop::SrcOver | rop::ConstantColor);

๐Ÿฆ‹ Coordinates ๐Ÿฆ‹

The Prima toolkit employs the XY grid where X ascends rightwards and Y ascends upwards. There, the (0,0) location is the bottom-left pixel of a canvas. Cute, right? Bottom-left is home base.

All graphic primitives use inclusive-inclusive boundaries. For example,

$d-> bar( 0, 0, 1, 1);

plots a bar that covers 4 pixels: (0,0), (0,1), (1,0) and (1,1). Four whole pixels. Slay.

The coordinate origin can be shifted using the ::matrix property that translates the (0,0) point to the given offset. Calls to ::matrix, ::clipRect and ::region always use the 'physical' (0,0) point, whereas the plotting methods use the transformation result, the 'logical' (0,0) point.

As noted before, these three properties cannot be used when an object is in the disabled state.

๐Ÿงš Matrix ๐Ÿงš

The Prima::Drawable class accepts matrix scalars in the form of 6-item arrays that constitute the following 2-D transformation matrix

A B DX
C D DY
0 0 1

where the coordinate transformation follows this formula:

x' = A x + B x + DX
y' = C y + D y + DY

There are two accessors, get_matrix and set_matrix that return a copy of the current matrix or copy a new matrix, correspondingly, from and to the drawable object.

The 6-item array that get_matrix returns is also a blessed object of type Prima::matrix ( see Prima::matrix in Prima::types ) that is a separate copy of the object matrix. Prima::matrix objects feature a set of operations such as rotate and translate that transform the matrix further. To apply this matrix, one calls $drawable->set_matrix($matrix) or $matrix->apply($drawable).

There is also a property matrix that is not orthogonal to the get_matrix/ set_matrix method pair, as matrix returns a Prima::Matrix object, that, contrary to a Prima::matrix object returned by get_matrix, is a direct accessor to the drawable's matrix:

        my $m = $self->get_matrix;
        $m->translate(1,2);
        $self->set_matrix($m); # or $self->matrix($m);

is the same as

        $self->matrix->translate(1,2);

and does not need an explicit call to set_matrix or apply.

This class has all the methods the Prima::matrix has. See more in Prima::Matrix in Prima::types. See also: reset_matrix.

๐ŸŽ€ Custom line end styles ๐ŸŽ€

Prima uses its own plotting mechanism in Prima::Drawable::Path to produce all primitive shapes, including lines. The way lines are plotted is managed by the properties lineEnd, lineJoin, linePattern, and miterLimit. All of these properties are described below, however, lineEnd provides rich capabilities to generate custom line ends, and this is what is described in this section.

๐ŸŒˆ le:: namespace ๐ŸŒˆ

There are 3 predefined le:: integer constants

le::Flat
le::Square
le::Round

that are hardcoded in Prima, that are accepted by the lineEnd property. These constants are somewhat limited in the way one can operate them, for the sake of efficiency.

Okay so bestie, itโ€™s also possible to supply an array descriptor that defines a set of primitives that plot a line cap, automatically transformed with respect to the current line tangent and width. Details of the descriptor syntax itself are in the next section; hereโ€™s the set of non-hardcoded line end functions, which is also suitable for use in the "lineEnd" property.

le::Arrow
le::Cusp
le::InvCusp
le::Knob
le::Rect
le::RoundRect
le::Spearhead
le::Tail

These descriptors could be arbitrarily transformed (f ex scaled):

# all three lines produce the same effect
$x->lineEnd( le::scale( Arrow => 1.5 ) );
$x->lineEnd( le::transform( le::Arrow, [1.5,0,0,1.5,0,0] ) );
$x->lineEnd( le::transform( le::Arrow, Prima::matrix->new->scale(1.5) ) );

โœจ lineEnd accessors โœจ

The lineEnd property can accept up to 4 line end definitions, depending on syntax. When Prima plots lines, depending on the location of a line end, one of these 4 definitions is selected. Each definition also has its own property โ€” peep lineHead, lineTail, arrowHead, and arrowTail, or the index-based accessor lineEndIndex:

                  [ lineHeads and lineTails ]
           \____    ____    ___     __   ____   ___\
           /                                       /
        arrowTail                                  arrowHead

๐ŸŽ€ Line end syntax ๐ŸŽ€

The syntax for the custom line end style is:

syntax  ::= array of pairs
pair    ::= command, array of points
command ::= line or conic or cubic
points  ::= set of x,y coordinate pairs (vertices)

where individual commands accept an arbitrary number of vertices, but no less than 1 for line, 2 for conic, and 3 for cubic.

The commands are executed sequentially on a coordinate grid where the line width is assumed to be 1, the plotting starts from the point at (1,0) and ends at (-1,0).

For example, this is the definition of le::Arrow:

[
   conic => [1,0,2.5,0,2.5,-0.5],
   line  => [0,2.5],
   conic => [-2.5,-0.5,-2.5,0,-1,0]
]

๐ŸŒˆ API ๐ŸŒˆ

๐Ÿ’… Graphic context properties ๐Ÿ’…

alpha INTEGER

Sets the alpha component of the brush, where 0 is fully transparent and 255 is fully opaque.

Note that premultiplication of color and backColor is not necessary as it is done internally.

Default: 255

antialias BOOLEAN

Turns on and off antialiased drawing on all primitives, excluding image, pixel, and bar_alpha calls.

It will not be possible to turn the property on if the system does not support it. Also, monochrome images won't support it as well.

See "Antialiasing and alpha".

arrowHead

Defines the style to paint line heads on starting or ending points used to define a line or polygon. Is never used on closed shapes. If undef, the heads are painted with the same style as lineHead.

Default value: le::Round. Cannot be undef.

arrowTail

Defines the style to paint line tails on starting or ending points used to define a line or a polygon. Is never used on closed shapes. If undef, the heads are painted with the same style as lineTail; if it is also undef, then the style of lineHead is used.

Default value: undef

backColor COLOR

Sets background color to the graphic context. All drawing routines that use non-solid or transparent fill or line patterns use this property value.

color COLOR

Sets foreground color to the graphic context. All drawing routines use this property value.

clipRect X1, Y1, X2, Y2

Selects the clipping rectangle corresponding to the physical canvas origin. On get-call, returns the extent of the clipping area, if it is not rectangular, or the clipping rectangle otherwise. The code

$d-> clipRect( 1, 1, 2, 2);
$d-> bar( 0, 0, 1, 1);

thus affects only one pixel at (1,1).

Set-call discards the previous ::region value.

๐Ÿšจ Note: ::clipRect can not be used while the object is in the paint-disabled state, its context is neither recorded nor used as a template ( see "Graphic context and canvas") -- except on images.

fillMode INTEGER

Affects the filling style of complex polygonal shapes filled by fillpoly. If fm::Winding, the filled shape contains no holes; if fm::Alternate, holes are present where the shape edges cross.

The fm::Overlay flag can be combined with these to counter an intrinsic defect of filled shapes both in Win32 and X11 that don't exactly follow polygon vertices. When supplied, it overlays a polygon over the filled shape, so that the latter falls exactly in the boundaries defined by vertices. This is desirable when one wants the shape to be defined exactly by polygon vertices but is not desirable when a shape has holes in it and is connected in a way that the polygon overlay may leave visible connection edges over them.

Default value: fm::Winding|fm::Overlay

fillPattern ( [ @PATTERN ] ) or ( fp::XXX ) or IMAGE

Selects 8x8 fill pattern that affects primitives that plot filled shapes: bar(), fill_chord(), fill_ellipse(), fillpoly(), fill_sector(), floodfill().

Accepts either a fp:: constant or a reference to an array of 8 integers, or an image reference. In all cases, except where the image is colored, treats 0s in the pattern as the currently selected backColor, and 1s as color. When rop2 is set to rop::NoOper, treats 0s as fully transparent pixels. Additionally, when in the render mode respects the alpha property.

๐Ÿšจ Note: Drawing over a monochrome bitmap or image will not respect its rop on Win32.

Depending on the parameters, treats the input as follows:

fp:: constant โ€” There are some predefined patterns, that can be referred to via fp:: constants:

  • fp::Empty
  • fp::Solid
  • fp::Line
  • fp::LtSlash
  • fp::Slash
  • fp::BkSlash
  • fp::LtBkSlash
  • fp::Hatch
  • fp::XHatch
  • fp::Interleave
  • fp::WideDot
  • fp::CloseDot
  • fp::SimpleDots
  • fp::Borland
  • fp::Parquet

( the actual patterns are hardcoded in api/api.c ) The default pattern is fp::Solid.

On a get-call, does not return the fp:: value but the corresponding array (see below). If a constant value is needed to be recovered, use the fp::builtin function that would return the constant from the array. There are also two shortcut functions, fp::is_solid and fp::is_empty that check if the fill pattern is all-ones or all-zeros, correspondingly.

Array โ€” Wants an 8-item array where each item is a byte value, representing 8 bits of each line in a pattern. The first integer is the topmost pattern line, and the bit 0x80 is the leftmost pixel in the line.

An example below shows the encoding of the fp::Parquet pattern:

   # 76543210
     84218421  Hex

   0  $ $   $  51
   1   $   $   22
   2    $ $ $  15
   3 $   $     88
   4  $   $ $  45
   5   $   $   22
   6  $ $ $    54
   7 $   $     88

   $d-> fillPattern([ 0x51, 0x22, 0x15, 0x88, 0x45, 0x22, 0x54, 0x88 ]);

Monochrome image โ€” Like the array above, wants an image consisting of 0s and 1s where these would represent the target canvas' backColor and color property values, correspondingly, when rendered. In the same fashion, when rop2 is set to rop::NoOper, zeros will be treated as transparent pixels.

Color image โ€” Ignores color, and backColor, and rop2. Just uses the tiles and the current alpha value.

Icon โ€” Ignores color, backColor, and rop2. Uses the alpha pixel values from the icon's mask and the current alpha value.

fillPatternOffset X, Y

Origin coordinates for the fillPattern. Image patterns origin (0,0) is system-dependent.

font %FONT

Manages font context. FONT hash acceptable values are name, height, size, width, style and pitch.

Synopsis:

$d-> font-> size( 10);
$d-> font-> name( 'Courier');
$d-> font-> set(
  style => $x-> font-> style | fs::Bold,
  width => 22
);

See "Fonts" for the detailed descriptions.

Applies to text_out(), get_text_width(), get_text_box(), get_font_abc(), get_font_def(), render_glyph().

font_mapper

Returns a font mapper object that provides the interface to a set of fonts used for substitution in polyfont shaping (see "text_shape"). The fonts can be accessed there either by their font hash (name and style only, currently), or the font's corresponding index.

There are two font lists used in the substitution mechanism, passive and active. The passive font list is initiated during the toolkit start and is never changed. Each font there is addressed by an index. When the actual search for a glyph is initiated, these fonts are queried in the loop and are checked if they contain the required glyphs. These queries are also cached so that next time lookups run much quicker. That way, an "active" font list is built, and the next substitutions use it before trying to look into the passive list. Since the ordering of fonts is system-based and is rather random, some fonts may not be a good or aesthetic substitution. Therefore the mapper can assist in adding or removing particular fonts to the active list, potentially allowing an application to store and load a user-driven selection of substitution fonts.

The following methods are available on the font mapper object:

  • activate %FONT โ€” Adds the FONT into the active substitution list if the font is not disabled
  • get INDEX โ€” Returns the font hash registered under INDEX
  • count โ€” Returns the number of all fonts in the collection
  • index โ€” Returns what index is assigned to the currently used font, if any
  • passivate %FONT โ€” Remove the font from the active substitution list

๐Ÿ’… is_active %FONT

Tells you whether the font is chilling in the active substitution list or not. That's the whole vibe check โ€” yes or no, no cap.

โœจ enable %FONT

Turns the font entry on, so it actually gets considered when the polyfont lookup goes shopping for a match. Slay.

๐Ÿšซ disable %FONT

Turns the font entry off โ€” it will not be considered for the polyfont lookup at all. It's giving benched.

๐Ÿซถ is_enabled %FONT

Returns whether the font is enabled or not. Basically the read-only twin of the two above, iykyk.


๐ŸŽ€ lineHead

Defines the style used to paint line heads โ€” in patterned lines only, and only on those line segments that don't lie on the line starting or ending points used to define a line or polygon. Very picky, very demure.

Default value: undef

๐Ÿ”ฅ lineEnd VALUE

Picks a line ending cap for plotting primitives. VALUE can be one of these constants:

le::Arrow
le::Cusp
le::InvCusp
le::Flat
le::Knob
le::Rect
le::RoundRect
le::Spearhead
le::Square
le::Round
le::Tail

โ€ฆor undef, or a custom line end description, or an array of four where each entry is one of the values above. Build-a-cap, basically ๐Ÿ’…

Heads up tho: the undef value is only accepted in the array syntax, never for index 0 (lineHead). The other indexes behave differently if they're set to undef โ€” see lineTail, arrowHead, arrowTail, and lineEndIndex for the tea.

le::Round is the default value. Iconic.

See also: "Custom line end styles".

๐ŸŒˆ lineEndIndex INDEX, VALUE

Same as lineEnd except it only addresses a single line ending style. One at a time, bestie.

Allows VALUE to be undef for indexes greater than 0; depending on the index, the line style will be different (see lineTail, arrowHead, arrowTail).

It also allows special INDEX values or'ed with le::Only, which behave differently if the line end style is undef: while normal INDEX queries may return undef, or possibly affect neighbor indexing (if those are, in turn, undefs), the calls with the le::Only bit set never return undef on get-calls, and never affect neighbor styles on set-calls. So well-behaved ๐Ÿ˜ญ

The following lookup rules are used if a line end style is undef:

lei::LineTail  - can never be undef
lei::LineHead  - if undef, same as lei::LineTail
lei::ArrowTail - if undef, same as lei::LineTail
lei::ArrowHead - if undef, same as lei::LineHead, and if it also is undef, then same as lei::LineTail

๐Ÿฆ‹ lineJoin VALUE

Selects a line joining style for polygons. VALUE can be one of the

lj::Round
lj::Bevel
lj::Miter

constants. lj::Round is the default value.

๐Ÿ“ linePattern PATTERN

Selects a line pattern for plotting primitives. PATTERN is either a predefined lp:: constant, or a string where each even byte is the length of a dash and each odd byte is the length of a gap. Byte-by-byte, we love a binary queen.

The predefined constants are:

lp::Null           #    ""              /*              */
lp::Solid          #    "\1"            /* ___________  */
lp::Dash           #    "\x9\3"         /* __ __ __ __  */
lp::LongDash       #    "\x16\6"        /* _____ _____  */
lp::ShortDash      #    "\3\3"          /* _ _ _ _ _ _  */
lp::Dot            #    "\1\3"          /* . . . . . .  */
lp::DotDot         #    "\1\1"          /* ............ */
lp::DashDot        #    "\x9\6\1\3"     /* _._._._._._  */
lp::DashDotDot     #    "\x9\3\1\3\1\3" /* _.._.._.._.. */
Lowkey important: not all systems are capable of accepting user-defined line patterns, and in such a situation the lp:: constants are mapped to the system-defined patterns. In Win9x, for example, lp::DashDotDot is much different from its string definition. This however is only actual for lines with width=0, since wider lines are rendered by the Prima internal code. โœจ

The default value is lp::Solid.

๐Ÿ’œ lineTail

Defines the style to paint line tails โ€” again, in patterned lines only, on line segments that do not lie on the line starting or ending points used to define a line or polygon. If undef, line tails are painted with the same style as lineHead. Copying her sister's fit, respectfully.

Default value: undef

๐Ÿงš lineWidth WIDTH

Selects a line width for plotting primitives when antialias is 0. If a VALUE is 0, then a cosmetic pen is used โ€” the thinnest possible line that a device can plot. If a VALUE is greater than 0, then a geometric pen is used โ€” the line width is set in device units. And yes, there's a subtle difference between VALUE 0 and 1 in the way the lines are joined. Zero and one are not the same, bestie ๐Ÿ™ˆ

When antialias is 1, the geometric plotting algorithm is always used.

Default value: 0

๐Ÿ‘‘ matrix [A,B,C,D,X,Y] | Prima::Matrix

Sets the current matrix transformation that's used in all plotting operations except clipRect and region. Returns a Matrix in Prima object.

The default value is (1,0,0,1,0,0) or Prima::matrix::identity.

Note: ::matrix can not be used while the object is in the paint-disabled state โ€” its context is neither recorded nor used as a template (see "Graphic context and canvas").

See also: Prima::matrix in Prima::types and Prima::types/Prima::Matrix.

๐Ÿ“ miterLimit VALUE

Okay so picture this: when path segments connect at a sharp angle, a miter join results in a spike that extends well beyond the connection point. The whole purpose of the miter limit is to cut off such spikes when they become objectionably long. At any given corner, the miter length is the distance from the point at which the inner edges of the stroke intersect to the point at which the outside edges of the strokes intersect โ€” in other words, the diagonal length of the miter. This distance increases as the angle between the segments decreases. If the ratio of the miter length to the line width exceeds the miter limit parameter, stroke treats the corner with a bevel join instead of a miter join. The ratio of miter length to line width is directly related to the angle j between the segments by the formula:

r = 1/sin(j/2)

Default value: 10.0

Assuming the line join is lj::Miter and the line angle is 30 degrees:

miter limit = 1.0: \__/

miter limit = 9.0: \  /
                    \/

๐ŸŽจ palette [ @PALETTE ]

Requests to install solid colors into the system palette, as many as possible. PALETTE is an array of integer triplets, where each is the R, G, and B components. So the call

$d-> palette([128, 240, 240]);

selects a gray-cyan color, for example. Cute, right? ๐Ÿ’–

The return value from the get-call is the content of the previous set-call, not the actual colors that were copied to the system palette. Yes, she's a little quirky like that.

๐Ÿ–ผ๏ธ region OBJECT

Selects a clipping region applied to all drawing and painting routines. In the set-call, the OBJECT is either undef, in which case the clip region is erased (no clip), or a Prima::Image object with a bit depth of 1, or a Prima::Region object. The bit mask of the OBJECT is applied to the system clipping region. If the OBJECT is smaller than the drawable, its exterior is assigned to the clipped area as well. This discards the previous ::clipRect value; successive get-calls to ::clipRect return the boundaries of the region.

In the get-mode it returns either undef or a Prima::Region object.

Note: ::region can not be used while the object is in the paint-disabled state โ€” its context is neither recorded nor used as a template (see "Graphic context and canvas").

๐Ÿ” resolution X, Y

A read-only property. Returns horizontal and vertical device resolution in dpi. Look but don't touch โœจ

โšก rop OPERATION

Selects the raster operation that applies to foreground color plotting routines.

See also: ::rop2, "Raster operations".

๐ŸŒ™ rop2 OPERATION

Selects the raster operation that applies to background color plotting routines.

See also: ::rop, "Raster operations".

๐Ÿ“ textOpaque FLAG

If FLAG is 1, then text_out() fills the text background area with the ::backColor property value before drawing the text. The default value is 0, when text_out() plots text only.

In the system-based text drawing, if the background area is filled, then the alpha value is ignored. In the standalone text drawing, if the background area is filled, then the alpha value is not ignored. Different strokes for different code paths, literally ๐Ÿ˜ญ

See get_text_box().

๐Ÿงต textOutBaseline FLAG

If FLAG is 1, then text_out() plots text on a given Y coordinate correspondent to the font baseline. If FLAG is 0, a Y coordinate is mapped to the font descent line. The default value is 0.

๐Ÿ”„ translate X_OFFSET, Y_OFFSET

Translates the origin point by X_OFFSET and Y_OFFSET. Does not affect ::clipRect and ::region. Not cumulative, so this call sequence

$d-> translate( 5, 5);
$d-> translate( 15, 15);

is equivalent to

$d-> translate( 15, 15);
Note: ::translate can not be used while the object is in the paint-disabled state โ€” its context is neither recorded nor used as a template (see "Graphic context and canvas").

๐ŸŽ€ Other properties

๐Ÿ“ height HEIGHT

Selects the height of a canvas.

๐Ÿงธ size WIDTH, HEIGHT

Selects the extent of a canvas.

๐ŸŒธ width WIDTH

Selects the width of a canvas.


๐Ÿ–Œ๏ธ Graphic primitives methods

๐ŸŒˆ arc X, Y, DIAMETER_X, DIAMETER_Y, START_ANGLE, END_ANGLE

Plots an arc with the center in X, Y, and DIAMETER_X and DIAMETER_Y axes, from START_ANGLE to END_ANGLE.

Context used: color, backColor, lineEnd, linePattern, lineWidth, miterLimit, rop, rop2

๐Ÿฌ bar X1, Y1, X2, Y2

Draws a filled rectangle. Simple as that, and she ate.

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2

๐Ÿซง bar_alpha ALPHA <X1, Y1, X2, Y2>

Fills a rectangle in the alpha channel bits only, using the ALPHA value between (0-255). Can be called without parameters โ€” in this case it fills the whole canvas. Ghost-mode rectangle, spooky โœจ

Has only effect on the layered surfaces.

๐Ÿง bars @RECTS

Draws a set of filled rectangles. RECTS is an array of integer quartets in the format (X1,Y1,X2,Y2). Bulk bar-ing, obsessed.

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2

๐Ÿ’ซ chord X, Y, DIAMETER_X, DIAMETER_Y, START_ANGLE, END_ANGLE

Plots an arc with the center in X, Y, and DIAMETER_X and DIAMETER_Y axes from START_ANGLE to END_ANGLE, and connects its ends with the straight line. Arc but make it closed ๐Ÿ’…

Context used: color, backColor, lineEnd, linePattern, lineWidth, miterLimit, rop, rop2

okay so next up in the drawable method lineup ๐Ÿ’… these are the canvas moves you'll be calling constantly, bestie.

clear <X1, Y1, X2, Y2> ๐Ÿงฝ

Draws a rectangle filled with the background color. You can call it with no parameters at all, and in that case it fills the whole canvas. whole-canvas reset, iconic.

Context used: backColor, rop2.

draw_text CANVAS, TEXT, X1, Y1, X2, Y2, [ FLAGS = dt::Default, TAB_INDENT = 1 ] ๐Ÿ’ฌ

Draws multiple lines of text stacked one under another, respecting the align and break rules you pass in FLAGS, plus the TAB_INDENT tab-character expansion. draw_text is a convenience wrapper around text_wrap for drawing the wrapped text, and it also gives you tilde (~)-character underlining support. bestie, it's giving โ€œtext layout but make it convenient.โ€ โœจ

FLAGS is a combination of these constants:

  • dt::Left โ€” text is aligned to the left boundary
  • dt::Right โ€” text is aligned to the right boundary
  • dt::Center โ€” text is aligned horizontally in the center
  • dt::Top โ€” text is aligned to the upper boundary
  • dt::Bottom โ€” text is aligned to the lower boundary
  • dt::VCenter โ€” text is aligned vertically in the center
  • dt::DrawMnemonic โ€” tilde-escapement and underlining is used
  • dt::DrawSingleChar โ€” sets tw::BreakSingle option to Prima::Drawable::text_wrap call
  • dt::NewLineBreak โ€” sets tw::NewLineBreak option to Prima::Drawable::text_wrap call
  • dt::SpaceBreak โ€” sets tw::SpaceBreak option to Prima::Drawable::text_wrap call
  • dt::WordBreak โ€” sets tw::WordBreak option to Prima::Drawable::text_wrap call
  • dt::ExpandTabs โ€” performs tab character (\t) expansion
  • dt::DrawPartial โ€” draws the last line, if it is visible partially
  • dt::UseExternalLeading โ€” text lines positioned vertically with respect to the font external leading
  • dt::UseClip โ€” assign ::clipRect property to the boundary rectangle
  • dt::QueryLinesDrawn โ€” calculates and returns the number of lines drawn (contrary to dt::QueryHeight)
  • dt::QueryHeight โ€” if set, calculates and returns vertical extension of the lines drawn
  • dt::NoWordWrap โ€” performs no word wrapping by the width of the boundaries
  • dt::WordWrap โ€” performs word wrapping by the width of the boundaries
  • dt::Default โ€” dt::NewLineBreak|dt::WordBreak|dt::ExpandTabs|dt::UseExternalLeading

Context used: color, backColor, font, rop, textOpaque, textOutBaseline.

ellipse X, Y, DIAMETER_X, DIAMETER_Y ๐Ÿฅš

Plots an ellipse with the center in X, Y, and DIAMETER_X and DIAMETER_Y axes.

Context used: color, backColor, linePattern, lineWidth, rop, rop2.

fill_chord X, Y, DIAMETER_X, DIAMETER_Y, START_ANGLE, END_ANGLE ๐Ÿ•

Fills a chord outline with the center in X, Y, and DIAMETER_X and DIAMETER_Y axes from START_ANGLE to END_ANGLE (see chord()).

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2.

fill_ellipse X, Y, DIAMETER_X, DIAMETER_Y ๐ŸŒธ

Fills an elliptical outline with the center in X, Y, and DIAMETER_X and DIAMETER_Y axes.

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2.

fillpoly \@POLYGON ๐Ÿ”บ

Fills a polygonal area defined by the POLYGON set of points. POLYGON must present an array of (X,Y) integer pairs. Example, bestie:

$d-> fillpoly([ 0, 0, 15, 20, 30, 0]); # triangle

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2, fillMode.

Returns success flag; if failed, $@ contains the error.

See also: polyline().

fill_sector X, Y, DIAMETER_X, DIAMETER_Y, START_ANGLE, END_ANGLE ๐Ÿฐ

Fills a sector outline with the center in X, Y, and DIAMETER_X and DIAMETER_Y axes from START_ANGLE to END_ANGLE (see sector()).

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2.

fill_spline \@VERTICES, %OPTIONS ๐ŸŒ€

Fills a polygonal area defined by the curve projected by applying a B-spline curve based on a set of VERTICES. VERTICES must present an array of (X,Y) integer pairs. Example:

$d-> fill_spline([ 0, 0, 15, 20, 30, 0]);

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2.

Returns success flag; if failed, $@ contains the error.

See also: spline, render_spline.

flood_fill X, Y, COLOR, SINGLEBORDER = 1 ๐ŸŒŠ

Fills an area of the canvas using the current fill context. The area is assumed to be bounded as specified by the SINGLEBORDER parameter. SINGLEBORDER can be 0 or 1.

  • SINGLEBORDER = 0: The fill area is bounded by the color specified by the COLOR parameter.
  • SINGLEBORDER = 1: The fill area is defined by the color that is specified by COLOR.

Filling continues outward in all directions as long as the color is encountered. This style is useful for filling areas with multicolored boundaries. flood fill said โ€œI go where the color goes,โ€ periodt.

Context used: color, backColor, fillPattern, fillPatternOffset, rop, rop2.

line X1, Y1, X2, Y2 ๐Ÿ“

Plots the straight line from (X1,Y1) to (X2,Y2).

Context used: color, backColor, linePattern, lineWidth, rop, rop2.

lines \@LINES ๐Ÿงต

LINES is an array of integer quartets in format (X1,Y1,X2,Y2). lines() plots the straight line per quartet.

Context used: color, backColor, linePattern, lineWidth, rop, rop2.

Returns success flag; if failed, $@ contains the error.

new_aa_surface ๐Ÿชž

Returns a new antialiasing surface object for AA emulation. See Prima::Drawable::Antialias for usage and details.

new_gradient ๐ŸŒˆ

Returns a new gradient object. See Prima::Drawable::Gradient for usage and details.

new_path ๐Ÿ›ค๏ธ

Returns a new path object. See Prima::Drawable::Path for usage and details.

pixel X, Y, <COLOR> ๐Ÿ”

::pixel is a property โ€” on set-call it changes the pixel value at (X,Y) to COLOR, on get-call (without COLOR) it does return a pixel value at (X,Y).

No context is used except matrix transformation of the coordinates. May return cl::Invalid to signal an error or the out-of-boundaries condition.

polyline \@POLYGON ๐Ÿ“

Draws a polygonal area defined by the POLYGON set of points. POLYGON must contain an array of integer pairs in (X,Y) format.

Context used: color, backColor, linePattern, lineWidth, lineJoin, lineEnd, miterLimit, rop, rop2.

Returns success flag; if failed, $@ contains the error.

See also: fillpoly().

put_image X, Y, OBJECT, [ ROP=rop::Default] ๐Ÿ–ผ๏ธ

Draws an OBJECT at coordinates (X,Y). OBJECT must be Prima::Image, Prima::Icon, or Prima::DeviceBitmap. If ROP raster operation is specified, it is used. Otherwise, the current value of the ::rop property is used.

Returns success flag; if failed, $@ contains the error.

Context used: rop; color and backColor for a monochrome DeviceBitmap.

put_image_indirect OBJECT, X, Y, X_FROM, Y_FROM, DEST_WIDTH, DEST_HEIGHT, SRC_WIDTH, SRC_HEIGHT, [ROP=rop::Default] ๐Ÿช„

Draws the OBJECT's source rectangle into the destination rectangle, stretching or compressing the source bits to fit the dimensions of the destination rectangle, if necessary. The source rectangle starts at (X_FROM,Y_FROM), and is SRC_WIDTH pixels wide and SRC_HEIGHT pixels tall. The destination rectangle starts at (X,Y), and is abs(DEST_WIDTH) pixels wide and abs(DEST_HEIGHT) pixels tall. If DEST_WIDTH or DEST_HEIGHT are negative, a mirroring by the respective axis is performed.

OBJECT must be Prima::Image, Prima::Icon, or Prima::DeviceBitmap.

No context is used, except color and backColor for a monochrome DeviceBitmap.

Returns success flag; if failed, $@ contains the error.

rect3d X1, Y1, X2, Y2, WIDTH, LIGHT_COLOR, DARK_COLOR, [ BACK_COLOR ] ๐ŸงŠ

Draws a 3d-shaded rectangle (X1,Y1 - X2,Y2) with WIDTH line width, and LIGHT_COLOR and DARK_COLOR colors. If BACK_COLOR is specified, paints an inferior rectangle with it, otherwise the inferior rectangle is not touched.

Context used: rop; color and backColor for a monochrome DeviceBitmap.

rect_fill X1, Y1, X2, Y2, BORDER_WIDTH, FOREGROUND, BACKGROUND ๐ŸŽจ

Draws a rectangle with outline color FOREGROUND and BORDER_WIDTH pixels, and fills it with color BACKGROUND. If FOREGROUND and/or BACKGROUND are undefined, current colors are used. BORDER_WIDTH is 1 pixel if omitted.

Contrary to a call to rectangle() with the line width greater than 1, never paints pixels outside the given rectangle; the border is painted inwards. inward border is the whole vibe here, no spillage.

Context used: rop, fillPattern.

rect_focus X1, Y1, X2, Y2, [ WIDTH = 1 ] ๐ŸŽฏ

Draws a marquee rectangle in boundaries X1,Y1 - X2,Y2 with WIDTH line width.

No context is used.

rect_solid X1, Y1, X2, Y2, BORDER_WIDTH, FOREGROUND ๐Ÿงฑ

Draws a rectangle with outline color FOREGROUND and BORDER_WIDTH pixels. If FOREGROUND is undefined, a current color is used. BORDER_WIDTH is 1 pixel if omitted.

Contrary to a call to rectangle() with line width greater than 1, never paints pixels outside the given rectangle; the border is painted inwards.

Context used: rop.

rectangle X1, Y1, X2, Y2 โฌœ

Plots a rectangle with (X1,Y1) - (X2,Y2) extents.

Context used: color, backColor, linePattern, lineWidth, rop, rop2.

sector X, Y, DIAMETER_X, DIAMETER_Y, START_ANGLE, END_ANGLE ๐Ÿฅง

Plots an arc with the center in X, Y, and DIAMETER_X and DIAMETER_Y axis from START_ANGLE to END_ANGLE and connects its ends and (X,Y) with two straight lines.

Context used: color, backColor, lineEnd, linePattern, lineWidth, miterLimit, rop, rop2.

spline \@VERTICES, %OPTIONS ๐ŸŽ€

Draws a B-spline curve defined by a set of VERTICES control points. VERTICES must present an array of (X,Y) integer pairs.

The extra options knots and weights described below allow to upgrade the B-spline into a NURBS curve. See https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline.

The following options are supported:

  • closed BOOL = undef โ€” When not set, checks if the first and the last vertices point to the same point, and assumes a closed shape if they do. Note - a closed shape rendering is implemented by adding a degree minus two points to the set; this is important if weight or knots are specified.
  • degree INTEGER = 2 โ€” the B-spline degree, bestie. Default is 2 (quadratic), and the number of points supplied must be at least a degree plus one. โœจ
  • knots \@INTEGERS โ€” an array of N integers ( N = number of points plus degree plus one ). By default, if the shape is opened (i.e. first and last points are different), this represents a clamped array, so that the first and last points of the final curve match the first and the last control points. If the shape is closed, it represents an unclamped array so that no control points lie directly on the curve.

Wikipedia says, and I quote (this part is important, bestie):

"The knot vector is a sequence of parameter values that determines where and how the control points affect the NURBS curve... The knot vector divides the parametric space in the intervals ... usually referred to as knot spans. Each time the parameter value enters a new knot span, a new control point becomes active, while an old control point is discarded. It follows that the values in the knot vector should be in nondecreasing order, so (0, 0, 1, 2, 3, 3) is valid while (0, 0, 2, 1, 3, 3) is not."
  • precision INTEGER = 24 โ€” defines the number of steps to split the curve into. The value is multiplied by the number of points and the result is used as the number of steps. ๐ŸŽ€
  • weight \@INTEGERS = [ 1, 1, 1, ... ] โ€” an array of integers, one for each point supplied. Assigning these can be used to convert B-spline into a NURBS. By default it's a set of ones. ๐Ÿฆ‹

Context used: color, backColor, linePattern, lineWidth, lineEnd, miterLimit, rop, rop2

See also: fill_spline, render_spline.


stretch_image

stretch_image X, Y, DEST_WIDTH, DEST_HEIGHT, OBJECT, [ ROP=rop::Default ]

Draws the OBJECT on the destination rectangle, stretching or compressing the source bits to fit the dimensions of the destination rectangle, if necessary. If DEST_WIDTH or DEST_HEIGHT are negative, a mirroring is performed. The destination rectangle starts at (X,Y) and is DEST_WIDTH pixels wide and DEST_HEIGHT pixels tall. ๐Ÿ’…

If ROP raster operation is specified, it is used. Otherwise, the value of the ::rop property is used.

OBJECT must be Prima::Image, Prima::Icon, or Prima::DeviceBitmap.

Returns success flag; if failed, $@ contains the error.

Context used: rop


text_out

text_out TEXT, X, Y

Draws TEXT string at (X,Y). TEXT is either a character string or a Prima::Drawable::Glyphs object returned from text_shape, or Prima::Drawable::Glyphs->glyphs strings of glyphs.

Returns success flag; if failed, $@ contains the error.

Context used: color, backColor, font, rop, textOpaque, textOutBaseline


text_shape

text_shape TEXT, %OPTIONS

Converts TEXT into a set of glyphs, returns either a Prima::Drawable::Glyphs object, or a 0 integer when shaping is not necessary, or undef as an error. ๐Ÿ˜ญ

When Prima is compiled with libfribidi, the method runs the unicode bidirectional algorithm on TEXT that properly positions embedded directional text (f.ex. a Latin quote inside an Arabic text), see Unicode Standard Annex #9 for the details. Without the library it only does minimal RTL alignment.

Glyphs returned are positioned according to RTL directions given in TEXT using characters from unicode block General Punctuation U+2000 .. U+206F. Additionally, character ligation may be performed so that one or more characters are represented by one or more glyphs. Such syntactic units, clusters, are adopted in Prima where appropriate, instead of character units, for selection, navigation, etc in f.ex. Prima::InputLine and Prima::Edit. Helper routines that translate clusters, glyphs, and characters into each other are found in Prima::Drawable::Glyphs. ๐Ÿงš

Options recognized:

  • advances BOOLEAN = false โ€” the shaping process may or may not fill an integer array of advances and positions for each glyph, depending on the implementation. The advances are needed to represent f.ex. combining graphemes, when TEXT consisting of two characters, A and combining grave accent U+300 should be drawn as a single ร€ cluster but are represented by two glyphs A and `. The grave glyph has its own advance for standalone usage, but in this case, it should be ignored, and that is achieved by filling the advance table where the A advance is the normal glyph advance, whereas the advance of the ` is zero. Also, the position table additionally shifts glyph position by X and Y coordinates, when that is needed (f.ex. it might be positioned differently by the vertical axis on a and A).

Setting these options to true will force it to fill advance and positioning tables. These tables can be manipulated later, and are respected by text_out and get_text_width.

  • language STRING = undef โ€” when set, the shaping process can take into account the language of the text. F.ex. text ae might be shaped as a single glyph รฆ for the Latin language, but never for English.
  • level INTEGER = ts::Full โ€” selects the shaping (i.e. text to glyph conversion) level, how the system should treat the input text, and how deep the shaping should go.

One of the following ts::XXX options:

  • ts::Bytes โ€” treats input text as non-unicode locale-specific codepoints, characters higher than 255 are treated as chr(255). Reordering never happens, font substitution never happens, kerning and ligation never happen; returns glyph indexes in a 1:1 mapping for each codepoint.
  • ts::None โ€” performs quick null shaping without mapping to the font glyphs, but only running the bidirectional algorithm on the text. On the return, glyphs, as well as eventual advances and positions, are filled with zeros, but indexes are filled with the proper character offsets, effectively making it a visual-to-logical map since the number of glyphs will always be equal to the number of characters in TEXT because ligation never happens here (except when TEXT contains unicode directional characters such as isolates etc - those are removed from the output).

By default, advances and positions are not filled, but if the advances option is set, fills them with zeros.

  • ts::Glyphs โ€” applies the unicode bidi algorithm and maps the result onto font glyphs. Ligation and kerning don't happen here, it's the same as ts::None but with the glyph mapping part.

By default, advances and positions are not filled, but if the advances option is set, fills the advances array with character glyph advances and the positions array with zeros.

May fill the fonts array if the polyfont option is set.

  • ts::Full โ€” applies the unicode bidi algorithm and runs the full shaping on the result. Ligation and kerning may occur. Always fills the advances and positions array; the advances option is ignored.

If the system or the selected font does not support shaping, tries to ligate known Arabic shapes using the fribidi library, if available. Also in this case it does not return the advances and positions by default, but if the advances option is set, fills the advances array with character glyph advances and the positions array with zeros.

May fill the fonts array if the polyfont option is set.

  • pitch INTEGER โ€” when the polyfont is set (default) and thus font substitution is desired, filters only fonts that match pitch, either fp::Variable or fp::Fixed. By default will be set to fp::Fixed if the current font is monospaced, but to fp::Default matching all fonts, otherwise.
  • polyfont BOOLEAN = true โ€” if set, checks if the currently selected font supports all the required unicode points, and if not, selects substitutions from a pre-populated list, taking into account the font pitch (see pitch above). In cases where the current font does not have enough glyphs to shape all the requested unicode points, font substitution is performed, and the result contains an extra array fonts (see fonts in Prima::Drawable::Glyphs). When the current font has all the needed glyphs, the fonts array is not created.

The font list access is available through font_mapper.

Valid only with shaping levels ts::Glyphs and ts::Full.

  • reorder BOOLEAN = true โ€” when set, the unicode bidi algorithm is used to reorder codepoints, and additionally, RTL codepoints may be reversed (depending on the direction context).

When unset, no such reordering occurs, to emulate as much as possible a behavior that each text grapheme is being mapped to a glyph cluster exactly as it occurs in the input text, from left to right. Note that bidi reordering still may occur internally, since system shapers may reverse the placement of RTL characters, so the Prima reordering is needed to cancel this. In theory the caller shouldn't see the difference as these should cancel each other, but if Prima miscalculates the expected way the system shaper does the bidi processing, it might.

A similar effect can be reached by prepending the text with U+202D (LEFT-TO-RIGHT OVERRIDE).

  • replace_tabs INTEGER = -1 โ€” if set to 0 or more, replaces each tab character with the space character and sets their widths to the width of the latter multiplied by the given number. Since it needs the advances table to operate, automatically sets the advances option. If the string passed indeed contains tab characters, also turns off the skip_if_simple option.

Note: if using the result later in text_wrap, set the tabIndent parameters there to 1 to avoid double multiplication of the tab character width. ๐Ÿซถ

okay so two shaping flags before we move on, bestie:

  • rtl BOOLEAN โ€” if set to 1, the default text direction is assumed as RTL, and as LTR if set to 0. If unset, the text direction is taken from textDirection in Prima::Application. โœจ
  • skip_if_simple BOOLEAN = false โ€” when set, checks whether the shaping result is identical to the input, in the sense that a call to text_out(TEXT) and a call to text_shape_out(TEXT) produce identical results. The majority of English text will fall into that category, and when that indeed happens, returns an integer value of 0 instead of a glyph object. ๐Ÿ’…

See also: text_shape_out, get_text_shape_width, text_wrap_shape.

  • text_shape_out TEXT, X, Y[, RTL] โ€” runs shaping on TEXT character string with the RTL flag (or $::application->textDirection). Draws the resulting glyph string at (X,Y).

Returns success flag; if failed, $@ contains the error.

Context used: color, backColor, font, rop, textOpaque, textOutBaseline


๐Ÿ› ๏ธ Methods

  • begin_paint โ€” enters the enabled (active paint) state and returns the success flag; if failed, $@ contains the error. Once the object is in the enabled state, painting and drawing methods can write on the canvas.

See also: end_paint, begin_paint_info, Graphic context and canvas

  • begin_paint_info โ€” enters the information state and returns the success flag; if failed, $@ contains the error. The object information state is the same as the enabled state (see begin_paint), except painting and drawing methods do not change the object canvas.

See also: end_paint_info, begin_paint, Graphic context and canvas

  • can_draw_alpha โ€” returns whether using alpha bits operation on the drawable will have any effect or not. Note that the drawable may not necessarily have an alpha channel, for example, a normal RGB image is capable of being painted on with alpha while not having any alpha on its own. On Unix, all non-1-bit drawables return true if Prima was compiled with XRender support and if that extension is present on the X server. On windows, all non-1-bit drawables return true unconditionally.

See also: has_alpha_layer

  • end_paint โ€” exits the enabled state and returns the object to a disabled state.

See also: begin_paint, Graphic context and canvas

  • end_paint_info โ€” exits the information state and returns the object to a disabled state.

See also: begin_paint_info, Graphic context and canvas

  • font_match \%SOURCE, \%DEST, PICK = 1 โ€” performs merging of two font hashes, SOURCE and DEST. Returns the merge result. If PICK is true, matches the result with a system font repository.

Called implicitly by ::font on set-call, allowing the following example to work:

$d-> font-> set( size => 10);
$d-> font-> set( style => fs::Bold);

In the example, the hash 'style => fs::Bold' does not overwrite the previous font context ('size => 10') but gets added to it (by font_match()), providing the resulting font with both font properties set.

  • fonts <FAMILY = "", ENCODING = ""> โ€” member of Prima::Application and Prima::Printer, does not present in Prima::Drawable.

Returns an array of font metric hashes for a given font FAMILY and ENCODING. Every hash has a full set of elements described in Fonts.

If called without parameters, returns an array of the same hashes where each hash represents a member of the font family from every system font set. In this special case, each font hash contains an additional encodings entry, which points to an array of encodings available for the font.

If called with FAMILY parameter set but no ENCODING is set, enumerates all combinations of fonts with all available encodings.

If called with FAMILY set to an empty string, but ENCODING specified, returns only fonts that can be displayed with the encoding.

Example:

print sort map {"$_->{name}\n"} @{$::application-> fonts};
  • get_bpp โ€” returns device color depth. 1 is for black-and-white monochrome, 24 for true color, etc.
  • get_effective_rop ROP โ€” converts a given ROP depending on the drawable type. The majority of cases only convert rop::Default to rop::CopyPut, however, layered device bitmaps and icons with 8-bit alpha masks return rop::Blend instead.
  • get_font_abc FIRST_CHAR = -1, LAST_CHAR = -1, UNICODE = 0 โ€” returns ABC font metrics for the given range, starting at FIRST_CHAR and ending with LAST_CHAR. If these two parameters are both -1, the default range (0 and 255) is assumed. The UNICODE boolean flag is responsible for the representation of characters in the 127-255 range. If 0, the default, encoding-dependent characters are assumed. If 1, the U007F-U00FF glyphs from the Latin-1 set are used.

The result is an integer array reference, where every character glyph is referred to by three integers, each triplet containing A, B and C values.

For a detailed explanation of ABC meaning, see Font ABC metrics;

Context used: font

  • get_font_def FIRST_CHAR = -1, LAST_CHAR = -1, UNICODE = 0 โ€” same as get_font_abc but for the vertical metrics. Is expensive on bitmap fonts because in order to find out the correct values Prima has to render glyphs on bitmaps and scan for black and white pixels.

Vector fonts are not subject to this, and the call is as effective as get_font_abc.

  • get_font_languages โ€” returns an array of ISO 639 strings that can be displayed using glyphs available in the currently selected font.
  • get_font_ranges โ€” returns an array of integer pairs denoting unicode indices of glyphs covered by the currently selected font. Each pair is the first and the last index of a contiguous range.

Context used: font

  • get_nearest_color COLOR โ€” returns the nearest possible solid color in the representation of the graphic device. Always returns the same color if the device bit depth is equal to or greater than 24.
  • get_paint_state โ€” returns the paint state value as one of the ps:: constants โ€” ps::Disabled if the object is in the disabled state, ps::Enabled for the enabled state, ps::Information for the information state.

The ps::Disabled constant is equal to 0 so this allows for simple boolean testing whether one can get/set graphical properties on the object.

See Graphic context and canvas for more.

  • get_physical_palette โ€” returns an array of (R,G,B) integer triplets where each color entry is in the 0 - 255 range.

The physical palette array is non-empty only on paletted graphic devices, the true color devices always return an empty array.

The physical palette reflects the solid colors currently available to all programs in the system. The information is volatile if the system palette can change colors, since any other application may request to change the system colors at any moment.

  • get_text_shape_width TEXT, [ FLAGS ] โ€” runs shaping on TEXT character string with the text direction either taken from the FLAGS & to::RTL value or from the $::application->textDirection property. Returns the width of the shaping result as if it would be drawn using the currently selected font.

If FLAGS & to::AddOverhangs is set, the first character's absolute A value and the last character's absolute C value are added to the string if they are negative.

  • get_text_width TEXT, ADD_OVERHANG = 0 โ€” returns the TEXT string width if it would be drawn using the currently selected font. TEXT is either a character string, or a Prima::Drawable::Glyphs object returned from text_shape, or a Prima::Drawable::Glyphs-> glyphs glyph string.

If ADD_OVERHANG is 1, the first character's absolute A value and the last character's absolute C value are added to the string if they are negative.

See more on ABC values at Font ABC metrics.

Context used: font

  • get_text_box TEXT โ€” returns the TEXT string extensions if it would be drawn using the currently selected font. TEXT is either a character string or a Prima::Drawable::Glyphs object returned from the text_shape method, or Prima::Drawable::Glyphs-> glyphs glyph string.

The result is an anonymous array of 5 points (5 integer pairs in (X,Y) format). These 5 points are pixel offsets for the following string extents, given the string is plotted at (0,0):

  1. start of string at the ascent line (top left)
  2. start of string at the descent line (bottom left)
  3. end of string at the ascent line (top right)
  4. end of string at the descent line (bottom right)
  5. concatenation point

The concatenation point coordinates (XC,YC) are the values passed to the consequent text_out() call so that the conjoint string would plot as if it was a part of the TEXT. Depending on the value of the textOutBaseline property, the concatenation point is located either on the baseline or on the descent line.

Context used: font, textOutBaseline

                 1      3         3         4
                    **               ****
                      *               *  *
                    ***               ***
                   *  *               *
                    ****               **
                 2       4         1        2
  • graphic_context %GC, $CALLBACK โ€” a shortcut method that saves the graphic context, applies changes in %GC, calls $CALLBACK, and finally restores the context. For example:
$self->graphic_context( fillPattern => fp::Solid, sub { $self-> bar(..) } );
  • graphic_context_pop โ€” restores the graphic context properties from the stack.
  • graphic_context_push โ€” saves the graphic context properties on the stack.
  • has_alpha_layer โ€” returns true if the drawable has an alpha channel. If the drawable is treated as a source, it means its alpha content will be respected when drawing on another surface. If the drawable is treated as a destination, it means that its alpha content will be updated if drawing on it uses alpha bits.

See also: can_draw_alpha.

โœจ render_glyph INDEX, %OPTIONS โœจ

Okay so this one hands you back a whole glyph as an outline ๐Ÿฆ‹ โ€” and the outline is an integer array, laid out as a little set of plotting commands. Each command is a ggo:: constant, then an integer that says how many points came back, then the 2D point coordinates in 1/64 pixels. Literally a whole glyph in a trench coat.

The options it knows about:

  • glyph BOOL โ€” if you set this, INDEX gets treated as the glyph index instead of the character index. Default is false, so like, character index by default, bestie ๐Ÿ’…
  • hints BOOL โ€” turns hinting on when set. Default is true (she's hinting by default, iconic).
  • unicode BOOL โ€” if set, INDEX is a utf8 character index, otherwise it's a locale-specific index. Default false. ๐Ÿ™‚

And the ggo:: commands are, in all their glory:

        ggo::Move  - move point
        ggo::Line  - plot line
        ggo::Conic - plot 2-degree spline
        ggo::Cubic - plot 3-degree spline

๐ŸŽ€ render_pattern IMAGE|ICON|ARRAY|INDEX, %OPTIONS ๐ŸŽ€

So this takes a fill pattern โ€” and a fill pattern here can be one of the fp::XXX constants, an array of 8 bytes, or an image (or icon). Same syntax as fillPattern, no cap ๐Ÿซถ.

It uses %OPTIONS to generate a brand-new rectangular pattern that you can then use in the fillPattern property. Why, you ask? Because Prima doesn't give you an individual property that manages specifically the matrix of a fill pattern โ€” so this method is the way you implement that functionality. It's giving workaround but make it fashion ๐Ÿ’…

It also respects the preserveType property of the image, and if that's set, it changes the resulting pattern image type back to the original type. And when fillPattern is given by an ARRAY or an INDEX, it always generates an im::BW image, so it can be used both in rop2 transparent and opaque modes, exactly like the original pattern. Slay โœจ

Options:

  • color COLOR, alpha 0-255 โ€” if margin is used, this pre-fills the target image with this color. The alpha is used to pre-fill the target image's mask with this value, if the image is an icon.
  • margin XY | [ X, Y ] โ€” sets the margins in X and Y pixels before applying the transformation.
  • matrix MATRIX โ€” a 2D matrix to transform IMAGE.

๐Ÿ”ฅ render_polyline \@POLYLINE, %OPTIONS ๐Ÿ”ฅ

This one does calculations on the POLYLINE, which is defined by OPTIONS. The following options are recognized โ€” buckle up, there's a few ๐Ÿ“:

  • aafill BOOLEAN โ€” if set, renders an 8-bit grayscale image with an antialiased filled polygon. The polygon gets automatically adjusted so its lower and left boundaries sit on the resulting image's lower and left boundaries. Also the image size corresponds to the polygon size. The filling mode can be specified with the mode option, or the current fillMode will be used. Note that the option only accepts the fm::Winding and fm::Alternate constants, and ignores fm::Overlay. Returns three scalars: the first two are the X and Y polygon offsets, and the first is the image itself. (Yes, that's what it says, I'm just the messenger ๐Ÿ˜ญ)
  • box BOOLEAN โ€” if set, instead of polyline vertices, it calculates the box extents of the polyline (either original or after the matrix transform, depending on whether the matrix option was supplied or not), and returns 4 numerics for left, bottom, width, and height of the box enclosure.
  • integer BOOLEAN โ€” by default the result comes back as a set of floating point numerics, but if you need integer results, they get transformed to integers using the int = float + ((float < 0) ? -0.5 : 0.5) formula. Math queen ๐Ÿ’œ
  • matrix A,B,C,D,U,V โ€” if supplied, it performs a matrix transformation on each polyline vertex:
        X' = AX + CY + U
        Y' = BX + DY + V

and returns the new polyline.

  • mode fm::Windings | fm::Alternate โ€” see aafill above.
  • path BOOLEAN โ€” if set, treats the polyline as a path that will get lineEnd, lineJoin, linePattern, and miterLimit properties applied (either from the object or from %OPTIONS), and returns a set of commands that represent the final shape. The commands are: arc (6 arguments, same as the arc primitive), line with 1 argument, a polyline array (respects the integer option), and open with no arguments. See widen in Prima::Drawable::Path for usage. See also line_join_hints below.
  • line_join_hints ARRAY OF INTEGERS โ€” only when the path option is present. It's a specially formatted array of indexes that hint where inside the polyline are the boundaries between the points that need to override lineJoin and force it to be lj::Miter. See widen in Prima::Drawable::Path for usage.

๐ŸŒˆ render_spline \@VERTICES, %OPTIONS ๐ŸŒˆ

Renders a B-spline curve from a set of VERTICES to a polyline, using the given options. It's used internally by spline and fill_spline, and it's provided for the cases when those two just aren't enough. For the options, go read the description in spline โ€” she already explained it there, iykyk ๐Ÿ’–


๐Ÿงš reset_matrix ๐Ÿงš

Sets the CTM to identity. That's it. That's the whole method. Short and iconic, we love a concise queen ๐Ÿ‘‘


โญ text_wrap TEXT, WIDTH, OPTIONS, [TAB_INDENT = 8, FROM = 0, LENGTH = -1, GLYPHS] โญ

Okay this is the big one, bestie โ€” get comfy ๐ŸŒธ

It breaks the TEXT string into chunks that have to fit into a box that's WIDTH pixels wide (for WIDTH >= 0). TEXT is either a character string, or a Prima::Drawable::Glyphs object returned from text_shape, or a Prima::Drawable::Glyphs->glyphs string of glyphs. In that last case, some of the wrapping options are not applicable โ€” sorry babe ๐Ÿ™ˆ. It's also possible to send both the text as TEXT and its shaped representation as GLYPHS.

The breaking algorithm and its result are managed by the OPTIONS integer value, which is a combination of the following tw:: constants:

  • tw::CalcMnemonic โ€” uses 'hotkey' semantics, where a character preceded by the tilde character (~) has a special meaning; f ex it gets underlined when used in menus. If this bit is set, the first tilde character used as an escape is not calculated, and never appears in the result apart from the escaped character. Not applicable in glyph wrapping.
  • tw::CollapseTilde โ€” in addition to tw::CalcMnemonic, removes the tilde character from the resulting chunks. Not applicable in glyph wrapping.
  • tw::CalcTabs โ€” if set, treats tab ('\t') characters as TAB_INDENT times space characters. Not applicable in glyph wrapping.
  • tw::ExpandTabs โ€” if set, expands tab ('\t') characters as TAB_INDENT times space characters. Not applicable in glyph wrapping.
  • tw::BreakSingle โ€” defines the method behavior when the text cannot fit in WIDTH. Doesn't affect anything else otherwise. If set, the method returns an empty array. If unset, returns text broken by the minimum number of characters per chunk โ€” and in that case, the width of the resulting text blocks will exceed the WIDTH. So like, heads up ๐Ÿ’€
  • tw::NewLineBreak โ€” forces the creation of a new chunk after the newline character ('\n'). If UTF8 text is passed, the unicode line break characters 0x2028 and 0x2029 produce the same effect as the newline character. Not applicable in glyph wrapping.
  • tw::SpaceBreak โ€” forces the creation of a new chunk after the space character (' ') or the tab character. Not applicable in glyph wrapping.
  • tw::ReturnChunks โ€” defines the result of the text_wrap() method. If set, the array consists of integer pairs, where each is a text offset within TEXT and its length. If unset, the resulting array consists of text chunks.
  • tw::ReturnGlyphs โ€” if GLYPHS is set (only together with TEXT), this option becomes available to get the resulting chunks as sub-sets of GLYPHS.
  • tw::ReturnLines โ€” equals to 0, and is a mnemonic to an unset tw::ReturnChunks. When wrapping glyphs, it has the same effect as the tw::ReturnGlyphs flag.
  • tw::WordBreak โ€” if unset, the TEXT breaks as soon as the chunk width exceeds WIDTH. If set, it tries to keep words in TEXT so they don't appear in two chunks, e.g. it breaks TEXT by words, not by characters. If Prima is compiled with the libthai library and Thai text is detected, Prima uses the library to detect the word boundaries, because the Thai language does not use spaces between words. This behavior can be disabled by running Prima with --no-libthai. Not applicable in glyph wrapping.
  • tw::ReturnFirstLineLength โ€” if set, text_wrap proceeds until the first line is wrapped, either by width or (if specified) by break characters. Returns the length of the resulting line. Used for efficiency as the inverted get_text_width function.

If OPTIONS has the tw::CalcMnemonic or tw::CollapseTilde bits set, then the last scalar of the array is a special hash reference ๐ŸŽ€. The hash contains extra information regarding the 'hotkey' position of the underline โ€” it's assumed that the tilde character '~' prefixes the underlined character. The hash contains the following keys:

  • tildeLine โ€” chunk index that contains the escaped character. Set to undef if no tilde escape was found; the rest of the information in the hash is not relevant in this case.
  • tildeStart โ€” the horizontal offset of the beginning of the line that underlines the escaped character.
  • tildeEnd โ€” the horizontal offset of the end of the line that underlines the escaped character.
  • tildeChar โ€” the escaped character.

Context used: font.


๐Ÿ’œ text_wrap_shape TEXT, WIDTH = -1, %OPTIONS ๐Ÿ’œ

Runs text_shape over the results from a text_wrap call, with TEXT, WIDTH, $OPTIONS{options}, and $OPTIONS{tabs}. The other %OPTIONS are used in the text_shape call. Where text_wrap returns text substrings or positions, this returns glyphs objects or their positions instead. Glow-up fr fr โœจ

When called with tw::CalcMnemonic options, it recalculates the tilde position so it adapts to the glyph positions returned.

And if $OPTIONS{kashida} is set, it performs kashida justification on the last wrapped line, using the optional $OPTIONS{min_kashida} value (see arabic_justify in Prima::Drawable::Glyphs). Obsessed ๐Ÿซถ

If $OPTIONS{letter} or $OPTIONS{word} is set, it performs the interspace justification on all but the last wrapped line โ€” like, every line gets the stretch treatment except the final one, no cap ๐Ÿซถ


๐Ÿ’– AUTHOR ๐Ÿ’–

Dmitry Karasik, <dmitry@karasik.eu.org>. That's the icon who made this whole thing, show some respect โœจ


๐ŸŒˆ SEE ALSO ๐ŸŒˆ

  • Prima โ€” the mothership, start here bestie
  • Prima::Object โ€” where all the object behavior lives
  • Prima::Image โ€” the image side of things
  • Prima::Region โ€” regions, the shapes-with-attitude squad
  • Prima::Drawable::Path โ€” paths, for when you're feeling fancy
  • Prima::Drawable::Glyphs โ€” glyphs, the literal letters themselves

and that's the whole page, bestie ๐ŸŽ€ this one comes to you from perl v5.42.0, dated 2024-08-20 โ€” go forth and draw pretty things, you absolute main character ๐Ÿ’…๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from