Picture

Picture is an imitation of a function whose input is an implicit parameter (which in Dotty would just be a context function). It has three type parameters. They are, in order:

  • The type Alg of the algebras that the picture needs to draw. This is an input to the Picture and hence it is contravariant.
  • The type of the effect F that the picture will create.
  • The type A of the result the picture will produce when it is drawn. This is usually Unit, as we normally draw pictures just for their effect, but it could be something else.

Thus in effect a Picture is a function with type Alg[F] => F[A].

Pictures Are Values

Algebras do not work directly with Picture. Instead they work with the F[A] type that is the output of a Picture. However, all the syntax that makes the algebras easier to use, and which we have used in our previous examples, create and consume Picture. The reason for this is that working with raw algebras requires we wrap everything in methods. Methods are not values; we cannot pass a method to a method nor return a method from a method. Functions are values, but in Scala 2 their input parameters cannot also be implicit parameters. Picture is like a function with an implicit input parameter. It also provides a bit more structure than using functions directly. When we see a Picture we know exactly what we’re dealing with.

Drawing Pictures

We can draw a picture to the screen using the draw method. This is syntax that depends on a having a `Renderer` effect in scope. There are other methods provided by the Renderer effect, as explained in its documentation.

Writing and Converting Pictures

In addition to drawing a picture to the screen we can write it to a file or convert it to some other type. The write method saves a picture to a file. When we call write we must pass two parameters: a normal parameter that is the file name to use and a type parameter that gives the format of the file. In the example below we save a file as a PNG.

import doodle.core._
import doodle.syntax._
import doodle.java2d._
import doodle.effect.Writer._

val picture = circle[Algebra, Drawing](100)

picture.write[Png]("circle.png")

The write method is syntax that comes from the `Writer` effect. There are other methods that allow, for example, specifying a Frame to use when saving the file.

We can convert a Picture to a Base64 value using the base64 method. As with write, this method is syntax for the `Base64` effect. The parameters are similar to write: we must specify a format to encode the picture in but we don’t specify a filename. Instead we get back the result of evaluating the Picture (the A in F[A] which is usually ()) and a Base64 value.

import doodle.core._
import doodle.syntax._
import doodle.java2d._
import doodle.effect.Writer._

val picture = circle[Algebra, Drawing](100)

val (result, b64) = picture.base64[Png]()

Converting Other Types to a Picture

The ToPicture algebra provides a single method that converts some type (fixed for each instance of ToPicture) to a F[Unit]. The corresponding syntax wraps the result in a Picture, as is standard for syntax, and therefore gives a way to convert the input type to a Picture.

The available instances vary depending on the backend. For the Java2D backend, Base64 and BufferedImage values can be converted to Picture. For SVG only Base64 is currently supported.

Here is quick example of use. First we create a Base64 value from a Picture.

import doodle.core._
import doodle.syntax._
import doodle.java2d._
import doodle.effect.Writer._
// The value we throw away is the result of evaluating the `Picture`, which is `Unit`.
val (_, base64) = circle[Algebra, Drawing](100).base64[Png]()
// base64: Base64[Png] = Base64(
//   "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"
// )

We can convert it right back to a Picture using the toPicture method.

val picture = base64.toPicture
// picture: Picture[doodle.algebra.Algebra[x], Drawing[A], Unit] = doodle.algebra.Picture$$anon$1@12664d00

Type Class Instances for Picture

There are a few type class instances defined for Picture.

Picture[Alg,F,?] has a Monoid instance if:

  • the algebra has Layout and Shape;
  • the effect type F has a Functor; and
  • and the result type has a Monoid.

In this case the combine is on, with identity empty.

Picture[Alg,F,?] has a Monad instance if F does.

The source code for this page can be found here.