Skip to content

Commit

Permalink
release v2.13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cormullion committed Jul 6, 2021
1 parent abb1c45 commit 2cf8f65
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 203 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## [v2.13.0] - forthcoming
## [v2.13.0] - 2021-07-06

### Added

Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ makedocs(
"Introduction to Luxor" => "index.md",
"Tutorials" => [
"A first tutorial" => "tutorial/basictutorial.md",
"Design a logo" => "tutorial/design-a-logo.md",
"Quick start" => "tutorial/quickstart.md",
"Simple animations" => "tutorial/simple-animation.md",
],
"Examples" => [
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/src/assets/luxor-docs.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
@font-face {
font-family: JuliaMono-Regular;
src:
url("https://github.com/cormullion/juliamono/raw/master/webfonts/JuliaMono-Regular.woff2");
local('JuliaMono-Regular'),
url("https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/JuliaMono-Regular.woff2");
}

pre, code {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/explanation/imagematrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

While drawing, you can copy the current graphics in a drawing as a matrix of pixels, using the [`image_as_matrix`](@ref) function.

With the `@imagematrix` macro, you can create your drawing with vector graphics in the usual way, but the result is returned as a matrix. This example processes an ampersand in Images.jl.
With the [`@imagematrix`](@ref) macro, you can create your drawing with vector graphics in the usual way, but the result is returned as a matrix. This example processes an ampersand in Images.jl.

```
using Luxor, Colors, Images, ImageFiltering
Expand Down
128 changes: 76 additions & 52 deletions docs/src/explanation/perfectpixels.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@

## Antialiasing

The process of converting smooth graphic shapes to a grid of pixels is automatically performed by Luxor/Cairo when you save the drawing as a PNG file. If you make an SVG or PDF drawing, this process is carried out by the application you use to view or display the file. It's usually better to defer the conversion as long as possible: eventually - unless you're using a pen plotter or laser cutter - your smooth outlines will have to be converted ("rasterized") to a grid of colored pixels.

The smoothing process includes "anti-aliasing". You can - to some extent - adjust the amount of anti-aliasing used when you make drawings in Luxor.
The process of converting smooth graphic shapes to a grid of
pixels is automatically performed by Luxor/Cairo when you
save the drawing as a PNG file. If you make an SVG or PDF
drawing, this process is carried out by the application you
use to view or display the file. It's usually better to
defer the conversion as long as possible: eventually -
unless you're using a pen plotter or laser cutter - your
smooth outlines will have to be converted ("rasterized") to
a grid of colored pixels for their final journey to the
analogue world.

The smoothing process includes "anti-aliasing". You can - to
some extent - adjust the amount of anti-aliasing used when
you make drawings in Luxor.

```@setup draw_matrix
using Luxor, Colors
Expand Down Expand Up @@ -45,19 +56,19 @@ function draw(antialias)
end
```

The [`setantialias`](@ref) function lets you set the antialiasing amount to a constant between 0 and 6. The Cairo documentation describes the different values as follows:
The [`setantialias`](@ref) function lets you set the anti-aliasing amount to a constant between 0 and 6. The Cairo documentation describes the different values as follows:

| Value | Name | Description |
|:----- |:---- |:---- |
|0 |`CAIRO_ANTIALIAS_DEFAULT` |Use the default antialiasing for the subsystem and target device|
|0 |`CAIRO_ANTIALIAS_DEFAULT` |Use the default anti-aliasing for the subsystem and target device|
|1 |`CAIRO_ANTIALIAS_NONE` |Use a bilevel alpha mask|
|2 |`CAIRO_ANTIALIAS_GRAY` |Perform single-color antialiasing (using shades of gray for black text on a white background, for example)|
|3 |`CAIRO_ANTIALIAS_SUBPIXEL` |Perform antialiasing by taking advantage of the order of subpixel elements on devices such as LCD panels|
|4 |`CAIRO_ANTIALIAS_FAST` |Hint that the backend should perform some antialiasing but prefer speed over quality|
|2 |`CAIRO_ANTIALIAS_GRAY` |Perform single-color anti-aliasing (using shades of gray for black text on a white background, for example)|
|3 |`CAIRO_ANTIALIAS_SUBPIXEL` |Perform anti-aliasing by taking advantage of the order of subpixel elements on devices such as LCD panels|
|4 |`CAIRO_ANTIALIAS_FAST` |Hint that the backend should perform some anti-aliasing but prefer speed over quality|
|5 |`CAIRO_ANTIALIAS_GOOD` |The backend should balance quality against performance|
|6 |`CAIRO_ANTIALIAS_BEST` |Hint that the backend should render at the highest quality, sacrificing speed if necessary|

To show the antialiasing in action, the following code draws a red circle:
To show the anti-aliasing in action, the following code draws a red circle:

```
Drawing(20, 20, :image)
Expand All @@ -69,15 +80,15 @@ mat = image_as_matrix()
finish()
```

Enlarging the matrix shows the default value of 0:
This drawing enlarges the matrix. Here's the default anti-aliasing value of 0:

```@example draw_matrix
draw(0) # hide
```

Luxor used 18 colors to render this red circle.
You can see that Luxor used 18 different colors to render this red circle.

Here's the bilevel mask (value 1 or "none"):
Heres the result of the bilevel mask (value 1 or none”) setting:

```@example draw_matrix
draw(1) # hide
Expand All @@ -99,58 +110,71 @@ The anti-aliasing process can vary according to the OS and device you're using.
## Text

The antialiasing described above does not apply to text.
The anti-aliasing described above does not apply to text.

Text rendering is much more platform-dependent than graphics; Windows, MacOS, and Linux all have their own methods for rendering and rasterizing fonts, and currently Cairo.jl doesn't currently provide an interface to any font rendering APIs.

```@setup draw_text
using Luxor, Colors
function make_matrix(;
antialias=0)
d = Drawing(20, 20, :image)
setantialias(antialias)
Consider the following code:

```julia
using Luxor

function make_matrix()
Drawing(40, 40, :image)
background(1, 1, 1, 1)
setantialias(0)
origin()
setcolor("red")
fontsize(20)
setcolor(0, 0, 0, 1)
fontsize(40)
text("a", halign=:center, valign=:middle)
mat = image_as_matrix()
matrix = image_as_matrix()
finish()
return mat
end
function drawmatrix(A;
cellsize = (10, 10))
table = Table(size(A)..., cellsize...)
for i in CartesianIndices(A)
r, c = Tuple(i)
sethue(A[r, c])
box(table, r, c, :fill)
sethue("black")
box(table, r, c, :stroke)
end
return matrix
end

function draw(antialias)
mat = make_matrix(antialias=antialias)
@drawsvg begin
background("black")
drawmatrix(mat, cellsize = 1 .* size(mat))
c = length(unique(color.(mat)))
sethue("white")
fontsize(8)
text("number of colors used: $c", boxbottomcenter(BoundingBox() * 0.9), halign=:center)
end 300 300
function draw()
matrix = make_matrix()
@png begin
background(0, 0, 0, 1)
table = Table(size(matrix)..., (15, 15))
for i in CartesianIndices(matrix)
r, c = Tuple(i)
setcolor(matrix[r, c])
box(table, r, c, :fillstroke)
end
end 400 400 "/tmp/alias-test.png"
end
```

On some platforms you'll see anti-aliased fonts rendered like this:
The output varies depending on the computer, OS, and rendering settings:

```@example draw_text
draw(1) # hide
```
MacOS standard rendering:

![macos alias text](../assets/figures/textrendering-macos-alias-test.png)

Linux Gnome standard anti-aliasing:

![linux gnome alias text](../assets/figures/textrendering-linux-gnome-greyscale-aaa .png)

Linux KDE RGB anti-aliasing:

![linux kde rgb alias text](../assets/figures/textrendering-linux-kde-rgb-subpixel-aa.png)

Windows Cleartype anti-aliasing:

![windows cleartype alias text](../assets/figures/textrendering-windows-cleartype.png)

On Windows systems, text might be displayed using Microsoft’s Cleartype subpixel rendering process, and variously colored pixels are drawn around the edges of text in order to provide a “smoother” appearance.
On Windows systems, and on some Linux desktops, text can be
displayed a subpixel rendering process, so that variously
colored pixels are drawn around the edges of text in an
attempt to provide a “smoother” appearance.

In addition, Windows uses font-hinting, a process in which the outlines of text glyphs are shifted so as to align better on the rectangular grid of pixels.
In addition, Windows and some Linux systems use
font-hinting, a process in which the outlines of text glyphs
are shifted so as to align better on the rectangular grid of
pixels.

If you want text to be aligned precisely on Windows, it might be worth investigating Luxor’s [`textoutlines`](@ref) function, which converts text to vector-based outlines.
If you want text to be aligned precisely, and in the
specified color, it might be worth investigating Luxor’s
[`textoutlines`](@ref) function, which converts text to
vector-based outlines.
10 changes: 5 additions & 5 deletions docs/src/explanation/transforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Graphics are placed on the current workspace according to the *current transform

# Transformation functions

For basic transformations, use `translate(tx, ty)`, `scale(sx, sy)`, and `rotate(a)`.
For basic transformations, use [`translate(tx, ty)`](@ref), [`scale(sx, sy)`](@ref), and [`rotate(a)`](@ref).

`translate(pos)` (or `translate(x, y)`) shifts the current origin to `pos` (or by the specified amounts in x and y). It's relative and cumulative, rather than absolute:
[`translate(pos)`](@ref) (or `translate(x, y)`) shifts the current origin to `pos` (or by the specified amounts in x and y). It's relative and cumulative, rather than absolute:

```@example
using Luxor, Colors, Random # hide
Expand Down Expand Up @@ -117,7 +117,7 @@ julia> getmatrix()
0.0
```

`transform(a)` transforms the current workspace by 'multiplying' the current matrix with matrix `a`. For example, `transform([1, 0, xskew, 1, 50, 0])` skews the current matrix by `xskew` radians and moves it 50 in x and 0 in y.
[`transform(a)`](@ref) transforms the current workspace by 'multiplying' the current matrix with matrix `a`. For example, `transform([1, 0, xskew, 1, 50, 0])` skews the current matrix by `xskew` radians and moves it 50 in x and 0 in y.

```@example
using Luxor # hide
Expand Down Expand Up @@ -149,8 +149,8 @@ nothing # hide

[`getmatrix`](@ref) gets the current matrix, `setmatrix(a)` sets the matrix to array `a`.

Other functions include [`getmatrix`](@ref)
[`setmatrix`](@ref) [`transform`](@ref) [`crossproduct`](@ref) [`blendmatrix`](@ref) [`rotationmatrix`](@ref) [`scalingmatrix`](@ref) [`translationmatrix`](@ref).
Other functions include [`getmatrix`](@ref),
[`setmatrix`](@ref), [`transform`](@ref), [`crossproduct`](@ref), [`blendmatrix`](@ref), [`rotationmatrix`](@ref), [`scalingmatrix`](@ref), and [`translationmatrix`](@ref).

Use the [`getscale`](@ref), [`gettranslation`](@ref), and [`getrotation`](@ref) functions to find the current values of the current matrix. These can also find the values of arbitrary 3x3 matrices.

Expand Down
61 changes: 31 additions & 30 deletions docs/src/howto/animation.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ animate(demo, [

Transitions for animations often use non-constant and non-linear motions, and these are usually provided by *easing* functions. Luxor defines some of the basic easing functions and they're listed in the (unexported) array `Luxor.easingfunctions`. Each scene can have one easing function.


|List of easing functions|
|:--- |
|easingflat|
|lineartween|
|easeinquad|
|easeoutquad|
|easeinoutquad|
|easeincubic|
|easeoutcubic|
|easeinoutcubic|
|easeinquart|
|easeoutquart|
|easeinoutquart|
|easeinquint|
|easeoutquint|
|easeinoutquint|
|easeinsine|
|easeoutsine|
|easeinoutsine|
|easeinexpo|
|easeoutexpo|
|easeinoutexpo|
|easeincirc|
|easeoutcirc|
|easeinoutcirc|
|easeinoutinversequad|
|easeinoutbezier|

Most easing functions have names constructed like this:

```
Expand All @@ -115,13 +144,13 @@ function draweasingfunction(f, pos, w, h)
end
end
Drawing(650, 650, "../assets/figures/easingfunctions.png") # hide
Drawing(800, 650, "../assets/figures/easingfunctions.png") # hide
background("white") # hide
origin() # hide
t = Tiler(650, 650, 5, 5)
margin=5
fontsize(10)
fontface("Menlo")
fontface("JuliaMono-Regular")
for (pos, n) in t
n > length(Luxor.easingfunctions) && continue
draweasingfunction(Luxor.easingfunctions[n], pos,
Expand Down Expand Up @@ -201,31 +230,3 @@ Here:
The [`easeinoutbezier`](@ref) function accepts two additional arguments, two normalized control points of a normalized Bezier curve from Point(0, 0) to Point(1, 1). You can use these to define the shape of a custom easing transition. The Bezier curve's `y` coordinate determines the acceleration. [?]

![animation of bezier easing](../assets/figures/animation-bezier-easing.gif)

|List of easing functions|
|:--- |
|easingflat|
|lineartween|
|easeinquad|
|easeoutquad|
|easeinoutquad|
|easeincubic|
|easeoutcubic|
|easeinoutcubic|
|easeinquart|
|easeoutquart|
|easeinoutquart|
|easeinquint|
|easeoutquint|
|easeinoutquint|
|easeinsine|
|easeoutsine|
|easeinoutsine|
|easeinexpo|
|easeoutexpo|
|easeinoutexpo|
|easeincirc|
|easeoutcirc|
|easeinoutcirc|
|easeinoutinversequad|
|easeinoutbezier|
10 changes: 6 additions & 4 deletions docs/src/howto/createdrawings.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ To create a drawing, and optionally specify the filename, type, and dimensions,

To finish a drawing and close the file, use [`finish`](@ref), and, if the drawing doesn't appear in your notebook, you can launch an external application to view it using [`preview`](@ref).

The `@draw`, `@svg`, `@png`, and `@pdf` macros are designed to let you quickly create graphics without having to provide the usual boiler-plate functions.
The [`@draw`](@ref), [`@svg`](@ref), [`@png`](@ref), and [`@pdf`](@ref) macros are designed to let you quickly create graphics without having to provide the usual boiler-plate functions.

!!! note

Expand Down Expand Up @@ -67,9 +67,9 @@ or (less nicely):
)
```

The `@draw` macro creates a PNG drawing in-memory (not saved in a file). You should see it displayed if you're working in a suitable environment (Juno, VSCode, Jupyter, Pluto).
The [`@draw`](@ref) macro creates a PNG drawing in-memory (not saved in a file). You should see it displayed if you're working in a suitable environment (Juno, VSCode, Jupyter, Pluto).

The SVG equivalent of `@draw` is `@drawsvg`.
The SVG equivalent of `@draw` is [`@drawsvg`](@ref).

If you don't specify a size, the defaults are usually 600 by 600. If you don't specify a file name, files created with the macros are placed in your current working directory as `luxor-drawing-` followed by a time stamp. You don't even have to specify the suffix:

Expand Down Expand Up @@ -102,7 +102,9 @@ You can choose to store the drawing in memory. The advantage is that in-memory d
Drawing(width, height, surfacetype, [filename])
```

lets you supply `surfacetype` as a symbol (`:svg` or `:png`). This creates a new drawing of the given surface type and stores the image only in memory if no `filename` is supplied. The `@draw` macro creates PNG files in memory.
lets you supply `surfacetype` as a symbol (`:svg` or `:png`). This creates a new drawing of the given surface type and stores the image only in memory if no `filename` is supplied.

The `@draw` and `@drawsvg` macros creates PNG/SVG files in memory.

You can specify `:image` as the surface type. This allows you to copy the current drawing into a 2D matrix (using [`image_as_matrix`](@ref)). See the Images chapter for more information.

Expand Down
Loading

0 comments on commit 2cf8f65

Please sign in to comment.