# Graphic commands

DB48X features a number of graphic commands. While displaying graphics, the
stack and headers will no longer be updated.

## Coordinates

DB48X recognizes the following types of coordinates

* *Pixel coordinates* are specified using based numbers such as `#0`, and
  correspond to exact pixels on the screen. Pixels are counted starting
  from the top-left corner of the screen, with the horizontal coordinate going
  from `10#0` to `10#399`, and the vertical coordinate going from `10#0` to
  `10#239`.

* *User unit coordinates* are scaled according to the content of the `PPAR` or
  `PlotParameters` reserved variables.

* *Text coordinates* are given on a square grid with a size corresponding to the
  height of a text line in the selected font. They can be fractional.

Coordinates can be given using one of the following object types:

* A complex number, where the real part represents the horizontal coordinate and
  the imaginary part represents the vertical coordinate.

* A 2-element list or vector containing the horizontal and vertical coordinates.

* A 1-element list of vector containing one of the above.

For some operations, the list or vector can contain additional parameters beyond
the coordinates. The selection of unit or pixel coordinates is done on a per
coordinate basis. For example, `{ 0 0 }` will be the origin in user coordinates,
in the center of the screen if no `PPAR` or `PlotParameters` variable is
present.

Note that unlike on the HP48, a complex value in DB48X can
contain a based number.


## ClearLCD

Clear the LCD display, and block updates of the header or menu areas.

## BlankGraphic

Create a blank graphic object with the specified dimensions.
The graphic is optimized for the device running the program.
On color RPL devices, it will produce a color pixmap.
On black-and-white RPL devices it will produce a color pixmap.

To create a blank graphic 20 pixels wide and 30 pixels high, use:

```rpl
20 30 BlankGraphic
```


## BlankGROB

Create a blank HP48-compatible graphic object (GROB) with the specified dimensions.

To create a blank HP48-compatible GROB 20 pixels wide and 30 pixels high, use:

```rpl
20 30 BlankGROB
@ Expecting Graphic 20 x 30
```

## BlankBitmap

Create a blank packed bitmap graphic object with the specified dimensions.
This object is always a black-and-white pixmap even on color RPL devices.

To create a blank HP48-compatible GROB 20 pixels wide and 30 pixels high, use:

```rpl
20 30 BlankBitmap
@ Expecting Bitmap 20 x 30
```

## BlankPixmap

Create a color pixmap graphic object with the specified dimensions.
THis command only exists on color RPL devices.

To create a color pixmap that is pixels wide and 30 pixels high, use:

```rpl
20 30 BlankPixmap
```

## PixTest

Test the pixel at the specified coordinates and return its gray level.

```rpl
{ 0 0 } PixTest
@ Expecting 1
```

## PixColor

Test the pixel at the specified coordinates and return its color as a three
component values for the red, green and blue levels, each represented as a
decimal value between 0 and 1.

This commands works both in Color RPL and regular RPL, but only Color RPL may
return distinct values for the red, green and blue components.

```rpl
{ 0 0 } PixColor →V3
@ Expecting [ 1 1 1 ]
```

## Gray

Create a gray pattern for graphics operations. The resulting pattern can be
given as input to commands such as `Foreground` or `Background`.

This operation creates a bitmap pattern on black-and-white devices,
and a pixmap with the gray level on color devices.

```rpl
0 LINEWIDTH
0 1 FOR G
	G GRAY FOREGROUND 0 0 R→C 5 1 G - * CIRCLE
0.1 STEP
{ Foreground LineWidth } PURGE
@ Image gray-circles
```

## RGB

Create an RGB (red-green-blue) color pattern for graphics operations. The
resulting pattern can be given as input to commands such as `Foreground` or
`Background`.

This operation creates a bitmap pattern on black-and-white devices,
and a pixmap with the given color on color devices.

```rpl
0 LINEWIDTH
0 1 FOR R
	0 1 FOR G
		0 1 FOR B
			R G B RGB FOREGROUND R 14 * 7 - G 10 * 5 - R→C 1 B - 0.5 * CIRCLE
		0.1 STEP
   0.1 STEP
0.1 STEP
{ Foreground LineWidth } PURGE
@ Image color-circles
```


## HSV

Create an HSV (hue-saturation-value) color pattern for graphics operations. The
resulting pattern can be given as input to commands such as `Foreground` or
`Background`.

This operation creates a bitmap pattern on black-and-white devices,
and a pixmap with the given color on color devices.

```rpl
0 LINEWIDTH
0 1 FOR H
	0 1 FOR S
		0 1 FOR V
			H S V HSV FOREGROUND H 14 * 7 - S 10 * 5 - R→C 1 V - 0.5 * CIRCLE
		0.1 STEP
   0.1 STEP
0.1 STEP
{ Foreground LineWidth } PURGE
@ Image hsv-circles
```

## Color

Create color pattern for graphics operations. The resulting pattern can be given
as input to commands such as `Foreground` or `Background`.

The operation takes an object as input and produces a color pattern that depends on the type of input, using the same convention as for `TruthPlot`:

* Truth value `True` or `False` for foreground and background color
* Real values between `0.0` and `1.0` for grayscales
* Complex values representing saturated HSV (colorwheel) colors
* 3-element vectors representing HSV (colorwheel) colors
* 3-element lists representing RGB colors
* Names or symbols representing common color names

This operation creates a bitmap pattern on black-and-white devices,
and a pixmap with the given color on color devices.

```rpl
0 LINEWIDTH
"NavyBlue" Color Foreground 0+0ⅈ 3 Circle
{ 1 1 1 } Color Foreground 0+0ⅈ 2 Circle
[ 0 1 1 ] Color Foreground 0+0ⅈ 1 Circle
{ Foreground LineWidth } PURGE
@ Image named-circles
```


## FromLCD

Return the content of the screen as a graphic object that is put on the stack.

For example, to extract the area of the screen that contains the battery
indicator and voltage, use the following code:

```rpl
LCD→ { #315₁₀ #0₁₀ } { #400₁₀ #22₁₀ } Extract
@ Image extracted-battery
```

## ToLCD

Display a graphic object on the screen. If the graphic object is smaller than
the screen, it is centered on the screen, surrounded by gray. Note that this is different from HP calculators where it is shown in the top-left.

For example, to draw an expression in the center of the screen, use:

```rpl
'X+(1/sqrt(X-1))' 3 →GROB →LCD
@ Image small-equation
```


## DrawText

Draw the text or object in level 2 at the position indicated by level 1. A text
is drawn without the surrounding quotation marks.

If the position in level 1 is an integer, fraction or real number, it is
interpreted as a line number starting at 1 for the top of the screen. For
example, `"Hello" 1 disp` will draw `Hello` at the top of the screen.
If the position is a based number, it is a row number in pixels. For example,
`"Hello" #120d disp` will show the text in the middle of the screen.

If the position in level 1 is a complex number or a list, it is interpreted as
specifying both the horizontal or vertical coordinates, in either pixel or unit
coordinates. For example `"Hello" { 0 0 } disp` will draw `Hello` starting in
the center of the screen.

Text is drawn using the stack font by default, using the
[foreground](#foreground) and [background](#background) patterns.

If level 1 contains a list with more than 2 elements, additional elements
provide:

* A *font number* for the text

* An *erase* flag (default true) which indicates whether the background for the
  text should be drawn or not.

* An *invert* flag (default false) which, if set, will swap the foreground and
  background patterns.

* A *horizontal align* value, where -1 means align left, 1 means align right,
  and 0 means center the text. Note that fractional values or values below -1 or
  above 1 are allowed for special effects.

* A *vertical align* value, where -1 means align top, 1 means align bottom, and
  0 means center the text vertically. Note that fractional values or values
  below -1 or above 1 are allowed for special effects.

For example, the following code will draw `Hello` in the
top-left corner (`#0 #0`) with the largest (editor) font (font identifier `3`),
erasing the background (the first `true`), in reverse colors (the second
`true`), and then draws `World` in the bottom right corner.

```rpl
"Hello" { #0 #0 3 true true } DrawText
"World" { 10#400 10#240 3 true true -1 -1 } DrawText
@ Image hello-world
```

## DrawStyledText

Draw the text or object in level 3 at the position indicated by level 2, using
the font specified in level 1. This behaves like [DrawText](#drawtext), except
for the additional parameter specifying the font size.

This command is compatible with the HP50G usage, where the position is specified
by a list containing two decimal integer values. A font size of 1 displays with
a small font, a font size of 2 displays with a regular font.

In addition to this HP50G-compatible usage, `DispXY` will also accept:

* A smaller font size, 0, for the help size, and other font sizes above 2, which
  are compatible with the values given to [StackFont](#stackfont).

* The position can accept the same values as [DrawText](#drawtext), including a
  single integer value indicating a line number, a fractional line position, or
  coordinates scaled according to [PlotParameters](#plotparameters).


## Show

Display the first level of the stack using the entire screen, with a possible
scroll using the 4, 8, 6 and 2 keys if the object is larger than the screen.
This makes it possible to comfortably examine very large objects, like `300!`, a
large program or a complicated equation. Arrow keys can also be used for
horizontal or vertical scrolling.

The maximum size of the graphic object is defined by the
[MaximumShowWidth](#maximumshowwidth) and
[MaximumShowHeight](#maximumshowheight) settings.

```rpl
1.0 3 / Show
@ Image many-decimals
```

## DrawLine

Draw a line between two points specified by level 1 and level 2 of the stack.

The width of the line is specified by [LineWidth](#linewidth). The line is drawn
using the [foreground](#foreground) pattern.


## Pict

`Pict` is the name given to the graphics shown on the calculator's screen.
It can only be used as an argument to `Store`, `Recall` and graphical
operations such as `GAnd`.

[Not fully implemented yet: `Store` and `Recall` do not work]


# Bitmap operations

## ToGrob

Creates a graphics object from a specified object on the stack.

The first level of the stack specifies the character size used while
rendering the object, where value `0` indicates the `StackFont` value.

If the second level of the stack is a text, then the quotes that appear
the text is displayed on the stack will not be included in the generated
graphic object. This is similar to the behaviour of `Disp`. The rendering
of objects respects the settings used to render on the stack, e.g.
`FIX` mode or `VerticalVectors`.

The object to draw must fit in a bit map at most `MaxW`-pixels wide and
`MaxH`-pixels high.


```rpl
@ Show font sizes
0 7 for fontID
  "Font " fontID + fontID →Grob
next
@ Image fontsizes
```

## ToHPGrob

Turn an object into a graphic object in HP compatible format (GROB).
When the input is a graphic object, its graphic format is adjusted.
If the input is a color graphic, it is dithered into black and white.

Otherwise, the object is turned into a graphic object, where the font size and
color settings are taken from the `ResultFont`, `Foreground` and `Background`
settings. If the object is text, then the quotes are now shown in the resulting
graphic object.

```rpl
"Hello" →HPGrob
```

## ToBitmap

Turn an object into a graphic object in DB48x `PackedBitmaps` format.
When the input is a graphic object, its graphic format is adjusted.
If the input is a color graphic, it is dithered into black and white.

Otherwise, the object is turned into a graphic object, where the font size and
color settings are taken from the `ResultFont`, `Foreground` and `Background`
settings. If the object is text, then the quotes are now shown in the resulting
graphic object.

```rpl
'sqrt(2*x)/y' →Bitmap
@ Image sqrt
```

## ToPixmap

(This command is only available for color RPL)

Turn an object into a color graphic object in DB50x format.
When the input is a graphic object, its graphic format is adjusted.

Otherwise, the object is turned into a graphic object, where the font size and
color settings are taken from the `ResultFont`, `Foreground` and `Background`
settings. If the object is text, then the quotes are now shown in the resulting
graphic object.

```rpl
'sqrt(2*x)/y' →Pixmap
@ Image sqrt
```


## GXor

Superimposes a source graphic object onto a destination graphic object, which
can be `Pict` to represent what is presently shown on screen. The upper left
corner pixel of the positioned at the specified coordinate in the destination.

`GXor` is used for creating cursors, for example, to make the cursor image
appear dark on a light background and light on a dark background. Executing
`Gxor` again with the same image restores the original picture.

`GXOR` uses a logical exclusive OR to determine the state of the pixels (on or
off) in the overlapping portion of the argument graphics objects.

If the destination is not `Pict`, the resulting graphic object is returned on
the stack. If the destination is `Pict`, the screen is updated and no result
is returned on the stack.

```rpl
@ Blinking cursor
"Hello" 1 DISP
1 20 start
  Pict { #0 #0 } "█" 3 →Grob GXor 0.5 Wait
next
```


## GOr

Superimposes a source graphic object onto a destination graphic object, which
can be `Pict` to represent what is presently shown on screen. The upper left
corner pixel of the positioned at the specified coordinate in the destination.

`GOr` uses a logical OR to determine the state of the pixels (on or
off) in the overlapping portion of the argument graphics objects.
On DB48X, pixels that are set appear white.

If the destination is not `Pict`, the resulting graphic object is returned on
the stack. If the destination is `Pict`, the screen is updated and no result
is returned on the stack.

```rpl
@ Erasing cursor
"Hello World" 1 DISP
1 50 for i
  Pict i R→B { #0 } + "▶" 3 →Grob GOr 0.05 Wait
next
```

## GAnd

Superimposes a source graphic object onto a destination graphic object, which
can be `Pict` to represent what is presently shown on screen. The upper left
corner pixel of the positioned at the specified coordinate in the destination.

`GAnd` uses a logical AND to determine the state of the pixels (on or
off) in the overlapping portion of the argument graphics objects.
On DB48X, pixels that are set appear white.

If the destination is not `Pict`, the resulting graphic object is returned on
the stack. If the destination is `Pict`, the screen is updated and no result
is returned on the stack.

```rpl
@ Darkening cursor
"Hello World" 1 DISP
1 250 for i
  Pict i R→B { #0 } + "▓" 3 →Grob GAnd 0.05 Wait
12 step
```


## GraphicAppend

Append two graphic objects side by side.
The two graphic objects are vertically centered with respect to one another.

```rpl
@ Juxtapose two font sizes
"ABC" 4 →Grob
"DEF" 2 →Grob
GraphicAppend
@ Image check
```


## GraphicStack

Stack two graphic objects on top of one another.
The two graphic objects are horizontally centered with respect to one another.

```rpl
@ Stack two font sizes
"ABC" 4 →Grob
"DEF" 2 →Grob
GraphicStack
@ Image check
```

## GraphicSubscript

Combine two graphic objects with the second one in subscript position

```rpl
@ Subscript with two font sizes
"ABC" 4 →Grob
"DEF" 2 →Grob
GraphicSubscript
@ Image check
```

## GraphicExponent

Combine two graphic objects with the second one in exponent position

```rpl
@ Exponent with two font sizes
"ABC" 4 →Grob
"DEF" 2 →Grob
GraphicExponent
@ Image check
```

## GraphicRatio

Combine two graphic objects as if they were in a fraction

```rpl
@ Ratio with two font sizes
"ABC" 4 →Grob
"DEF" 2 →Grob
GraphicRatio
@ Image check
```

## GraphicRoot

Generate a square root sign around a graphical object

```rpl
@ Square root sign
"ABC" 4 →Grob
GraphicRoot
@ Image check
```

## GraphicParentheses

Generate parentheses around a graphical object

```rpl
@ Parentheses around graphic
"ABC" 4 →Grob
GraphicParentheses
@ Image check
```

## GraphicNorm

Generate a norm (vertical bars) around a graphical object

```rpl
@ Norm around graphic
"ABC" 4 →Grob
GraphicNorm
@ Image check
```


## GraphicSum

Generate a sum (capital Sigma) sign of the given size

```rpl
@ 128-pixel Sigma sign
128 GraphicSum
@ Image check
```

## GraphicProduct

Generate a product (capital Pi) sign of the given size

```rpl
@ 96-pixel Sigma sign
96 GraphicProduct
@ Image check
```

## GraphicIntegral

Generate an integral sign of the given size

```rpl
@ 45-pixel Sigma sign
45 GraphicIntegral
@ Image check
```
