├── .gitignore
├── samples
├── sample_arc.png
├── sample_clip.png
├── sample_dash.png
├── sample_image.png
├── sample_text.png
├── data
│ └── mulberry.png
├── sample_curve_to.png
├── sample_gradient.png
├── sample_record0.png
├── sample_record1.png
├── sample_script0.png
├── sample_set_dash.png
├── sample_clip_image.png
├── sample_copy_path.png
├── sample_fill_style.png
├── sample_image_copy.png
├── sample_operators.png
├── sample_pango_text.png
├── sample_alpha_paint.png
├── sample_arc_negative.png
├── sample_current_point.png
├── sample_imagepattern.png
├── sample_imagestream.png
├── sample_meshpattern.png
├── sample_set_line_cap.png
├── sample_set_line_join.png
├── sample_text_extents.png
├── sample_copy_path_flat.png
├── sample_curve_rectangle.png
├── sample_fill_and_stroke2.png
├── sample_multi_segment_caps.png
├── sample_rounded_rectangle.png
├── sample_text_align_center.png
├── sample_image.jl
├── sample_multi_segment_caps.jl
├── sample_clip.jl
├── sample_clip_image.jl
├── sample_curve_to.jl
├── sample_set_dash.jl
├── sample_pango_text1.jl
├── sample_dash.jl
├── sample_fill_and_stroke2.jl
├── sample_arc.jl
├── sample_arc_negative.jl
├── sample_image_copy.jl
├── sample_set_line_join.jl
├── sample_imagepattern.jl
├── sample_pango_text.jl
├── sample_text.jl
├── sample_gradient.jl
├── sample_record0.jl
├── sample_set_line_cap.jl
├── sample_fill_style.jl
├── sample_record1.jl
├── sample_text_extents.jl
├── sample_text_align_center.jl
├── sample_script0.jl
├── sample_rounded_rectangle.jl
├── sample_current_point.jl
├── sample_imagestream.jl
├── sample_alpha_paint.jl
├── sample_copy_path.jl
├── sample_copy_path_flat.jl
├── sample_meshpattern.jl
├── sample_operators.jl
├── sample_curve_rectangle.jl
└── Samples.md
├── test
├── tex.jl
├── test_stream.jl
├── test_speed.jl
├── test_painting.jl
├── runtests.jl
└── shape_functions.jl
├── .github
└── workflows
│ ├── TagBot.yml
│ └── CompatHelper.yml
├── .drone.yml
├── README.md
├── .travis.yml
├── Project.toml
├── appveyor.yml
├── LICENSE.md
└── src
├── constants.jl
└── Cairo.jl
/.gitignore:
--------------------------------------------------------------------------------
1 | test/test_results
2 | .DS_Store
3 | *~
4 | .vscode
5 |
--------------------------------------------------------------------------------
/samples/sample_arc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_arc.png
--------------------------------------------------------------------------------
/samples/sample_clip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_clip.png
--------------------------------------------------------------------------------
/samples/sample_dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_dash.png
--------------------------------------------------------------------------------
/samples/sample_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_image.png
--------------------------------------------------------------------------------
/samples/sample_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_text.png
--------------------------------------------------------------------------------
/samples/data/mulberry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/data/mulberry.png
--------------------------------------------------------------------------------
/samples/sample_curve_to.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_curve_to.png
--------------------------------------------------------------------------------
/samples/sample_gradient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_gradient.png
--------------------------------------------------------------------------------
/samples/sample_record0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_record0.png
--------------------------------------------------------------------------------
/samples/sample_record1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_record1.png
--------------------------------------------------------------------------------
/samples/sample_script0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_script0.png
--------------------------------------------------------------------------------
/samples/sample_set_dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_set_dash.png
--------------------------------------------------------------------------------
/samples/sample_clip_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_clip_image.png
--------------------------------------------------------------------------------
/samples/sample_copy_path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_copy_path.png
--------------------------------------------------------------------------------
/samples/sample_fill_style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_fill_style.png
--------------------------------------------------------------------------------
/samples/sample_image_copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_image_copy.png
--------------------------------------------------------------------------------
/samples/sample_operators.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_operators.png
--------------------------------------------------------------------------------
/samples/sample_pango_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_pango_text.png
--------------------------------------------------------------------------------
/samples/sample_alpha_paint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_alpha_paint.png
--------------------------------------------------------------------------------
/samples/sample_arc_negative.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_arc_negative.png
--------------------------------------------------------------------------------
/samples/sample_current_point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_current_point.png
--------------------------------------------------------------------------------
/samples/sample_imagepattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_imagepattern.png
--------------------------------------------------------------------------------
/samples/sample_imagestream.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_imagestream.png
--------------------------------------------------------------------------------
/samples/sample_meshpattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_meshpattern.png
--------------------------------------------------------------------------------
/samples/sample_set_line_cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_set_line_cap.png
--------------------------------------------------------------------------------
/samples/sample_set_line_join.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_set_line_join.png
--------------------------------------------------------------------------------
/samples/sample_text_extents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_text_extents.png
--------------------------------------------------------------------------------
/samples/sample_copy_path_flat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_copy_path_flat.png
--------------------------------------------------------------------------------
/samples/sample_curve_rectangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_curve_rectangle.png
--------------------------------------------------------------------------------
/samples/sample_fill_and_stroke2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_fill_and_stroke2.png
--------------------------------------------------------------------------------
/samples/sample_multi_segment_caps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_multi_segment_caps.png
--------------------------------------------------------------------------------
/samples/sample_rounded_rectangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_rounded_rectangle.png
--------------------------------------------------------------------------------
/samples/sample_text_align_center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wikunia/Cairo.jl/master/samples/sample_text_align_center.png
--------------------------------------------------------------------------------
/test/tex.jl:
--------------------------------------------------------------------------------
1 | using Cairo: tex2pango
2 | using Test
3 |
4 | fsize = 1.618034
5 | @test tex2pango("ƒ_{Nyquist} [\\mu K]",fsize) == "ƒNyquist [μK]"
6 |
--------------------------------------------------------------------------------
/.github/workflows/TagBot.yml:
--------------------------------------------------------------------------------
1 | name: TagBot
2 | on:
3 | schedule:
4 | - cron: 43 22 * * *
5 | jobs:
6 | TagBot:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: JuliaRegistries/TagBot@v1
10 | with:
11 | token: ${{ secrets.GITHUB_TOKEN }}
12 |
--------------------------------------------------------------------------------
/.github/workflows/CompatHelper.yml:
--------------------------------------------------------------------------------
1 | name: CompatHelper
2 |
3 | on:
4 | schedule:
5 | - cron: '00 00 * * *'
6 |
7 | jobs:
8 | CompatHelper:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Pkg.add("CompatHelper")
12 | run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
13 | - name: CompatHelper.main()
14 | env:
15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16 | run: julia -e 'using CompatHelper; CompatHelper.main()'
17 |
--------------------------------------------------------------------------------
/.drone.yml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: pipeline
3 | name: linux - arm - Julia 1.3
4 |
5 | platform:
6 | os: linux
7 | arch: arm
8 |
9 | steps:
10 | - name: build
11 | image: julia:1.3
12 | commands:
13 | - "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"
14 |
15 | ---
16 | kind: pipeline
17 | name: linux - arm64 - Julia 1.3
18 |
19 | platform:
20 | os: linux
21 | arch: arm64
22 |
23 | steps:
24 | - name: build
25 | image: julia:1.3
26 | commands:
27 | - "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"
28 |
29 | ...
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/JuliaGraphics/Cairo.jl)
2 | [](https://ci.appveyor.com/project/lobingera/cairo-jl-f7sfx)
3 | [](https://coveralls.io/github/JuliaGraphics/Cairo.jl?branch=master)
4 |
5 | ## Bindings to the Cairo graphics library ##
6 |
7 | Adaptation to [Cairo](https://www.cairographics.org/), a 2D graphics library with support for multiple output devices.
8 |
9 | Some of the functions implemented by this wrapper may be documented in [Graphics.jl](https://juliagraphics.github.io/Graphics.jl/stable/).
10 |
11 | There is an extensive set of [examples](samples/Samples.md).
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ## Documentation: http://docs.travis-ci.com/user/languages/julia/
2 | language: julia
3 | os:
4 | - linux
5 | - freebsd
6 | - osx
7 | julia:
8 | - 1.3
9 | - nightly
10 | notifications:
11 | email: false
12 | git:
13 | depth: 99999999
14 |
15 | ## uncomment the following lines to allow failures on nightly julia
16 | ## (tests will run but not make your overall status red)
17 | matrix:
18 | allow_failures:
19 | - julia: nightly
20 |
21 | branches:
22 | only:
23 | - master
24 | - gh-pages # For building documentation
25 | - /^testing-.*$/ # testing branches
26 | - /^v[0-9]+\.[0-9]+\.[0-9]+$/ # version tags
27 |
28 | cache:
29 | directories:
30 | - $HOME/.julia/artifacts
31 |
32 | after_success:
33 | - julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder()); Coveralls.submit(Coveralls.process_folder())'
34 |
--------------------------------------------------------------------------------
/samples/sample_image.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 |
15 | image = read_from_png("data/mulberry.png");
16 | w = image.width;
17 | h = image.height;
18 |
19 | translate(cr, 128.0, 128.0);
20 | rotate(cr, 45* pi/180);
21 | scale(cr, 256.0/w, 256.0/h);
22 | translate(cr, -0.5*w, -0.5*h);
23 |
24 | set_source_surface(cr, image, 0, 0);
25 | paint(cr);
26 | #surface_destroy (image);
27 |
28 | ## mark picture with current date
29 | restore(cr);
30 | move_to(cr,0.0,12.0);
31 | set_source_rgb(cr, 0,0,0);
32 | show_text(cr,Libc.strftime(time()));
33 | write_to_png(c,"sample_image.png");
34 |
--------------------------------------------------------------------------------
/samples/sample_multi_segment_caps.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 |
15 | move_to(cr, 50.0, 75.0);
16 | line_to(cr, 200.0, 75.0);
17 |
18 | move_to(cr, 50.0, 125.0);
19 | line_to(cr, 200.0, 125.0);
20 |
21 | move_to(cr, 50.0, 175.0);
22 | line_to(cr, 200.0, 175.0);
23 |
24 | set_line_width(cr, 30.0);
25 | set_line_cap(cr, Cairo.CAIRO_LINE_CAP_ROUND);
26 | stroke(cr);
27 |
28 | ## mark picture with current date
29 | restore(cr);
30 | move_to(cr,0.0,12.0);
31 | set_source_rgb(cr, 0,0,0);
32 | show_text(cr,Libc.strftime(time()));
33 | write_to_png(c,"sample_multi_segment_caps.png");
34 |
--------------------------------------------------------------------------------
/Project.toml:
--------------------------------------------------------------------------------
1 | name = "Cairo"
2 | uuid = "159f3aea-2a34-519c-b102-8c37f9878175"
3 | version = "1.0.4"
4 |
5 | [deps]
6 | Cairo_jll = "83423d85-b0ee-5818-9007-b63ccbeb887a"
7 | Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
8 | Glib_jll = "7746bdde-850d-59dc-9ae8-88ece973131d"
9 | Graphics = "a2bd30eb-e257-5431-a919-1863eab51364"
10 | Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
11 | Pango_jll = "36c8627f-9965-5494-a995-c6b170f724f3"
12 |
13 | [compat]
14 | julia = "1.3"
15 | Cairo_jll = "1.16.0"
16 | Colors = "0.9, 0.10, 0.11, 0.12"
17 | Glib_jll = "2.59.0"
18 | Graphics = "0.4, 1"
19 | Pango_jll = "1.42.4"
20 |
21 | [extras]
22 | Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
23 | Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
24 | Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
25 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
26 |
27 | [targets]
28 | test = ["Base64", "Random", "Printf", "Test"]
29 |
--------------------------------------------------------------------------------
/test/test_stream.jl:
--------------------------------------------------------------------------------
1 | # So that this test can be run independently
2 | using Cairo
3 | using Base64
4 |
5 | include("shape_functions.jl")
6 |
7 | @testset "Test that writing images to a Julia IO object works" begin
8 | c = CairoRGBSurface(256,256)
9 | cr = CairoContext(c)
10 | ddots4(cr,256,246,1.0,3000)
11 | buf = IOBuffer()
12 | pipe = Base64EncodePipe(buf)
13 | write_to_png(c,pipe)
14 | close(pipe)
15 |
16 | # Catch short writes
17 |
18 | str = String(take!(buf))
19 | str_data = codeunits(str)
20 |
21 | @test length(str_data) > 200
22 | end
23 |
24 | @testset "Test that writing images to a temp file works" begin
25 | c = CairoRGBSurface(256,256)
26 | cr = CairoContext(c)
27 | ddots4(cr,256,246,1.0,3000)
28 | fn = tempname()*".png"
29 | @test write_to_png(c,fn) == Cairo.STATUS_SUCCESS
30 | @test isfile(fn)
31 | rm(fn) # clean up
32 | end
33 |
--------------------------------------------------------------------------------
/samples/sample_clip.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 |
15 | arc(cr, 128.0, 128.0, 76.8, 0, 2 * pi);
16 | clip(cr);
17 |
18 | new_path(cr); # current path is not consumed by cairo_clip()
19 | rectangle(cr, 0, 0, 256, 256);
20 | fill(cr);
21 | set_source_rgb(cr, 0, 1, 0);
22 | move_to(cr, 0, 0);
23 | line_to(cr, 256, 256);
24 | move_to(cr, 256, 0);
25 | line_to(cr, 0, 256);
26 | set_line_width(cr, 10.0);
27 | stroke(cr);
28 |
29 | ## mark picture with current date
30 | restore(cr);
31 | move_to(cr,0.0,12.0);
32 | set_source_rgb(cr, 0,0,0);
33 | show_text(cr,Libc.strftime(time()));
34 | write_to_png(c,"sample_clip.png");
35 |
--------------------------------------------------------------------------------
/samples/sample_clip_image.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 |
14 | ## original example, following here
15 |
16 | arc(cr, 128.0, 128.0, 76.8, 0, 2*pi);
17 | clip(cr);
18 | new_path(cr); # path not consumed by clip
19 |
20 | image = read_from_png("data/mulberry.png"); # should be create_from_png
21 | w = image.width;
22 | h = image.height;
23 |
24 | scale(cr, 256.0/w, 256.0/h);
25 |
26 | set_source_surface(cr, image, 0, 0);
27 | paint(cr);
28 |
29 | #cairo_surface_destroy not used here
30 |
31 | ## mark picture with current date
32 | restore(cr);
33 | move_to(cr,0.0,12.0);
34 | set_source_rgb(cr, 0,0,0);
35 | show_text(cr,Libc.strftime(time()));
36 | write_to_png(c,"sample_clip_image.png");
37 |
--------------------------------------------------------------------------------
/samples/sample_curve_to.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 |
14 | ## original example, following here
15 |
16 | x=25.6; y=128.0;
17 | x1=102.4; y1=230.4;
18 | x2=153.6; y2=25.6;
19 | x3=230.4; y3=128.0;
20 |
21 | move_to(cr, x, y);
22 | curve_to(cr, x1, y1, x2, y2, x3, y3);
23 |
24 | set_line_width(cr, 10.0);
25 | stroke(cr);
26 |
27 | set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
28 | set_line_width(cr, 6.0);
29 | move_to(cr,x,y); line_to(cr,x1,y1);
30 | move_to(cr,x2,y2); line_to(cr,x3,y3);
31 | stroke(cr);
32 |
33 | ## mark picture with current date
34 | restore(cr);
35 | move_to(cr,0.0,12.0);
36 | set_source_rgb(cr, 0,0,0);
37 | show_text(cr,Libc.strftime(time()));
38 | write_to_png(c,"sample_curve_to.png");
39 |
--------------------------------------------------------------------------------
/samples/sample_set_dash.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 |
14 | ## api example, use set_line_type
15 |
16 | dashes_by_name = [
17 | "solid",
18 | "dot",
19 | "dotdashed",
20 | "longdashed",
21 | "dash",
22 | "dotdotdashed",
23 | "dotdotdotdashed"]
24 |
25 | set_line_width(cr, 3.0);
26 |
27 | for k=1:7
28 | save(cr)
29 | set_line_type(cr, dashes_by_name[k])
30 | move_to(cr,16.0,16.0+(k*32.0))
31 | line_to(cr,240.0,16.0+(k*32.0))
32 | stroke(cr)
33 | restore(cr)
34 | end
35 |
36 | ## mark picture with current date
37 | restore(cr);
38 | move_to(cr,0.0,12.0);
39 | set_source_rgb(cr, 0,0,0);
40 | show_text(cr,Libc.strftime(time()));
41 | write_to_png(c,"sample_set_dash.png");
42 |
--------------------------------------------------------------------------------
/samples/sample_pango_text1.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | using Printf
4 |
5 | c = CairoRGBSurface(256,256);
6 | cr = CairoContext(c);
7 |
8 | save(cr);
9 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
10 | rectangle(cr,0.0,0.0,256.0,256.0); # background
11 | fill(cr);
12 | restore(cr);
13 |
14 | save(cr);
15 |
16 | set_font_face(cr, "Sans 16")
17 |
18 | text(cr,40.0,40.0,"EF",markup=true)
19 | text(cr,40.0,60.0,"EGDC")
20 |
21 | text(cr,40.0,90.0,"EFGH",markup=true)
22 | text(cr,40.0,110.0,"EGDC",markup=true)
23 |
24 | text(cr,40.0,140.0,"GEFJ",markup=true)
25 | text(cr,40.0,160.0,"EGDC")
26 |
27 |
28 | ## mark picture with current date
29 | restore(cr);
30 | move_to(cr,0.0,12.0);
31 | set_source_rgb(cr, 0,0,0);
32 | show_text(cr,Libc.strftime(time()));
33 | write_to_png(c,"sample_pango_text1.png");
34 |
--------------------------------------------------------------------------------
/samples/sample_dash.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 |
15 | dashes = [50.0, # ink
16 | 10.0, # skip
17 | 10.0, # ink
18 | 10.0 # skip
19 | ];
20 | #ndash = length(dashes); not implemented as ndash on set_dash
21 | offset = -50.0;
22 |
23 | set_dash(cr, dashes, offset);
24 | set_line_width(cr, 10.0);
25 |
26 | move_to(cr, 128.0, 25.6);
27 | line_to(cr, 230.4, 230.4);
28 | rel_line_to(cr, -102.4, 0.0);
29 | curve_to(cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
30 |
31 | stroke(cr);
32 |
33 |
34 | ## mark picture with current date
35 | restore(cr);
36 | move_to(cr,0.0,12.0);
37 | set_source_rgb(cr, 0,0,0);
38 | show_text(cr,Libc.strftime(time()));
39 | write_to_png(c,"sample_dash.png");
40 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 | matrix:
3 | - julia_version: 1.3
4 | - julia_version: nightly
5 |
6 | platform:
7 | - x86 # 32-bit
8 | - x64 # 64-bit
9 |
10 | ## uncomment the following lines to allow failures on nightly julia
11 | ## (tests will run but not make your overall status red)
12 | matrix:
13 | allow_failures:
14 | - platform: x86
15 | - julia_version: latest
16 |
17 | branches:
18 | only:
19 | - master
20 | - /release-.*/
21 |
22 | cache:
23 | - '%USERPROFILE%\.julia\artifacts'
24 |
25 | notifications:
26 | - provider: Email
27 | on_build_success: false
28 | on_build_failure: false
29 | on_build_status_changed: false
30 |
31 | install:
32 | - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
33 |
34 | build_script:
35 | - echo "%JL_BUILD_SCRIPT%"
36 | - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
37 |
38 | test_script:
39 | - echo "%JL_TEST_SCRIPT%"
40 | - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
41 |
--------------------------------------------------------------------------------
/samples/sample_fill_and_stroke2.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | move_to(cr, 128.0, 25.6);
15 | line_to(cr, 230.4, 230.4);
16 | rel_line_to(cr, -102.4, 0.0);
17 | curve_to(cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
18 | close_path(cr);
19 |
20 | move_to(cr, 64.0, 25.6);
21 | rel_line_to(cr, 51.2, 51.2);
22 | rel_line_to(cr, -51.2, 51.2);
23 | rel_line_to(cr, -51.2, -51.2);
24 | close_path(cr);
25 |
26 | set_line_width(cr, 10.0);
27 | set_source_rgb(cr, 0, 0, 1);
28 | fill_preserve(cr);
29 | set_source_rgb(cr, 0, 0, 0);
30 | stroke(cr);
31 |
32 | ## mark picture with current date
33 | restore(cr);
34 | move_to(cr,0.0,12.0);
35 | set_source_rgb(cr, 0,0,0);
36 | show_text(cr,Libc.strftime(time()));
37 | write_to_png(c,"sample_fill_and_stroke2.png");
38 |
--------------------------------------------------------------------------------
/samples/sample_arc.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 |
4 | c = CairoRGBSurface(256,256);
5 | cr = CairoContext(c);
6 |
7 | save(cr);
8 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
9 | rectangle(cr,0.0,0.0,256.0,256.0); # background
10 | fill(cr);
11 | restore(cr);
12 |
13 | ## original example, following here
14 | xc = 128.0;
15 | yc = 128.0;
16 | radius = 100.0;
17 | angle1 = 45.0 * (pi/180.0); # angles are specified
18 | angle2 = 180.0 * (pi/180.0); # in radians
19 |
20 | set_line_width(cr, 10.0);
21 | arc(cr, xc, yc, radius, angle1, angle2);
22 | stroke(cr);
23 |
24 | # draw helping lines
25 | set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
26 | set_line_width(cr, 6.0);
27 |
28 | arc(cr, xc, yc, 10.0, 0, 2*pi);
29 | fill(cr);
30 |
31 | arc(cr, xc, yc, radius, angle1, angle1);
32 | line_to(cr, xc, yc);
33 | arc(cr, xc, yc, radius, angle2, angle2);
34 | line_to(cr, xc, yc);
35 | stroke(cr);
36 |
37 | ## mark picture with current date
38 | move_to(cr,0.0,12.0);
39 | set_source_rgb(cr, 0,0,0);
40 | show_text(cr,Libc.strftime(time()));
41 | write_to_png(c,"sample_arc.png");
42 |
--------------------------------------------------------------------------------
/samples/sample_arc_negative.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | ## original example, following here
13 | xc = 128.0;
14 | yc = 128.0;
15 | radius = 100.0;
16 | angle1 = 45.0 * (pi/180.0); # angles are specified
17 | angle2 = 180.0 * (pi/180.0); # in radians
18 |
19 | set_line_width(cr, 10.0);
20 | arc_negative(cr, xc, yc, radius, angle1, angle2);
21 | stroke(cr);
22 |
23 | # draw helping lines
24 | set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
25 | set_line_width(cr, 6.0);
26 |
27 | arc(cr, xc, yc, 10.0, 0, 2*pi);
28 | fill(cr);
29 |
30 | arc(cr, xc, yc, radius, angle1, angle1);
31 | line_to(cr, xc, yc);
32 | arc(cr, xc, yc, radius, angle2, angle2);
33 | line_to(cr, xc, yc);
34 | stroke(cr);
35 |
36 | ## mark picture with current date
37 | move_to(cr,0.0,12.0);
38 | set_source_rgb(cr, 0,0,0);
39 | show_text(cr,Libc.strftime(time()));
40 | write_to_png(c,"sample_arc_negative.png");
41 |
--------------------------------------------------------------------------------
/samples/sample_image_copy.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | using Graphics
4 |
5 | c = CairoRGBSurface(256,256);
6 | cr = CairoContext(c);
7 |
8 | save(cr);
9 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
10 | rectangle(cr,0.0,0.0,256.0,256.0); # background
11 | fill(cr);
12 | restore(cr);
13 |
14 | save(cr);
15 |
16 | # put image top left
17 | s = read_from_png("data/mulberry.png");
18 | Cairo.image(cr,s,0,0,128,128)
19 |
20 | # copy inplace, so to apply copy as source, need coordinate translate
21 | c1 = copy(cr)
22 |
23 | save(cr)
24 | translate(cr,128,0)
25 | rectangle(cr,0,0,256,256)
26 | set_source_surface(cr,c1.surface)
27 | paint(cr)
28 | restore(cr)
29 |
30 | # copy centered part
31 | c2 = copy(cr,Graphics.BoundingBox(64,192,0,128))
32 |
33 | save(cr)
34 |
35 | rectangle(cr,0,0,256,256)
36 | set_source_surface(cr,c2.surface,64,128)
37 | paint(cr)
38 | restore(cr)
39 |
40 | ## mark picture with current date
41 | restore(cr);
42 | move_to(cr,0.0,12.0);
43 | set_source_rgb(cr, 0,0,0);
44 | show_text(cr,Libc.strftime(time()));
45 | write_to_png(c,"sample_image_copy.png");
46 |
--------------------------------------------------------------------------------
/samples/sample_set_line_join.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | set_line_width(cr, 40.96);
15 | move_to(cr, 76.8, 84.48);
16 | rel_line_to(cr, 51.2, -51.2);
17 | rel_line_to(cr, 51.2, 51.2);
18 | set_line_join(cr, Cairo.CAIRO_LINE_JOIN_MITER); # default
19 | stroke(cr);
20 |
21 | move_to(cr, 76.8, 161.28);
22 | rel_line_to(cr, 51.2, -51.2);
23 | rel_line_to(cr, 51.2, 51.2);
24 | set_line_join(cr, Cairo.CAIRO_LINE_JOIN_BEVEL);
25 | stroke(cr);
26 |
27 | move_to(cr, 76.8, 238.08);
28 | rel_line_to(cr, 51.2, -51.2);
29 | rel_line_to(cr, 51.2, 51.2);
30 | set_line_join(cr, Cairo.CAIRO_LINE_JOIN_ROUND);
31 | stroke(cr);
32 |
33 | ## mark picture with current date
34 | restore(cr);
35 | move_to(cr,0.0,12.0);
36 | set_source_rgb(cr, 0,0,0);
37 | show_text(cr,Libc.strftime(time()));
38 | write_to_png(c,"sample_set_line_join.png");
39 |
--------------------------------------------------------------------------------
/samples/sample_imagepattern.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | image = read_from_png("data/mulberry.png");
15 | w = image.width;
16 | h = image.height;
17 |
18 | pattern = CairoPattern(image);
19 | pattern_set_extend(pattern, Cairo.EXTEND_REPEAT);
20 |
21 | translate(cr, 128.0, 128.0);
22 | rotate(cr, pi / 4);
23 | scale(cr, 1 / sqrt(2), 1 / sqrt(2));
24 | translate(cr, -128.0, -128.0);
25 |
26 | m = CairoMatrix(w/256.0 * 5.0,0,0,h/256.0 * 5.0,0,0);
27 | #matrix_init_scale (&matrix, w/256.0 * 5.0, h/256.0 * 5.0);
28 |
29 | set_matrix(pattern, m);
30 | set_source(cr, pattern);
31 |
32 | rectangle(cr, 0, 0, 256.0, 256.0);
33 | fill(cr);
34 |
35 | ## mark picture with current date
36 | restore(cr);
37 | move_to(cr,0.0,12.0);
38 | set_source_rgb(cr, 0,0,0);
39 | show_text(cr,Libc.strftime(time()));
40 | write_to_png(c,"sample_imagepattern.png");
41 |
--------------------------------------------------------------------------------
/samples/sample_pango_text.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | using Printf
4 |
5 | c = CairoRGBSurface(256,256);
6 | cr = CairoContext(c);
7 |
8 | save(cr);
9 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
10 | rectangle(cr,0.0,0.0,256.0,256.0); # background
11 | fill(cr);
12 | restore(cr);
13 |
14 | save(cr);
15 |
16 | set_font_face(cr, "Sans 16")
17 |
18 | text(cr,16.0,40.0,"Hamburgefons")
19 | text(cr,16.0,72.0,"sp⁰¹²³,min⁻²,αΑβΒφϕΦγΓ")
20 | text(cr,16.0,104.0,"TextBoldItalicsuper-2",markup=true)
21 |
22 | text(cr,40.0,224.0,"Es geht aufwärts !",markup=true,angle=30.0)
23 |
24 | #using textwidth and height
25 |
26 | set_font_face(cr, "Sans 12")
27 |
28 | a = "A"
29 | aheight = textheight(cr,a)
30 | awidth = textwidth(cr,a)
31 | atext = @sprintf("%s wd=%2.2f,ht=%2.2f",a,awidth,aheight)
32 | text(cr,16.0,240.0,atext,markup=true)
33 |
34 |
35 | ## mark picture with current date
36 | restore(cr);
37 | move_to(cr,0.0,12.0);
38 | set_source_rgb(cr, 0,0,0);
39 | show_text(cr,Libc.strftime(time()));
40 | write_to_png(c,"sample_pango_text.png");
41 |
--------------------------------------------------------------------------------
/samples/sample_text.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 |
15 | select_font_face(cr, "Sans", Cairo.FONT_SLANT_NORMAL,
16 | Cairo.FONT_WEIGHT_BOLD);
17 | set_font_size(cr, 90.0);
18 |
19 | move_to(cr, 10.0, 135.0);
20 | show_text(cr, "Hello");
21 |
22 | move_to(cr, 70.0, 165.0);
23 | text_path(cr, "void");
24 | set_source_rgb(cr, 0.5, 0.5, 1);
25 | fill_preserve(cr);
26 | set_source_rgb(cr, 0, 0, 0);
27 | set_line_width(cr, 2.56);
28 | stroke(cr);
29 |
30 | # draw helping lines
31 | set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
32 | arc(cr, 10.0, 135.0, 5.12, 0, 2*pi);
33 | close_path(cr);
34 | arc(cr, 70.0, 165.0, 5.12, 0, 2*pi);
35 | fill(cr);
36 |
37 |
38 | ## mark picture with current date
39 | restore(cr);
40 | move_to(cr,0.0,12.0);
41 | set_source_rgb(cr, 0,0,0);
42 | show_text(cr,Libc.strftime(time()));
43 | write_to_png(c,"sample_text.png");
44 |
--------------------------------------------------------------------------------
/samples/sample_gradient.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 |
14 | ## original example, following here
15 |
16 | pat = pattern_create_linear(0.0, 0.0, 0.0, 256.0);
17 | pattern_add_color_stop_rgb(pat, 1, 0, 0, 0); # alpha=1
18 | pattern_add_color_stop_rgb(pat, 0, 1, 1, 1);
19 | rectangle(cr, 0, 0, 256, 256);
20 | set_source(cr, pat);
21 | fill(cr);
22 | destroy(pat);
23 |
24 | pat = pattern_create_radial(115.2, 102.4, 25.6,
25 | 102.4, 102.4, 128.0);
26 | pattern_add_color_stop_rgba(pat, 0, 1, 1, 1, 1); # explicit alpha=1
27 | pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 1);
28 | set_source(cr, pat);
29 | arc(cr, 128.0, 128.0, 76.8, 0, 2 * pi);
30 | fill(cr);
31 | destroy(pat);
32 |
33 | ## mark picture with current date
34 | restore(cr);
35 | move_to(cr,0.0,12.0);
36 | set_source_rgb(cr, 0,0,0);
37 | show_text(cr,Libc.strftime(time()));
38 | write_to_png(c,"sample_gradient.png");
39 |
--------------------------------------------------------------------------------
/samples/sample_record0.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoARGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgba(cr,0.0,0.0,0.0,0.0); # transparent black
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 | save(cr);
12 |
13 | s1 = CairoRecordingSurface()
14 | c1 = CairoContext(s1)
15 |
16 | ## original example, following here
17 | move_to(c1, 128.0, 25.6);
18 | line_to(c1, 230.4, 230.4);
19 | rel_line_to(c1, -102.4, 0.0);
20 | curve_to(c1, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
21 | close_path(c1);
22 |
23 | move_to(c1, 64.0, 25.6);
24 | rel_line_to(c1, 51.2, 51.2);
25 | rel_line_to(c1, -51.2, 51.2);
26 | rel_line_to(c1, -51.2, -51.2);
27 | close_path(c1);
28 |
29 | set_line_width(c1, 10.0);
30 | set_source_rgb(c1, 0, 0, 1);
31 | fill_preserve(c1);
32 | set_source_rgb(c1, 0, 0, 0);
33 | stroke(c1);
34 |
35 | ## now using the recorded painting
36 | set_source(cr, s1, 0.0, 0.0)
37 | paint(cr)
38 |
39 |
40 | ## mark picture with current date
41 | restore(cr);
42 | move_to(cr,0.0,12.0);
43 | set_source_rgb(cr, 0,0,0);
44 | show_text(cr,Libc.strftime(time()));
45 | write_to_png(c,"sample_record0.png");
46 |
--------------------------------------------------------------------------------
/samples/sample_set_line_cap.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | set_line_width(cr, 30.0);
15 | set_line_cap(cr, Cairo.CAIRO_LINE_CAP_BUTT); # default
16 | move_to(cr, 64.0, 50.0); line_to(cr, 64.0, 200.0);
17 | stroke(cr);
18 | set_line_cap(cr, Cairo.CAIRO_LINE_CAP_ROUND);
19 | move_to(cr, 128.0, 50.0); line_to(cr, 128.0, 200.0);
20 | stroke(cr);
21 | set_line_cap(cr, Cairo.CAIRO_LINE_CAP_SQUARE);
22 | move_to(cr, 192.0, 50.0); line_to(cr, 192.0, 200.0);
23 | stroke(cr);
24 |
25 | # draw helping lines
26 | set_source_rgb(cr, 1, 0.2, 0.2);
27 | set_line_width(cr, 2.56);
28 | move_to(cr, 64.0, 50.0); line_to(cr, 64.0, 200.0);
29 | move_to(cr, 128.0, 50.0); line_to(cr, 128.0, 200.0);
30 | move_to(cr, 192.0, 50.0); line_to(cr, 192.0, 200.0);
31 | stroke(cr);
32 |
33 | ## mark picture with current date
34 | restore(cr);
35 | move_to(cr,0.0,12.0);
36 | set_source_rgb(cr, 0,0,0);
37 | show_text(cr,Libc.strftime(time()));
38 | write_to_png(c,"sample_set_line_cap.png");
39 |
--------------------------------------------------------------------------------
/samples/sample_fill_style.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | set_line_width(cr, 6);
15 |
16 | rectangle(cr, 12, 12, 232, 70);
17 | new_sub_path(cr); arc(cr, 64, 64, 40, 0, 2*pi);
18 | new_sub_path(cr); arc_negative(cr, 192, 64, 40, 0, -2*pi);
19 |
20 | set_fill_type(cr, Cairo.CAIRO_FILL_RULE_EVEN_ODD); # should be set_fill_rule
21 | set_source_rgb(cr, 0, 0.7, 0); fill_preserve(cr);
22 | set_source_rgb(cr, 0, 0, 0); stroke(cr);
23 |
24 | translate(cr, 0, 128);
25 | rectangle(cr, 12, 12, 232, 70);
26 | new_sub_path(cr); arc(cr, 64, 64, 40, 0, 2*pi);
27 | new_sub_path(cr); arc_negative(cr, 192, 64, 40, 0, -2*pi);
28 |
29 | set_fill_type(cr, Cairo.CAIRO_FILL_RULE_WINDING);
30 | set_source_rgb(cr, 0, 0, 0.9); fill_preserve(cr);
31 | set_source_rgb(cr, 0, 0, 0); stroke(cr);
32 |
33 | ## mark picture with current date
34 | restore(cr);
35 | move_to(cr,0.0,12.0);
36 | set_source_rgb(cr, 0,0,0);
37 | show_text(cr,Libc.strftime(time()));
38 | write_to_png(c,"sample_fill_style.png");
39 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Cairo.jl is licensed under the MIT License:
2 |
3 | > Copyright (c) 2012-2013: Jeff Bezanson, Keno Fischer, Tim Holy, Mike
4 | > Nolta, Viral Shah, and other contributors.>
5 |
6 | > Permission is hereby granted, free of charge, to any person obtaining
7 | > a copy of this software and associated documentation files (the
8 | > "Software"), to deal in the Software without restriction, including
9 | > without limitation the rights to use, copy, modify, merge, publish,
10 | > distribute, sublicense, and/or sell copies of the Software, and to
11 | > permit persons to whom the Software is furnished to do so, subject to
12 | > the following conditions:
13 | >
14 | > The above copyright notice and this permission notice shall be
15 | > included in all copies or substantial portions of the Software.
16 | >
17 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | > LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/samples/sample_record1.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoARGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgba(cr,0.0,0.0,0.0,0.0); # transparent black
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 | save(cr);
12 |
13 | ## paint the following to a Recording Surface
14 | s1 = CairoRecordingSurface()
15 | c1 = CairoContext(s1)
16 |
17 | move_to(c1, 128.0, 25.6);
18 | line_to(c1, 230.4, 230.4);
19 | rel_line_to(c1, -102.4, 0.0);
20 | curve_to(c1, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
21 | close_path(c1);
22 |
23 | move_to(c1, 64.0, 25.6);
24 | rel_line_to(c1, 51.2, 51.2);
25 | rel_line_to(c1, -51.2, 51.2);
26 | rel_line_to(c1, -51.2, -51.2);
27 | close_path(c1);
28 |
29 | set_line_width(c1, 10.0);
30 | set_source_rgb(c1, 0, 0, 1);
31 | fill_preserve(c1);
32 | set_source_rgb(c1, 0, 0, 0);
33 | stroke(c1);
34 |
35 | ## play back on transform coord
36 | scale(cr,0.5,0.5)
37 | set_source(cr, s1, 128.0, 128.0)
38 |
39 | paint(cr)
40 |
41 |
42 | ## mark picture with current date
43 | restore(cr);
44 | move_to(cr,0.0,12.0);
45 | set_source_rgb(cr, 0,0,0);
46 | show_text(cr,Libc.strftime(time()));
47 | write_to_png(c,"sample_record1.png");
48 |
49 | ## write to script
50 | #s2 = Cairo.CairoScript("cairo-record1.cs")
51 | #Cairo.script_from_recording_surface(s2,s1)
52 |
--------------------------------------------------------------------------------
/samples/sample_text_extents.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | select_font_face(cr, "Sans", Cairo.FONT_SLANT_NORMAL,
15 | Cairo.FONT_WEIGHT_NORMAL);
16 | set_font_size(cr, 100.0);
17 | extents = text_extents(cr, "cairo");
18 |
19 | #
20 | # typedef struct {
21 | # double x_bearing;
22 | # double y_bearing;
23 | # double width;
24 | # double height;
25 | # double x_advance;
26 | # double y_advance;
27 | # } cairo_text_extents_t;
28 |
29 | x = 25.0;
30 | y = 150.0;
31 |
32 | move_to(cr, x, y);
33 | show_text(cr, "cairo");
34 |
35 | # draw helping lines
36 | set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
37 | set_line_width(cr, 6.0);
38 | arc(cr, x, y, 10.0, 0, 2*pi);
39 | fill(cr);
40 | move_to(cr, x,y);
41 | rel_line_to(cr, 0, -extents[4]);
42 | rel_line_to(cr, extents[3], 0);
43 | rel_line_to(cr, extents[1], -extents[2]);
44 | stroke(cr);
45 | ## mark picture with current date
46 | restore(cr);
47 | move_to(cr,0.0,12.0);
48 | set_source_rgb(cr, 0,0,0);
49 | show_text(cr,Libc.strftime(time()));
50 | write_to_png(c,"sample_text_extents.png");
51 |
--------------------------------------------------------------------------------
/samples/sample_text_align_center.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 | select_font_face(cr, "Sans", Cairo.FONT_SLANT_NORMAL,
15 | Cairo.FONT_WEIGHT_NORMAL);
16 | set_font_size(cr, 52.0);
17 | extents = text_extents(cr, "cairo");
18 |
19 | #
20 | # typedef struct {
21 | # double x_bearing;
22 | # double y_bearing;
23 | # double width;
24 | # double height;
25 | # double x_advance;
26 | # double y_advance;
27 | # } cairo_text_extents_t;
28 |
29 | x = 128.0-(extents[3]/2 + extents[1]);
30 | y = 128.0-(extents[4]/2 + extents[2]);
31 |
32 | move_to(cr, x, y);
33 | show_text(cr, "cairo");
34 |
35 | # draw helping lines
36 | set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
37 | set_line_width(cr, 6.0);
38 | arc(cr, x, y, 10.0, 0, 2*pi);
39 | fill(cr);
40 | move_to(cr, 128.0, 0);
41 | rel_line_to(cr, 0, 256);
42 | move_to(cr, 0, 128.0);
43 | rel_line_to(cr, 256, 0);
44 | stroke(cr);
45 |
46 | ## mark picture with current date
47 | restore(cr);
48 | move_to(cr,0.0,12.0);
49 | set_source_rgb(cr, 0,0,0);
50 | show_text(cr,Libc.strftime(time()));
51 | write_to_png(c,"sample_text_align_center.png");
52 |
--------------------------------------------------------------------------------
/samples/sample_script0.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoARGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.5,0.5,0.5);
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 | save(cr);
12 |
13 | ## paint the following to a Recording Surface
14 | s1 = CairoRecordingSurface()
15 | c1 = CairoContext(s1)
16 |
17 | move_to(c1, 128.0, 25.6);
18 | line_to(c1, 230.4, 230.4);
19 | rel_line_to(c1, -102.4, 0.0);
20 | curve_to(c1, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
21 | close_path(c1);
22 |
23 | move_to(c1, 64.0, 25.6);
24 | rel_line_to(c1, 51.2, 51.2);
25 | rel_line_to(c1, -51.2, 51.2);
26 | rel_line_to(c1, -51.2, -51.2);
27 | close_path(c1);
28 |
29 | set_line_width(c1, 10.0);
30 | set_source_rgb(c1, 0, 0, 1);
31 | fill_preserve(c1);
32 | set_source_rgb(c1, 0, 0, 0);
33 | stroke(c1);
34 |
35 | ## write to script
36 |
37 | io = IOBuffer()
38 | s2 = Cairo.CairoScript(io)
39 | Cairo.script_from_recording_surface(s2,s1);
40 | destroy(s2)
41 |
42 | seek(io,0)
43 | r = String(read(io))
44 |
45 | r1 = split(r,"\n")
46 |
47 | t1 = 24.0
48 | for x in r1
49 | move_to(cr,0.0,t1)
50 | show_text(cr,x)
51 | global t1 += 12.0
52 | end
53 |
54 |
55 | ## mark picture with current date
56 | restore(cr);
57 | move_to(cr,0.0,12.0);
58 | set_source_rgb(cr, 0,0,0);
59 | show_text(cr,Libc.strftime(time()));
60 | write_to_png(c,"sample_script0.png");
61 |
62 |
--------------------------------------------------------------------------------
/samples/sample_rounded_rectangle.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, following here
14 |
15 | # a custom shape that could be wrapped in a function */
16 | x = 25.6; # parameters like cairo_rectangle */
17 | y = 25.6;
18 | xw = 204.8;
19 | yw = 204.8;
20 | aspect = 1.0; # aspect ratio */
21 | corner_radius = yw / 10.0; #* and corner curvature radius */
22 |
23 | radius = corner_radius / aspect;
24 | degrees = pi / 180.0;
25 |
26 | new_sub_path(cr);
27 | arc(cr, x + xw - radius, y + radius, radius, -90 * degrees, 0 * degrees);
28 | arc(cr, x + xw - radius, y + yw - radius, radius, 0 * degrees, 90 * degrees);
29 | arc(cr, x + radius, y + yw - radius, radius, 90 * degrees, 180 * degrees);
30 | arc(cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
31 | close_path(cr);
32 |
33 | set_source_rgb(cr, 0.5, 0.5, 1);
34 | fill_preserve(cr);
35 | set_source_rgba(cr, 0.5, 0, 0, 0.5);
36 | set_line_width(cr, 10.0);
37 | stroke(cr);
38 |
39 | ## mark picture with current date
40 | restore(cr);
41 | move_to(cr,0.0,12.0);
42 | set_source_rgb(cr, 0,0,0);
43 | show_text(cr,Libc.strftime(time()));
44 | write_to_png(c,"sample_rounded_rectangle.png");
45 |
--------------------------------------------------------------------------------
/samples/sample_current_point.jl:
--------------------------------------------------------------------------------
1 | using Cairo
2 |
3 | function common_header()
4 | ## header to provide surface and context
5 | c = CairoRGBSurface(256,256);
6 | cr = CairoContext(c);
7 |
8 | save(cr);
9 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
10 | rectangle(cr,0.0,0.0,256.0,256.0); # background
11 | fill(cr);
12 | restore(cr);
13 |
14 | return c,cr
15 | end
16 |
17 | function write_out_picture(filename::AbstractString,c::CairoSurface)
18 | ## mark picture with current date
19 | move_to(cr,0.0,12.0);
20 | set_source_rgb(cr, 0,0,0);
21 | show_text(cr,Libc.strftime(time()));
22 | ##
23 | write_to_png(c,filename);
24 | nothing
25 | end
26 |
27 | function example_current_point(cr)
28 | save(cr);
29 |
30 | x=25.6; y=128.0;
31 | x1=102.4; y1=30.4;
32 | x2=123.6; y2=45.6;
33 | x3=130.4; y3=128.0;
34 |
35 | move_to(cr, x, y);
36 | curve_to(cr, x1, y1, x2, y2, x3, y3);
37 |
38 | if has_current_point(cr)
39 | x,y = get_current_point(cr);
40 | save(cr)
41 | move_to(cr,x,y)
42 | set_source_rgb(cr, 0,0,1.0);
43 | show_text(cr,"current point")
44 | restore(cr)
45 | end
46 |
47 | set_line_width(cr, 10.0);
48 | stroke(cr);
49 |
50 |
51 | restore(cr);
52 | save(cr);
53 |
54 | nothing
55 | end
56 |
57 |
58 | c,cr = common_header();
59 | save(cr);
60 | example_current_point(cr);
61 | restore(cr);
62 | write_out_picture("sample_current_point.png",c);
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/samples/sample_imagestream.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | # example, following here
14 |
15 | inline_png2 = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00d\x00\x00\x00d\x08\x02\x00\x00\x00\xff\x80\x02\x03\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x01=IDATx\x9c\xed\xdc\xc1i\x85@\x14@\xd1IH!\x96bi\x96f)\x96\x92E@!\x01\x7f\xeeF\xfdp\xce\xca\x9d\xc3\xe5\xb9{\xce\xc7\xb2,\x83\xff\xf9\xbc\xfb\x00\xefD\xac@\xac@\xac@\xac@\xac@\xac@\xac@\xac\xe0\xeb\xee\x03\xfc\xb1\xaec]\xc7\x18c\x9e\xc7<\xdf{\x96_LV V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V\xf0j[\xf9gq\xf8J\xdbv<\\\xff\xf6\xd3\xfd\xe8\xe7\xc5\xdam\xdb\x11\xee2\xa7\xb1|\x86\xc1\xab\xc9\xba~m\x7f\x1f\xa8i\x1a\xd3t\xf5\xdbO=/\xd6\xba\x1e\xb1\xfca\xf1\xbe\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\xc4\n\x9ew\x1f\xfc\xf3\xae\x81\xdf\x99\xac@\xac@\xac@\xac@\xac@\xac@\xac@\xac@\xac\xe0\x1b\xaf\xef\x1c\xd4\x17\xfe\xcaX\x00\x00\x00\x00IEND\xaeB`\x82"
16 | png_stream = IOBuffer();
17 | write(png_stream,inline_png2);
18 | seekstart(png_stream);
19 |
20 | imagesurface = read_from_png(png_stream);
21 | set_source_surface(cr, imagesurface, 0, 0);
22 | paint(cr);
23 |
24 | ## mark picture with current date
25 | restore(cr);
26 | move_to(cr,0.0,12.0);
27 | set_source_rgb(cr, 0,0,0);
28 | show_text(cr,Libc.strftime(time()));
29 | write_to_png(c,"sample_imagestream.png");
30 |
--------------------------------------------------------------------------------
/samples/sample_alpha_paint.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | using Colors
4 |
5 | c = CairoRGBSurface(256,256)
6 | cr = CairoContext(c)
7 |
8 | save(cr)
9 |
10 | z = Array{RGB24}(undef, 2, 2)
11 | c1 = convert(RGB24,colorant"grey20")
12 | c2 = convert(RGB24,colorant"grey80")
13 | z[1,1] = c1
14 | z[1,2] = c2
15 | z[2,1] = c2
16 | z[2,2] = c1
17 |
18 | img = CairoImageSurface(z)
19 | pattern = CairoPattern(img)
20 | pattern_set_extend(pattern, Cairo.EXTEND_REPEAT)
21 | pattern_set_filter(pattern, Cairo.FILTER_BILINEAR)
22 |
23 | m = CairoMatrix(1/8.0,0,0,1/8.0,0,0)
24 |
25 | set_matrix(pattern, m)
26 | set_source(cr, pattern)
27 | paint(cr)
28 | restore(cr)
29 |
30 | save(cr)
31 |
32 | # 5 uses of set_source
33 |
34 | # color
35 | save(cr)
36 | rectangle(cr,16,32,224,32)
37 | set_source(cr, colorant"red4")
38 | fill(cr)
39 | restore(cr)
40 |
41 | # color with alpha
42 | save(cr)
43 | rectangle(cr,16,72,224,32)
44 | set_source(cr, alphacolor(colorant"blue",0.5))
45 | fill(cr)
46 | restore(cr)
47 |
48 | # image from surface
49 | save(cr)
50 | rectangle(cr,16,112,224,32)
51 | clip(cr)
52 | new_path(cr)
53 | s = read_from_png("data/mulberry.png")
54 | set_source(cr,s)
55 | paint_with_alpha(cr,0.6)
56 | restore(cr)
57 |
58 | # image from context (from surface)
59 | save(cr)
60 | rectangle(cr,16,152,224,32)
61 | clip(cr)
62 | new_path(cr)
63 | set_source(cr,creategc(s))
64 | paint(cr)
65 | restore(cr)
66 |
67 | # image for surface with offset
68 | save(cr)
69 | rectangle(cr,16,192,224,32)
70 | clip(cr)
71 | set_source(cr,s,0.0,40.0)
72 | paint(cr)
73 | restore(cr)
74 |
75 |
76 |
77 | ## mark picture with current date
78 | restore(cr)
79 | move_to(cr,0.0,12.0)
80 | set_source_rgb(cr, 0,0,0)
81 | show_text(cr,Libc.strftime(time()))
82 | write_to_png(c,"sample_alpha_paint.png")
83 |
--------------------------------------------------------------------------------
/samples/sample_copy_path.jl:
--------------------------------------------------------------------------------
1 | using Cairo
2 |
3 | function common_header()
4 | ## header to provide surface and context
5 | c = CairoRGBSurface(256,256);
6 | cr = CairoContext(c);
7 |
8 | save(cr);
9 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
10 | rectangle(cr,0.0,0.0,256.0,256.0); # background
11 | fill(cr);
12 | restore(cr);
13 |
14 | return c,cr
15 | end
16 |
17 | function write_out_picture(filename::AbstractString,c::CairoSurface)
18 | ## mark picture with current date
19 | move_to(cr,0.0,12.0);
20 | set_source_rgb(cr, 0,0,0);
21 | show_text(cr,Libc.strftime(time()));
22 | ##
23 | write_to_png(c,filename);
24 | nothing
25 | end
26 |
27 | function example_copy_path(cr)
28 |
29 | save(cr);
30 | # single (large) character set with text_path+stroke
31 | select_font_face(cr, "Sans", Cairo.FONT_SLANT_NORMAL,
32 | Cairo.FONT_WEIGHT_BOLD);
33 | set_font_size(cr, 100.0);
34 | translate(cr, 10.0, 100.0);
35 | text_path(cr, "J");
36 | stroke_preserve(cr);
37 |
38 | # copied and converted
39 | opath = Cairo.convert_cairo_path_data(Cairo.copy_path(cr));
40 |
41 | restore(cr);
42 |
43 | l = 2 # something like a line counter
44 |
45 | # loop over all entries and just print out command and available points
46 | for x in opath
47 | if x.element_type == Cairo.CAIRO_PATH_MOVE_TO
48 | s0 = "moveto"
49 | elseif x.element_type == Cairo.CAIRO_PATH_LINE_TO
50 | s0 = "lineto"
51 | elseif x.element_type == Cairo.CAIRO_PATH_CURVE_TO
52 | s0 = "curveto"
53 | elseif x.element_type == Cairo.CAIRO_PATH_CLOSE_PATH
54 | s0 = "closepath"
55 | end
56 | s1 = repr(x.points)
57 | move_to(cr,100.0,14.0*l)
58 | l += 1
59 | show_text(cr,s0*s1)
60 | end
61 | nothing
62 | end
63 |
64 |
65 | c,cr = common_header();
66 | save(cr);
67 | example_copy_path(cr);
68 | restore(cr);
69 | write_out_picture("sample_copy_path.png",c);
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/samples/sample_copy_path_flat.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 |
4 | c = CairoRGBSurface(256,256)
5 | cr = CairoContext(c)
6 |
7 | save(cr)
8 | set_source_rgb(cr,0.8,0.8,0.8) # light gray
9 | rectangle(cr,0.0,0.0,256.0,256.0) # background
10 | fill(cr)
11 | restore(cr)
12 |
13 | save(cr)
14 |
15 | ## original example, following here
16 | move_to(cr, 16.0, 32.0)
17 | curve_to(cr, 16.0, 16.0, 16.0, 16.0, 32.0, 16.0)
18 |
19 | opath = Cairo.convert_cairo_path_data(Cairo.copy_path(cr))
20 | dx,dy,ex,ey = path_extents(cr)
21 |
22 | fpath = Cairo.convert_cairo_path_data(Cairo.copy_path_flat(cr))
23 |
24 | stroke(cr)
25 |
26 | restore(cr)
27 |
28 | l = 2 # something like a line counter
29 |
30 | # loop over all entries and just print out command and available points
31 | for x in opath
32 | if x.element_type == Cairo.CAIRO_PATH_MOVE_TO
33 | s0 = "moveto"
34 | elseif x.element_type == Cairo.CAIRO_PATH_LINE_TO
35 | s0 = "lineto"
36 | elseif x.element_type == Cairo.CAIRO_PATH_CURVE_TO
37 | s0 = "curveto"
38 | elseif x.element_type == Cairo.CAIRO_PATH_CLOSE_PATH
39 | s0 = "closepath"
40 | end
41 | s1 = repr(x.points)
42 | move_to(cr,10.0,16.0+(14.0*l))
43 | global l += 1
44 | show_text(cr,s0*s1)
45 | end
46 |
47 | l = 2 # something like a line counter
48 |
49 | # loop over all entries and just print out command and available points
50 | for x in fpath
51 | if x.element_type == Cairo.CAIRO_PATH_MOVE_TO
52 | s0 = "moveto"
53 | elseif x.element_type == Cairo.CAIRO_PATH_LINE_TO
54 | s0 = "lineto"
55 | elseif x.element_type == Cairo.CAIRO_PATH_CURVE_TO
56 | s0 = "curveto"
57 | elseif x.element_type == Cairo.CAIRO_PATH_CLOSE_PATH
58 | s0 = "closepath"
59 | end
60 | s1 = repr(x.points)
61 | move_to(cr,10.0,50.0+(14.0*l))
62 | global l += 1
63 | show_text(cr,s0*s1)
64 | end
65 |
66 |
67 | ## mark picture with current date
68 | restore(cr)
69 |
70 | move_to(cr,0.0,12.0)
71 | set_source_rgb(cr, 0,0,0)
72 | show_text(cr,Libc.strftime(time()))
73 |
74 | write_to_png(c,"sample_copy_path_flat.png")
75 |
--------------------------------------------------------------------------------
/test/test_speed.jl:
--------------------------------------------------------------------------------
1 | using Cairo
2 | include("shape_functions.jl")
3 |
4 | function test_all(;tmax = 2.0, save_flag = false)
5 | print("cairo version: ",Cairo.libcairo_version,"\n");
6 | size_surface = [512];#,512,1024]; #three sizes of a surface
7 | paint_width = [0.5,1.0,3.0,5.0];
8 | shapes = [ddots1, ddots2, ddots3, ddots4, ddots5,
9 | rdots1, rdots2, rdots3, rdots4, rdots5, rdots6,
10 | lines0, lines1, lines2, lines3, lines4];
11 | n_elements = [100,300,1000,3000,10000,30000,100000];
12 |
13 | n_tests = length(size_surface) * length(paint_width) * length(shapes);
14 | test_data = zeros(n_tests+1,3 + length(n_elements));
15 | test_data[1,3+(1:length(n_elements))] = n_elements;
16 | i = 1;
17 |
18 | if save_flag && !isdir("test_results")
19 | mkdir("test_results")
20 | end
21 |
22 | for s_size in size_surface
23 | s = Cairo.CairoARGBSurface(s_size,s_size);
24 | c = Cairo.CairoContext(s);
25 | print("Surface Size: ",s_size,"\n")
26 | for w in paint_width
27 | print("Paint Width: ",w,"\n")
28 | for m_index in 1:length(shapes)
29 | test_data[i,1] = s_size;
30 | test_data[i,2] = w;
31 | test_data[i,3] = m_index;
32 | m = shapes[m_index];
33 | for n_index in 1:length(n_elements)
34 | n = n_elements[n_index];
35 | t = @elapsed(m(c,s_size,s_size,w,n));
36 | print(m," ",@sprintf("%6d",n)," elapsed time: ",@sprintf("%f seconds",t),"\n");
37 | test_data[i+1,3+n_index] = t;
38 | if save_flag
39 | write_to_png(s,@sprintf("test_results/test_speed_%2.1f_%02d_%02d.png",w,m_index,n_index));
40 | end
41 | if t > tmax && n_index < length(n_elements)
42 | println("Remaining tests in this sequence skipped")
43 | break
44 | end
45 | end
46 | print("\n")
47 | i += 1;
48 | end
49 | end
50 | end
51 | end
52 |
53 | test_all()
54 |
--------------------------------------------------------------------------------
/samples/sample_meshpattern.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 | ## original example, taken from cairo/test/pattern-mesh.c
14 | function draw(cr, width::Int, height::Int)
15 |
16 | PAT_WIDTH = 170
17 | PAT_HEIGHT = 170
18 | SIZE = PAT_WIDTH
19 | PAD = 2
20 | WIDTH = (PAD + SIZE + PAD)
21 | HEIGHT = WIDTH
22 |
23 | pattern = CairoPatternMesh();
24 |
25 | #cairo_test_paint_checkered (cr); ?
26 |
27 | translate(cr, PAD, PAD);
28 | translate(cr, 10, 10);
29 |
30 | mesh_pattern_begin_patch(pattern);
31 |
32 | mesh_pattern_move_to(pattern, 0, 0);
33 | mesh_pattern_curve_to(pattern, 30, -30, 60, 30, 100, 0);
34 | mesh_pattern_curve_to(pattern, 60, 30, 130, 60, 100, 100);
35 | mesh_pattern_curve_to(pattern, 60, 70, 30, 130, 0, 100);
36 | mesh_pattern_curve_to(pattern, 30, 70, -30, 30, 0, 0);
37 |
38 | mesh_pattern_set_corner_color_rgb(pattern, 0, 1, 0, 0);
39 | mesh_pattern_set_corner_color_rgb(pattern, 1, 0, 1, 0);
40 | mesh_pattern_set_corner_color_rgb(pattern, 2, 0, 0, 1);
41 | mesh_pattern_set_corner_color_rgb(pattern, 3, 1, 1, 0);
42 |
43 | mesh_pattern_end_patch(pattern);
44 |
45 | mesh_pattern_begin_patch(pattern);
46 |
47 | mesh_pattern_move_to(pattern, 50, 50);
48 | mesh_pattern_curve_to(pattern, 80, 20, 110, 80, 150, 50);
49 | mesh_pattern_curve_to(pattern, 110, 80, 180, 110, 150, 150);
50 | mesh_pattern_curve_to(pattern, 110, 120, 80, 180, 50, 150);
51 | mesh_pattern_curve_to(pattern, 80, 120, 20, 80, 50, 50);
52 |
53 | mesh_pattern_set_corner_color_rgba(pattern, 0, 1, 0, 0, 0.3);
54 | mesh_pattern_set_corner_color_rgb(pattern, 1, 0, 1, 0);
55 | mesh_pattern_set_corner_color_rgba(pattern, 2, 0, 0, 1, 0.3);
56 | mesh_pattern_set_corner_color_rgb(pattern, 3, 1, 1, 0);
57 |
58 | mesh_pattern_end_patch(pattern);
59 |
60 | set_source(cr, pattern);
61 | paint(cr);
62 | #pattern_destroy (pattern);
63 |
64 | end
65 |
66 | draw(cr,170,170);
67 |
68 | ## mark picture with current date
69 | restore(cr);
70 | move_to(cr,0.0,12.0);
71 | set_source_rgb(cr, 0,0,0);
72 | show_text(cr,Libc.strftime(time()));
73 | write_to_png(c,"sample_meshpattern.png");
74 |
--------------------------------------------------------------------------------
/samples/sample_operators.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoARGBSurface(512,512);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,512.0,512.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 |
14 | function operator_demo(operator_index)
15 | c = CairoARGBSurface(126,98);
16 | cr = CairoContext(c);
17 | operators = [
18 | (Cairo.OPERATOR_CLEAR,"OPERATOR_CLEAR"),
19 | (Cairo.OPERATOR_SOURCE,"OPERATOR_SOURCE"),
20 | (Cairo.OPERATOR_OVER,"OPERATOR_OVER"),
21 | (Cairo.OPERATOR_IN,"OPERATOR_IN"),
22 | (Cairo.OPERATOR_OUT,"OPERATOR_OUT"),
23 | (Cairo.OPERATOR_ATOP,"OPERATOR_ATOP"),
24 | (Cairo.OPERATOR_DEST,"OPERATOR_DEST"),
25 | (Cairo.OPERATOR_DEST_OVER,"OPERATOR_DEST_OVER"),
26 | (Cairo.OPERATOR_DEST_IN,"OPERATOR_DEST_IN"),
27 | (Cairo.OPERATOR_DEST_OUT,"OPERATOR_DEST_OUT"),
28 | (Cairo.OPERATOR_DEST_ATOP,"OPERATOR_DEST_ATOP"),
29 | (Cairo.OPERATOR_XOR,"OPERATOR_XOR"),
30 | (Cairo.OPERATOR_ADD,"OPERATOR_ADD"),
31 | (Cairo.OPERATOR_SATURATE,"OPERATOR_SATURATE"),
32 | (Cairo.OPERATOR_MULTIPLY,"OPERATOR_MULTIPLY"),
33 | (Cairo.OPERATOR_SCREEN,"OPERATOR_SCREEN"),
34 | (Cairo.OPERATOR_OVERLAY,"OPERATOR_OVERLAY"),
35 | (Cairo.OPERATOR_DARKEN,"OPERATOR_DARKEN"),
36 | (Cairo.OPERATOR_LIGHTEN,"OPERATOR_LIGHTEN")]
37 |
38 | save(cr)
39 | set_source_rgb(cr, 0.9, 0.9, 0.9)
40 | paint(cr);
41 |
42 | save(cr)
43 | scale(cr,6,6)
44 | rectangle(cr, 0, 5, 12, 9)
45 | set_source_rgba(cr, 0.7, 0, 0, 0.8)
46 | fill(cr)
47 |
48 | set_operator(cr, operators[operator_index][1])
49 |
50 | rectangle(cr, 4, 2, 12, 9)
51 | set_source_rgba(cr, 0, 0, 0.9, 0.4)
52 | fill(cr)
53 |
54 | local_operator = get_operator(cr)
55 | restore(cr)
56 |
57 | move_to(cr,0,10)
58 | set_source_rgb(cr, 0,0,0)
59 | show_text(cr,operators[local_operator+1][2])
60 |
61 | restore(cr)
62 | c
63 | end
64 |
65 | for k=1:19
66 | save(cr)
67 | translate(cr,6+(128*mod(k-1,4)),24+(100*div(k-1,4)))
68 | set_source(cr,operator_demo(k))
69 | paint(cr)
70 | restore(cr)
71 | end
72 |
73 | ## mark picture with current date
74 | restore(cr);
75 | move_to(cr,0.0,12.0);
76 | set_source_rgb(cr, 0,0,0);
77 | show_text(cr,Libc.strftime(time()));
78 | write_to_png(c,"sample_operators.png");
79 |
--------------------------------------------------------------------------------
/samples/sample_curve_rectangle.jl:
--------------------------------------------------------------------------------
1 | ## header to provide surface and context
2 | using Cairo
3 | c = CairoRGBSurface(256,256);
4 | cr = CairoContext(c);
5 |
6 | save(cr);
7 | set_source_rgb(cr,0.8,0.8,0.8); # light gray
8 | rectangle(cr,0.0,0.0,256.0,256.0); # background
9 | fill(cr);
10 | restore(cr);
11 |
12 | save(cr);
13 |
14 | ## original example, following here
15 |
16 | # custom shape wrapped in a function
17 | function shape_curve_rectangle(cr::CairoContext,x0::Real,y0::Real,
18 | rect_width::Real, rect_height::Real, radius::Real)
19 |
20 | save(cr);
21 |
22 | x1=x0+rect_width;
23 | y1=y0+rect_height;
24 |
25 | if (rect_width == 0 || rect_height == 0)
26 | return;
27 | end
28 | if (rect_width/2 < radius)
29 | if (rect_height/2 < radius)
30 | move_to(cr, x0, (y0 + y1)/2);
31 | curve_to(cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
32 | curve_to(cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
33 | curve_to(cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
34 | curve_to(cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
35 | else
36 | move_to(cr, x0, y0 + radius);
37 | curve_to(cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
38 | curve_to(cr, x1, y0, x1, y0, x1, y0 + radius);
39 | line_to(cr, x1 , y1 - radius);
40 | curve_to(cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
41 | curve_to(cr, x0, y1, x0, y1, x0, y1- radius);
42 | end
43 |
44 | else
45 | if (rect_height/2 < radius)
46 | move_to(cr, x0, (y0 + y1)/2);
47 | curve_to(cr, x0 , y0, x0 , y0, x0 + radius, y0);
48 | line_to(cr, x1 - radius, y0);
49 | curve_to(cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
50 | curve_to(cr, x1, y1, x1, y1, x1 - radius, y1);
51 | line_to(cr, x0 + radius, y1);
52 | curve_to(cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
53 | else
54 | move_to(cr, x0, y0 + radius);
55 | curve_to(cr, x0 , y0, x0 , y0, x0 + radius, y0);
56 | line_to(cr, x1 - radius, y0);
57 | curve_to(cr, x1, y0, x1, y0, x1, y0 + radius);
58 | line_to(cr, x1 , y1 - radius);
59 | curve_to(cr, x1, y1, x1, y1, x1 - radius, y1);
60 | line_to(cr, x0 + radius, y1);
61 | curve_to(cr, x0, y1, x0, y1, x0, y1- radius);
62 | end
63 | end
64 | close_path(cr);
65 |
66 | set_source_rgb(cr, 0.5, 0.5, 1);
67 | fill_preserve(cr);
68 | set_source_rgba(cr, 0.5, 0, 0, 0.5);
69 | set_line_width(cr, 10.0);
70 | stroke(cr);
71 | restore(cr);
72 | return;
73 | end
74 |
75 | shape_curve_rectangle(cr,25.6,25.6,204.8,204.8,102.4);
76 |
77 | ## mark picture with current date
78 | restore(cr);
79 | move_to(cr,0.0,12.0);
80 | set_source_rgb(cr, 0,0,0);
81 | show_text(cr,Libc.strftime(time()));
82 | write_to_png(c,"sample_curve_rectangle.png");
83 |
--------------------------------------------------------------------------------
/test/test_painting.jl:
--------------------------------------------------------------------------------
1 | # some collection of some painting plus support functions
2 |
3 | """
4 | function ngray(base::Int,digits::Int,value::Int)
5 | Convert a value to a graycode with the given base and digits
6 | """
7 | function ngray(base::Int,digits::Int,value::Int)
8 | baseN = zeros(Int,digits)
9 | gray = zeros(Int,1,digits)
10 |
11 | for i=1:digits
12 | baseN[i] = value % base
13 | value = div(value,base)
14 | end
15 |
16 | shift = 0
17 | for i=digits:-1:1
18 | gray[i] = (baseN[i] + shift) % base
19 | shift = shift + base - gray[i]
20 | end
21 | gray
22 | end
23 |
24 | """
25 | function hilbert_curve(c,x,y,lg,i1,i2)
26 | recursive hilbert curve (2D), appends pairs of x,y to c, lg = dimension/length
27 | """
28 | function hilbert_curve(c,x,y,lg,i1,i2)
29 | if lg == 1
30 | append!(c,[x,y])
31 | else
32 | lg = lg / 2;
33 | hilbert_curve(c,x+i1*lg,y+i1*lg,lg,i1,1-i2);
34 | hilbert_curve(c,x+i2*lg,y+(1-i2)*lg,lg,i1,i2);
35 | hilbert_curve(c,x+(1-i1)*lg,y+(1-i1)*lg,lg,i1,i2);
36 | hilbert_curve(c,x+(1-i2)*lg,y+i2*lg,lg,1-i1,i2);
37 | end
38 | end
39 |
40 |
41 | function hilbert_colored(surf)
42 |
43 | zscale = 8;
44 | n1 = 8;
45 | cr = CairoContext(surf)
46 |
47 | c = Float64[]
48 | hilbert_curve(c,0,0,64,0,0)
49 |
50 | move_to(cr,0,0)
51 |
52 | translate(cr,zscale/2,zscale/2)
53 | scale(cr,zscale,zscale)
54 | set_line_width(cr,zscale/2)
55 | set_line_cap(cr,Cairo.CAIRO_LINE_CAP_SQUARE)
56 |
57 | for k in zip(collect(1:2:(length(c)-2)),1:(length(1:2:(length(c)-2))))
58 | move_to(cr,c[k[1]],c[k[1]+1])
59 | line_to(cr,c[k[1]+2],c[k[1]+3])
60 |
61 | c1 = ngray(n1,3,k[2])
62 | set_source_rgb(cr,c1[1]/float(n1-1),c1[2]/float(n1-1),c1[3]/float(n1-1))
63 | stroke(cr)
64 |
65 | end
66 | end
67 |
68 |
69 | """ function hdraw(s,dim,zscale,linewidth)
70 | draws a hilbert curve with dimension dim (power of 2) and scales the drawing with
71 | zscale.
72 | """
73 | function hdraw(s,dim,zscale,linewidth)
74 |
75 | cr = CairoContext(s)
76 |
77 | set_source_rgba(cr,0.0,0.0,1.0,0.5)
78 |
79 | set_line_width(cr,linewidth)
80 | set_line_cap(cr,Cairo.CAIRO_LINE_CAP_SQUARE)
81 | translate(cr,zscale/2,zscale/2)
82 |
83 | save(cr)
84 | c = Float64[]
85 |
86 | hilbert_curve(c,0,0,dim,0,0)
87 |
88 | scale(cr,zscale,zscale)
89 |
90 | move_to(cr,0,0)
91 | for k=1:div(length(c),2)
92 | line_to(cr,c[(k*2)-1],c[(k*2)])
93 | end
94 |
95 | stroke(cr)
96 | restore(cr)
97 | end
98 |
99 | """
100 | function simple_hist(data)
101 | simple histogram by population count in a Dict
102 | """
103 | function simple_hist(data)
104 | # poor man's hist -> pop count in Dict
105 |
106 | pc = Dict()
107 |
108 | for d in data
109 | if d in keys(pc)
110 | pc[d] += 1
111 | else
112 | pc[d] = 1
113 | end
114 | end
115 | pc
116 | end
117 |
118 | """
119 | function matrix_read(surface)
120 | paint the input surface into a matrix image of the same size to access
121 | the pixels.
122 | """
123 | function matrix_read(surface)
124 | w = Int(surface.width)
125 | h = Int(surface.height)
126 | z = zeros(UInt32,w,h)
127 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
128 |
129 | cr = CairoContext(surf)
130 | set_source_surface(cr,surface,0,0)
131 | paint(cr)
132 |
133 | surf.data
134 | end
135 |
--------------------------------------------------------------------------------
/samples/Samples.md:
--------------------------------------------------------------------------------
1 | ## Sample programs #
2 |
3 | This is roughly a copy of the sample code listed at [cairographics.org/samples](http://www.cairographics.org/samples/).
4 | These examples are C code and assume that you've already set up a Cairo surface and Cairo Context.
5 |
6 | This (samples) directory contains ports of these examples to julia, additionally creating the Surface and Context, adding a time-stamp to the image, and saving the result to a .png file.
7 |
8 | ### arc #
9 |
10 | Example of using the arc path operator [sample_arc.jl](sample_arc.jl).
11 | Note: The path creation starts without current point, otherwise there would be a linesegment first, before starting of the arc.
12 |
13 | 
14 |
15 | ### arc_negative #
16 |
17 | Example of using the arc_negative path operator [sample_arc_negative.jl](sample_arc_negative.jl).
18 |
19 | 
20 |
21 | ### clip #
22 |
23 | A clip path, a circle is defined, then the drawing is done [sample_clip.jl](sample_clip.jl).
24 |
25 | 
26 |
27 | ### clip image #
28 |
29 | Like the previous, but now inserting a picture by reading a .png to an Image Surface. Note: the function is called read_from_png and creates an Image Surface; while in pure C cairo this would be a call of cairo_image_surface_create_from_png [sample_clip_image.jl](sample_clip_image.jl).
30 |
31 | 
32 |
33 | ### curve rectangle #
34 |
35 | Example of more complex path construction, here a rectangle constructed be four bezier segments. Note: Different as in the original example, this here now puts the path construction and stroke and fill operations into a function with coordinates and corner radius as arguments [sample_curve_rectangle.jl](sample_curve_rectangle.jl).
36 |
37 | 
38 |
39 | ### curve to #
40 |
41 | Example of using the curve to path operator, which adds a cubic Bézier spline to the current path [sample_curve_to.jl](sample_curve_to.jl).
42 |
43 | 
44 |
45 | ### dash #
46 |
47 | Example of using a dash line pattern for stroking a path. Note: the julia set_dash uses the length of the dash array to set the ndash internally [sample_dash.jl](sample_dash.jl).
48 |
49 | 
50 |
51 | ### fill and stroke 2 #
52 |
53 | Example of creating a path of non connected areas and fill - while preserving the path - and stroke [sample_fill_and_stroke2.jl](sample_fill_and_stroke2.jl).
54 |
55 | 
56 |
57 | ### fill style #
58 |
59 | Exmaple of using the different fill rules. The same path is filled and stroked [sample_fill_style.jl](sample_fill_style.jl). Note: the julia function is called set_fill_type while the pure C cairo is called with set_fill_rule.
60 |
61 | 
62 |
63 | ### gradient #
64 |
65 | Example of gradients - both linear and radiant - as definition and used for filling [sample_gradient.jl](sample_gradient.jl).
66 |
67 | 
68 |
69 | ### image #
70 |
71 | Example of painting with a Image Surface as source [sample_image.jl](sample_image.jl).
72 |
73 | 
74 |
75 | ### image pattern #
76 |
77 | Example of painting with a Image Surface as pattern [sample_imagepattern.jl] (sample_imagepattern.jl).
78 |
79 | 
80 |
81 | ### multi segment caps #
82 |
83 | Example of stroking a path with non connected segments [sample_multi_segment_caps.jl](sample_multi_segment_caps.jl).
84 |
85 | 
86 |
87 | ### rounded rectangle #
88 |
89 | Example of more path operators, custom shape could be wrapped in a function [sample_rounded_rectangle.jl](sample_rounded_rectangle.jl).
90 |
91 | 
92 |
93 | ### set line caps
94 |
95 | Examples of the line cap settings [sample_set_line_cap.jl](sample_set_line_cap.jl).
96 |
97 | 
98 |
99 | ### set line join
100 |
101 | Examples of the line join settings [sample_set_line_join.jl](sample_set_line_join.jl).
102 |
103 | 
104 |
105 | ### text
106 |
107 | Example of setting text, one with text_show, second with text_path extending the current path and fill and stroke the outline [sample_text.jl](sample_text.jl).
108 |
109 | 
110 |
111 | ### text align center
112 |
113 | Example of getting the text extents, then centering the text around 128.0,128.0 [sample_text_align_center.jl](sample_text_align_center.jl).
114 |
115 | 
116 |
117 | ### text extents
118 |
119 | Example of getting the text extents, plotting the dimension [sample_text_extents.jl](sample_text_extents.jl).
120 |
121 | 
122 |
123 | ### copy path
124 |
125 | Example of getting the path to a single character via text_path, copy_path and convert to an Array of CairoPathEntry [sample_copy_path.jl](sample_copy_path.jl).
126 |
127 | 
128 |
129 | ### image (from stream)
130 |
131 | Example of painting with a Image Surface as source that was created by reading from a stream. The example reads the png data from an inline string [sample_imagestream.jl](sample_imagestream.jl).
132 |
133 | 
134 |
135 |
136 | ## More Samples for Testing
137 |
138 | The following examples have been created to have more coverage in testing (all samples_X are executed).
139 |
140 | ### alpha paint
141 |
142 | Example to use set_source with different input (for multiple dispatch). For better viewing the background is not plain gray anymore, but has structure
143 | [sample_alpha_paint.jl](sample_alpha_paint.jl).
144 |
145 | 
146 |
147 | ### image copy
148 |
149 | Example to use copy(Image). You need to take care about coordinate transformation, as the copy is inplace [sample_image_copy.jl](sample_image_copy.jl).
150 |
151 | 
152 |
153 | ### operators
154 |
155 | Example to use the defined operators for set_operator with two filled rectangles [sample_operators.jl](sample_operators.jl).
156 |
157 | 
158 |
159 | ### set dash
160 |
161 | Example to use the set line type function (input to set_dash) [sample_set_dash.jl](sample_set_dash.jl).
162 |
163 | 
164 |
165 | ### copy path flat
166 |
167 | [sample_copy_path_flat.jl](sample_copy_path_flat.jl).
168 |
169 | 
170 |
171 | ### pango text
172 |
173 | Example of a few (but not all) pango text formating options [sample_pango_text.jl](sample_pango_text.jl).
174 |
175 | 
176 |
177 | ### mesh pattern
178 |
179 | Example of creating and using a mesh pattern [sample_meshpattern.jl](sample_meshpattern.jl).
180 | Mesh patterns are tensor-product patch meshes (type 7 shadings in PDF), read more in [http://www.cairographics.org/manual/cairo-cairo-pattern-t.html#cairo-pattern-create-mesh] or [http://www.w3.org/TR/SVG2/pservers.html#MeshGradients].
181 |
182 | 
183 |
184 | ### Recording and Scripting Surfaces
185 |
186 | Example of using Recording surface, simple copy, then scaled and offset.
187 |
188 | 
189 | 
190 |
191 | Example of writing to script, put script text into frame.
192 |
193 | 
194 |
195 | ### current point
196 |
197 | Example of using current point
198 |
199 | 
--------------------------------------------------------------------------------
/test/runtests.jl:
--------------------------------------------------------------------------------
1 | using Cairo
2 | using Colors
3 | import Base.Sys
4 |
5 | import Base.show
6 |
7 | using Test
8 |
9 | # Test that an the CairoSurface holds a reference to the passed IOBuffer
10 | @testset "IOBuffer Rooting " begin
11 | CairoSVGSurface(IOBuffer(), 200, 110)
12 | GC.gc()
13 | GC.gc()
14 | end
15 |
16 | # Image Surface
17 | @testset "Image Surface " begin
18 |
19 | surf = CairoImageSurface(100, 200, Cairo.FORMAT_ARGB32)
20 | @test width(surf) == 100
21 | @test height(surf) == 200
22 | ctx = CairoContext(surf)
23 | @test width(ctx) == 100
24 | @test height(ctx) == 200
25 |
26 | surf = CairoImageSurface(fill(RGB24(0), 10, 10))
27 | @test Cairo.format(surf) == RGB24
28 | io = IOBuffer()
29 | show(io, MIME("image/png"), surf)
30 |
31 | seek(io,0)
32 | str_data = Vector{UInt8}(read(io))
33 |
34 | @test length(str_data) > 8 && str_data[1:8] == [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]
35 | surf = CairoImageSurface(fill(ARGB32(0), 10, 10))
36 | @test Cairo.format(surf) == ARGB32
37 |
38 | end
39 |
40 | @testset "Conversions " begin
41 |
42 | include("shape_functions.jl")
43 | include("test_stream.jl")
44 |
45 | function test_pattern_get_surface()
46 | # test getting a surface from a surface pattern
47 | surf = CairoImageSurface(100, 200, Cairo.FORMAT_ARGB32)
48 | ctx = CairoContext(surf)
49 | Cairo.push_group(ctx)
50 | pattern = Cairo.pop_group(ctx)
51 | group_surf = Cairo.pattern_get_surface(pattern)
52 | @test group_surf.width == 100
53 | @test group_surf.height == 200
54 |
55 | # test that surfaces can't be gotten from non-surface patterns
56 | pattern = Cairo.pattern_create_linear(0, 0, 100, 200)
57 | @test_throws ErrorException Cairo.pattern_get_surface(pattern)
58 | end
59 |
60 | test_pattern_get_surface()
61 |
62 | # Test creating a CairoContext from a cairo_t pointer
63 | surf = CairoImageSurface(fill(ARGB32(0), 10, 10))
64 | ctx_ptr = ccall((:cairo_create, Cairo.libcairo),Ptr{Nothing}, (Ptr{Nothing}, ), surf.ptr)
65 | ctx = CairoContext(ctx_ptr)
66 | ccall((:cairo_destroy,Cairo.libcairo),Nothing, (Ptr{Nothing}, ), ctx_ptr)
67 |
68 | @test isa(ctx, CairoContext)
69 | end
70 |
71 | @testset "TexLexer " begin
72 | include("tex.jl")
73 | end
74 |
75 | # Run all the samples -> success, if output file exits
76 | @testset "Samples " begin
77 |
78 | samples_dir_path = joinpath(dirname(dirname(@__FILE__)), "samples")
79 | samples_files = filter(str->endswith(str,".jl"), readdir(samples_dir_path))
80 | # filter known >= 1.12 -> sample_meshpattern.jl
81 | if Cairo.libcairo_version < v"1.12.0"
82 | files_to_exclude = ["sample_meshpattern.jl","sample_record0.jl","sample_record1.jl","sample_script0.jl"]
83 | samples_files = setdiff(samples_files, files_to_exclude)
84 | end
85 |
86 | @testset "sample: $test_file_name" for test_file_name in samples_files
87 | # Run each sample script in a separate module to avoid pollution
88 | s = Symbol(test_file_name)
89 | mod = @eval(Main, module $s end)
90 | @eval mod include($(joinpath(samples_dir_path, test_file_name)))
91 |
92 | output_png_name = replace(test_file_name,".jl" => ".png")
93 | @test isfile(output_png_name)
94 | rm(output_png_name)
95 | end
96 | end
97 |
98 | # Run some painting, check the colored pixels by counting them
99 | @testset "Bitmap Painting" begin
100 |
101 | include("test_painting.jl")
102 |
103 | # fill all
104 | z = zeros(UInt32,512,512);
105 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
106 | # fills a 512x512 pixel area with blue,0.5 by using a hilbert curve of
107 | # dimension 64 (scaled by 8 -> 512) and a linewidth of 8
108 | hdraw(surf,64,8,8)
109 |
110 | d = simple_hist(surf.data)
111 |
112 | @test length(d) == 1
113 | @test collect(keys(d))[1] == 0x80000080
114 |
115 | # fill 1/4 (upper quarter)
116 | z = zeros(UInt32,512,512);
117 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
118 | # fills a 256x256 pixel area with blue,0.5 by using a hilbert curve of
119 | # dimension 32 (scaled by 8 -> 256) and a linewidth of 8
120 | hdraw(surf,32,8,8)
121 |
122 | d = simple_hist(surf.data)
123 |
124 | @test length(d) == 2
125 | @test d[0x80000080] == 256*256
126 |
127 | # fill ~1/2 full,
128 | z = zeros(UInt32,512,512);
129 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
130 | # fills a 512x512 pixel area with blue,0.5 by using a hilbert curve of
131 | # dimension 64 (scaled by 8 -> 512) and a linewidth of 4 -> 1/4 of pixels -16
132 | hdraw(surf,64,8,4)
133 |
134 | d = simple_hist(surf.data)
135 |
136 | @test length(d) == 2
137 | @test d[0x80000080] == ((512*256)-16)
138 | end
139 |
140 | # vector surfaces
141 | @testset "Vector Surfaces" begin
142 |
143 | output_file_name = "a.svg"
144 | surf = CairoSVGSurface(output_file_name,512,512)
145 | hdraw(surf,64,8,4)
146 | finish(surf)
147 |
148 | @test isfile(output_file_name)
149 | rm(output_file_name)
150 |
151 | io = IOBuffer()
152 | surf = CairoSVGSurface(io,512,512)
153 | hdraw(surf,64,8,4)
154 | finish(surf)
155 |
156 | seek(io,0)
157 | str_data = Vector{UInt8}(read(io))
158 |
159 | @test length(str_data) > 31000 && str_data[1:13] == [0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e]
160 |
161 | output_file_name = "a.pdf"
162 | surf = CairoPDFSurface(output_file_name,512,512)
163 | hdraw(surf,64,8,4)
164 | finish(surf)
165 |
166 | @test isfile(output_file_name)
167 | rm(output_file_name)
168 |
169 | io = IOBuffer()
170 | surf = CairoPDFSurface(io,512,512)
171 | hdraw(surf,64,8,4)
172 | finish(surf)
173 |
174 | seek(io,0)
175 | str_data = Vector{UInt8}(read(io))
176 |
177 | @test length(str_data) > 3000 && str_data[1:7] == [0x25,0x50,0x44,0x46,0x2d,0x31,0x2e]
178 |
179 | output_file_name = "a.eps"
180 | surf = CairoEPSSurface(output_file_name,512,512)
181 | hdraw(surf,64,8,4)
182 | finish(surf)
183 |
184 | @test isfile(output_file_name)
185 | rm(output_file_name)
186 |
187 | io = IOBuffer()
188 | surf = CairoEPSSurface(io,512,512)
189 | hdraw(surf,64,8,4)
190 | finish(surf)
191 |
192 | seek(io,0)
193 | str_data = Vector{UInt8}(read(io))
194 |
195 | @test length(str_data) > 3000 && str_data[1:10] == [0x25,0x21,0x50,0x53,0x2d,0x41,0x64,0x6f,0x62,0x65]
196 |
197 | output_file_name = "a.ps"
198 | surf = CairoPSSurface(output_file_name,512,512)
199 | hdraw(surf,64,8,4)
200 | finish(surf)
201 |
202 | @test isfile(output_file_name)
203 | rm(output_file_name)
204 |
205 | io = IOBuffer()
206 | surf = CairoPSSurface(io,512,512)
207 | hdraw(surf,64,8,4)
208 | finish(surf)
209 |
210 | seek(io,0)
211 | str_data = Vector{UInt8}(read(io))
212 |
213 | @test length(str_data) > 3000 && str_data[1:10] == [0x25,0x21,0x50,0x53,0x2d,0x41,0x64,0x6f,0x62,0x65]
214 |
215 | if Cairo.libcairo_version >= v"1.12.0"
216 |
217 | # just write to surface and test for content
218 | io = IOBuffer()
219 | surf = CairoScriptSurface(io,512,512)
220 | hdraw(surf,64,8,4)
221 | finish(surf)
222 |
223 | seek(io,0)
224 | str_data = Vector{UInt8}(read(io))
225 |
226 | @test length(str_data) > 3000 && str_data[1:10] == [0x25,0x21,0x43,0x61,0x69,0x72,0x6f,0x53,0x63,0x72]
227 |
228 | # create_for_target
229 | z = zeros(UInt32,512,512);
230 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
231 |
232 | io = IOBuffer()
233 | scsurf = CairoScriptSurface(io,surf)
234 | hdraw(scsurf,64,8,8)
235 | finish(surf)
236 | destroy(scsurf)
237 |
238 | seek(io,0)
239 | str_data = Vector{UInt8}(read(io))
240 |
241 | @test length(str_data) > 3000 && str_data[1:10] == [0x25,0x21,0x43,0x61,0x69,0x72,0x6f,0x53,0x63,0x72]
242 |
243 | d = simple_hist(surf.data)
244 |
245 | @test length(d) == 1
246 | @test collect(keys(d))[1] == 0x80000080
247 |
248 |
249 | end
250 | end
251 |
252 | # pixel/bitmap surfaces
253 | @testset "Bitmap Surfaces" begin
254 |
255 | z = zeros(UInt32,512,512)
256 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
257 |
258 | hilbert_colored(surf)
259 | d1 = matrix_read(surf)
260 | d = simple_hist(d1)
261 |
262 | @test length(d) == 513 # 512 colors and empty background
263 |
264 | surf = CairoARGBSurface(z)
265 |
266 | hilbert_colored(surf)
267 | d1 = matrix_read(surf)
268 | d = simple_hist(d1)
269 |
270 | @test length(d) == 513
271 |
272 | surf = CairoRGBSurface(z)
273 |
274 | hilbert_colored(surf)
275 | d1 = matrix_read(surf)
276 | d = simple_hist(d1)
277 |
278 | @test length(d) == 512 # black is included
279 | end
280 |
281 | @testset "Assert/Status " begin
282 |
283 | z = zeros(UInt32,512,512);
284 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
285 |
286 | @test Cairo.status(surf) == 0
287 |
288 | pa = surf.ptr
289 | surf.ptr = C_NULL
290 |
291 | @test destroy(surf) == nothing
292 |
293 | surf.ptr = pa
294 | cr = Cairo.CairoContext(surf)
295 |
296 | pa = cr.ptr
297 | cr.ptr = C_NULL
298 |
299 | @test destroy(cr) == nothing
300 |
301 | @test push_group(cr) == nothing
302 | @test pop_group(cr) == nothing
303 |
304 | @test_throws AssertionError Cairo.align2offset("to")
305 |
306 | @test_throws ErrorException Cairo.set_line_type(cr,"nondef")
307 | end
308 |
309 | @testset "reset_transform" begin
310 | using Graphics
311 |
312 | z = zeros(UInt32,512,512);
313 | surf = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
314 |
315 | @test Cairo.status(surf) == 0
316 |
317 | pa = surf.ptr
318 | surf.ptr = C_NULL
319 |
320 | @test destroy(surf) == nothing
321 |
322 | surf.ptr = pa
323 | cr = Cairo.CairoContext(surf)
324 |
325 | m1 = CairoMatrix(1, 0, 0, 1, 0, 0)
326 | m2 = CairoMatrix(1.0,2.0,2.0,1.0,0.,0.)
327 | m = get_matrix(cr)
328 | @test m == m1
329 | set_matrix(cr, m2)
330 | @test get_matrix(cr) == m2
331 | Graphics.reset_transform(cr)
332 | @test get_matrix(cr) == m1
333 | @test destroy(cr) == nothing
334 | end
335 |
336 | nothing
337 |
--------------------------------------------------------------------------------
/test/shape_functions.jl:
--------------------------------------------------------------------------------
1 | using Cairo
2 | using Random
3 |
4 | # shape functions,
5 |
6 |
7 | function randpos(n,w::Real,h::Real)
8 | @static if VERSION >= v"0.7"
9 | Random.seed!(141413)
10 | else
11 | srand(141413)
12 | end
13 | px = rand(n)*w
14 | py = rand(n)*h
15 | return (px,py)
16 | end
17 |
18 | function clear_bg(c::CairoContext,w::Real,h::Real)
19 | save(c)
20 | set_source_rgb(c,1.0,1.0,1.0)
21 | rectangle(c, 0,0,w,h)
22 | paint(c)
23 | restore(c)
24 | end
25 |
26 | # ddotsx: fill random dots with different methods, disc only (no ring)
27 | function ddots1(cr::CairoContext, rect_width::Real, rect_height::Real, radius::Real, n::Int)
28 |
29 | clear_bg(cr,rect_width,rect_height)
30 | px,py = randpos(n,rect_width,rect_height)
31 |
32 | new_path(cr)
33 | for i=1:n
34 | move_to(cr,px[i],py[i])
35 | rel_move_to(cr,radius,0)
36 | arc(cr, px[i], py[i], radius, 0, 2*pi)
37 | end
38 | close_path(cr)
39 |
40 | set_source_rgb(cr, 0, 0, 1.0)
41 | fill(cr)
42 | end
43 |
44 | function ddots2(cr::CairoContext, rect_width::Real, rect_height::Real, radius::Real, n::Int)
45 |
46 | clear_bg(cr,rect_width,rect_height)
47 | px,py = randpos(n,rect_width,rect_height)
48 |
49 | for i=1:n
50 | new_path(cr)
51 | move_to(cr,px[i],py[i])
52 | rel_move_to(cr,radius,0)
53 | arc(cr, px[i], py[i], radius, 0, 2*pi)
54 | close_path(cr)
55 | set_source_rgb(cr, 0, 0, 1.0)
56 | fill(cr)
57 | end
58 | end
59 |
60 |
61 | function ddots3(cr::CairoContext, rect_width::Real, rect_height::Real, radius::Real, n::Int)
62 |
63 | clear_bg(cr,rect_width,rect_height)
64 | px,py = randpos(n,rect_width,rect_height)
65 |
66 | new_path(cr)
67 |
68 | set_source_rgb(cr, 0, 0, 1.0)
69 | set_line_cap(cr,Cairo.CAIRO_LINE_CAP_ROUND)
70 | set_line_width(cr,radius*2.0)
71 |
72 | for i=1:n
73 | move_to(cr,px[i],py[i])
74 | rel_line_to(cr,0,0)
75 | stroke(cr)
76 | end
77 |
78 | close_path(cr)
79 |
80 | end
81 |
82 | function ddots4(cr::CairoContext,
83 | rect_width::Real, rect_height::Real, radius::Real, n::Int)
84 |
85 | clear_bg(cr,rect_width,rect_height)
86 | px,py = randpos(n,rect_width,rect_height)
87 |
88 | cc = radius + 1
89 |
90 | rectangle(cr,0,0,2*cc,2*cc)
91 | clip(cr)
92 | push_group(cr)
93 | arc(cr,radius,radius,radius,0,2*pi)
94 | set_source_rgb(cr,0,0,1.0)
95 | fill(cr)
96 | p = pop_group(cr)
97 | reset_clip(cr)
98 |
99 | for i=1:n
100 | save(cr)
101 | translate(cr,px[i]-cc,py[i]-cc)
102 | set_source(cr,p)
103 | paint(cr)
104 | restore(cr)
105 | end
106 | end
107 |
108 | function ddots5(cr::CairoContext,
109 | rect_width::Real, rect_height::Real, radius::Real, n::Int)
110 |
111 | clear_bg(cr,rect_width,rect_height)
112 | px,py = randpos(n,rect_width,rect_height)
113 |
114 | cc = radius + 1
115 |
116 | s1 = Cairo.CairoARGBSurface(cc*2,cc*2)
117 | c1 = Cairo.CairoContext(s1)
118 | rectangle(c1,0,0,2*cc,2*cc)
119 | set_source_rgba(c1,0,0,0,0)
120 | paint(c1)
121 | new_path(c1)
122 | arc(c1,radius,radius,radius,0,2*pi)
123 | set_source_rgb(c1,0,0,1.0)
124 | fill(c1)
125 |
126 | p = Cairo.CairoPattern(s1)
127 |
128 | for i=1:n
129 | save(cr)
130 | translate(cr,px[i]-cc,py[i]-cc)
131 | set_source(cr,p)
132 | paint(cr)
133 | restore(cr)
134 | end
135 | end
136 |
137 | # rdotsx: fill random dots with different methods
138 | function rdots1(cr::CairoContext, rect_width::Real, rect_height::Real, radius::Real, n::Int)
139 |
140 | clear_bg(cr,rect_width,rect_height)
141 | px,py = randpos(n,rect_width,rect_height)
142 |
143 | new_path(cr)
144 | for i=1:n
145 | move_to(cr,px[i],py[i])
146 | rel_move_to(cr,radius,0)
147 | arc(cr, px[i], py[i], radius, 0, 2*pi)
148 | end
149 | close_path(cr)
150 |
151 | set_source_rgb(cr, 0, 0, 1.0)
152 | fill_preserve(cr)
153 | set_line_width(cr,1.0)
154 | set_source_rgb(cr, 0, 0, 0)
155 | stroke(cr)
156 | end
157 |
158 | function rdots2(cr::CairoContext, rect_width::Real, rect_height::Real, radius::Real, n::Int)
159 |
160 | clear_bg(cr,rect_width,rect_height)
161 | px,py = randpos(n,rect_width,rect_height)
162 |
163 | for i=1:n
164 | new_path(cr)
165 | move_to(cr,px[i],py[i])
166 | rel_move_to(cr,radius,0)
167 | arc(cr, px[i], py[i], radius, 0, 2*pi)
168 | close_path(cr)
169 | set_source_rgb(cr, 0, 0, 1.0)
170 | fill_preserve(cr)
171 | set_line_width(cr,1.0)
172 | set_source_rgb(cr, 0, 0, 0)
173 | stroke(cr)
174 | end
175 | end
176 |
177 |
178 | function rdots3(cr::CairoContext, rect_width::Real, rect_height::Real, radius::Real, n::Int)
179 |
180 | clear_bg(cr,rect_width,rect_height)
181 | px,py = randpos(n,rect_width,rect_height)
182 |
183 | new_path(cr)
184 |
185 | set_line_cap(cr,Cairo.CAIRO_LINE_CAP_ROUND)
186 |
187 | set_source_rgb(cr, 0, 0, 0)
188 | set_line_width(cr,radius*2 + 2.0)
189 | for i=1:n
190 | move_to(cr,px[i],py[i])
191 | rel_line_to(cr,0,0)
192 | stroke(cr)
193 | end
194 |
195 | set_source_rgb(cr, 0, 0, 1.0)
196 | set_line_width(cr,radius*2)
197 | for i=1:n
198 | move_to(cr,px[i],py[i])
199 | rel_line_to(cr,0,0)
200 | stroke(cr)
201 | end
202 |
203 |
204 | end
205 |
206 | function rdots4(cr::CairoContext,
207 | rect_width::Real, rect_height::Real, radius::Real, n::Int)
208 |
209 | clear_bg(cr,rect_width,rect_height)
210 | px,py = randpos(n,rect_width,rect_height)
211 |
212 | cc = radius + 3.0
213 |
214 | rectangle(cr,0,0,2*cc,2*cc)
215 | clip(cr)
216 | push_group(cr)
217 | arc(cr,radius,radius,radius,0,2*pi)
218 | set_source_rgb(cr,0,0,1.0)
219 | fill_preserve(cr)
220 | set_source_rgb(cr,0,0,0)
221 | set_line_width(cr,1.0)
222 | stroke(cr)
223 | p = pop_group(cr)
224 | reset_clip(cr)
225 |
226 | for i=1:n
227 | save(cr)
228 | translate(cr,px[i]-cc,py[i]-cc)
229 | set_source(cr,p)
230 | paint(cr)
231 | restore(cr)
232 | end
233 | end
234 |
235 | function rdots5(cr::CairoContext,
236 | rect_width::Real, rect_height::Real, radius::Real, n::Int)
237 |
238 | clear_bg(cr,rect_width,rect_height)
239 | px,py = randpos(n,rect_width,rect_height)
240 |
241 | cc = radius + 3.0
242 |
243 | s1 = Cairo.CairoARGBSurface(cc*2,cc*2)
244 | c1 = Cairo.CairoContext(s1)
245 | rectangle(c1,0,0,2*cc,2*cc)
246 | set_source_rgba(c1,0,0,0,0)
247 | paint(c1)
248 | new_path(c1)
249 | arc(c1,radius+1,radius+1,radius,0,2*pi)
250 | set_source_rgb(c1,0,0,1.0)
251 | fill_preserve(c1)
252 | set_source_rgb(c1,0,0,0)
253 | set_line_width(c1,1.0)
254 | stroke(c1)
255 |
256 | p = Cairo.CairoPattern(s1)
257 |
258 | for i=1:n
259 | save(cr)
260 | translate(cr,px[i]-cc,py[i]-cc)
261 | set_source(cr,p)
262 | paint(cr)
263 | restore(cr)
264 | end
265 | end
266 |
267 | # alpha transparency using paint_with_alpha
268 | function rdots6(cr::CairoContext,
269 | rect_width::Real, rect_height::Real, radius::Real, n::Int)
270 |
271 | clear_bg(cr,rect_width,rect_height)
272 | px,py = randpos(n,rect_width,rect_height)
273 |
274 | cc = radius + 3.0
275 |
276 | s1 = Cairo.CairoARGBSurface(cc*2,cc*2)
277 | c1 = Cairo.CairoContext(s1)
278 | rectangle(c1,0,0,2*cc,2*cc)
279 | set_source_rgba(c1,0,0,0,0)
280 | paint_with_alpha(c1, 0.5)
281 | new_path(c1)
282 | arc(c1,radius+1,radius+1,radius,0,2*pi)
283 | set_source_rgb(c1,0,0,1.0)
284 | fill_preserve(c1)
285 | set_source_rgb(c1,0,0,0)
286 | set_line_width(c1,1.0)
287 | stroke(c1)
288 |
289 | p = Cairo.CairoPattern(s1)
290 |
291 | for i=1:n
292 | save(cr)
293 | translate(cr,px[i]-cc,py[i]-cc)
294 | set_source(cr,p)
295 | paint_with_alpha(cr, 1 - i/n)
296 | restore(cr)
297 | end
298 | end
299 |
300 | # lines0, random x,y lines
301 | function lines0(cr::CairoContext, rect_width::Real, rect_height::Real, width::Real, n::Int)
302 |
303 | clear_bg(cr,rect_width,rect_height)
304 | px,py = randpos(n,rect_width,rect_height)
305 |
306 | new_path(cr)
307 |
308 | set_source_rgb(cr, 0, 0, 1.0)
309 | set_line_width(cr,width)
310 |
311 | new_path(cr)
312 | move_to(cr,px[1],py[1])
313 | for i=2:n
314 | line_to(cr,px[i],py[i])
315 | end
316 | stroke(cr)
317 | end
318 |
319 | # lines1, x sorted, line a plot
320 | function lines1(cr::CairoContext, rect_width::Real, rect_height::Real, width::Real, n::Int)
321 |
322 | clear_bg(cr,rect_width,rect_height)
323 | px,py = randpos(n,rect_width,rect_height)
324 |
325 | px = sort(px)
326 |
327 | set_source_rgb(cr, 0, 0, 1.0)
328 | set_line_width(cr,width)
329 |
330 | new_path(cr)
331 | move_to(cr,px[1],py[1])
332 | for i=2:n
333 | line_to(cr,px[i],py[i])
334 | end
335 | stroke(cr)
336 | end
337 |
338 | # lines2, x sorted, independent lines per coord
339 | function lines2(cr::CairoContext, rect_width::Real, rect_height::Real, width::Real, n::Int)
340 |
341 | clear_bg(cr,rect_width,rect_height)
342 | px,py = randpos(n,rect_width,rect_height)
343 |
344 | px = sort(px)
345 |
346 | set_source_rgb(cr, 0, 0, 1.0)
347 | set_line_width(cr,width)
348 |
349 | new_path(cr)
350 | for i=1:n-1
351 | move_to(cr,px[i],py[i])
352 | line_to(cr,px[i+1],py[i+1])
353 | stroke(cr)
354 | end
355 | end
356 |
357 | # lines3, x sorted, in clusters of 100
358 | function lines3(cr::CairoContext, rect_width::Real, rect_height::Real, width::Real, n::Int)
359 |
360 | clear_bg(cr,rect_width,rect_height)
361 | px,py = randpos(n,rect_width,rect_height)
362 |
363 | px = sort(px)
364 |
365 | set_source_rgb(cr, 0, 0, 1.0)
366 | set_line_width(cr,width)
367 | new_path(cr)
368 | for c = 1:100:n
369 | move_to(cr,px[c],py[c])
370 | for i=c:min(c+100,n)
371 | line_to(cr,px[i],py[i])
372 | end
373 | stroke(cr)
374 | end
375 | end
376 |
377 | # lines4, x sorted, in clusters of 1000
378 | function lines4(cr::CairoContext, rect_width::Real, rect_height::Real, width::Real, n::Int)
379 |
380 | clear_bg(cr,rect_width,rect_height)
381 | px,py = randpos(n,rect_width,rect_height)
382 |
383 | px = sort(px)
384 |
385 | set_source_rgb(cr, 0, 0, 1.0)
386 | set_line_width(cr,width)
387 | new_path(cr)
388 | for c = 1:1000:n
389 | move_to(cr,px[c],py[c])
390 | for i=c:min(c+1000,n)
391 | line_to(cr,px[i],py[i])
392 | end
393 | stroke(cr)
394 | end
395 | end
396 |
--------------------------------------------------------------------------------
/src/constants.jl:
--------------------------------------------------------------------------------
1 | ## Cairo Constants ##
2 |
3 | # deprecated exports---do not add more!
4 | export CAIRO_FORMAT_ARGB32,
5 | CAIRO_FORMAT_RGB24,
6 | CAIRO_FORMAT_A8,
7 | CAIRO_FORMAT_A1,
8 | CAIRO_FORMAT_RGB16_565,
9 | CAIRO_CONTENT_COLOR,
10 | CAIRO_CONTENT_ALPHA,
11 | CAIRO_CONTENT_COLOR_ALPHA,
12 | CAIRO_FILTER_FAST,
13 | CAIRO_FILTER_GOOD,
14 | CAIRO_FILTER_BEST,
15 | CAIRO_FILTER_NEAREST,
16 | CAIRO_FILTER_BILINEAR,
17 | CAIRO_FILTER_GAUSSIAN
18 |
19 | const format_t = Int32
20 | const FORMAT_INVALID = Int32(-1)
21 | const FORMAT_ARGB32 = Int32(0)
22 | const FORMAT_RGB24 = Int32(1)
23 | const FORMAT_A8 = Int32(2)
24 | const FORMAT_A1 = Int32(3)
25 | const FORMAT_RGB16_565 = Int32(4)
26 | const FORMAT_RGB30 = Int32(5)
27 |
28 | const status_t = Int32
29 | const STATUS_SUCCESS = Int32(0)
30 | const STATUS_NO_MEMORY = Int32(1)
31 | const STATUS_INVALID_RESTORE = Int32(2)
32 | const STATUS_INVALID_POP_GROUP = Int32(3)
33 | const STATUS_NO_CURRENT_POINT = Int32(4)
34 | const STATUS_INVALID_MATRIX = Int32(5)
35 | const STATUS_INVALID_STATUS = Int32(6)
36 | const STATUS_NULL_POINTER = Int32(7)
37 | const STATUS_INVALID_STRING = Int32(8)
38 | const STATUS_INVALID_PATH_DATA = Int32(9)
39 | const STATUS_READ_ERROR = Int32(10)
40 | const STATUS_WRITE_ERROR = Int32(11)
41 | const STATUS_SURFACE_FINISHED = Int32(12)
42 | const STATUS_SURFACE_TYPE_MISMATCH = Int32(13)
43 | const STATUS_PATTERN_TYPE_MISMATCH = Int32(14)
44 | const STATUS_INVALID_CONTENT = Int32(15)
45 | const STATUS_INVALID_FORMAT = Int32(16)
46 | const STATUS_INVALID_VISUAL = Int32(17)
47 | const STATUS_FILE_NOT_FOUND = Int32(17)
48 | const STATUS_INVALID_DASH = Int32(18)
49 | const STATUS_INVALID_DSC_COMMENT = Int32(19)
50 | const STATUS_INVALID_INDEX = Int32(20)
51 | const STATUS_CLIP_NOT_REPRESENTABLE = Int32(21)
52 | const STATUS_TEMP_FILE_ERROR = Int32(22)
53 | const STATUS_INVALID_STRIDE = Int32(23)
54 | const STATUS_FONT_TYPE_MISMATCH = Int32(24)
55 | const STATUS_USER_FONT_IMMUTABLE = Int32(25)
56 | const STATUS_USER_FONT_ERROR = Int32(26)
57 | const STATUS_NEGATIVE_COUNT = Int32(27)
58 | const STATUS_INVALID_CLUSTERS = Int32(28)
59 | const STATUS_INVALID_SLANT = Int32(29)
60 | const STATUS_INVALID_WEIGHT = Int32(30)
61 | const STATUS_INVALID_SIZE = Int32(31)
62 | const STATUS_USER_FONT_NOT_IMPLEMENTED = Int32(32)
63 | const STATUS_DEVICE_TYPE_MISMATCH = Int32(33)
64 | const STATUS_DEVICE_ERROR = Int32(34)
65 | const STATUS_INVALID_MESH_CONSTRUCTION = Int32(35)
66 | const STATUS_DEVICE_FINISHED = Int32(36)
67 | const STATUS_LAST_STATUS = Int32(37)
68 |
69 | const surface_t = Int32
70 | const CAIRO_SURFACE_TYPE_IMAGE = Int32(0)
71 | const CAIRO_SURFACE_TYPE_PDF, = Int32(1)
72 | const CAIRO_SURFACE_TYPE_PS, = Int32(2)
73 | const CAIRO_SURFACE_TYPE_XLIB, = Int32(3)
74 | const CAIRO_SURFACE_TYPE_XCB, = Int32(4)
75 | const CAIRO_SURFACE_TYPE_GLITZ, = Int32(5)
76 | const CAIRO_SURFACE_TYPE_QUARTZ, = Int32(6)
77 | const CAIRO_SURFACE_TYPE_WIN32, = Int32(7)
78 | const CAIRO_SURFACE_TYPE_BEOS, = Int32(8)
79 | const CAIRO_SURFACE_TYPE_DIRECTFB, = Int32(9)
80 | const CAIRO_SURFACE_TYPE_SVG, = Int32(10)
81 | const CAIRO_SURFACE_TYPE_OS2, = Int32(11)
82 | const CAIRO_SURFACE_TYPE_WIN32_PRINTING, = Int32(12)
83 | const CAIRO_SURFACE_TYPE_QUARTZ_IMAGE, = Int32(13)
84 | const CAIRO_SURFACE_TYPE_SCRIPT, = Int32(14)
85 | const CAIRO_SURFACE_TYPE_QT, = Int32(15)
86 | const CAIRO_SURFACE_TYPE_RECORDING, = Int32(16)
87 | const CAIRO_SURFACE_TYPE_VG, = Int32(17)
88 | const CAIRO_SURFACE_TYPE_GL, = Int32(18)
89 | const CAIRO_SURFACE_TYPE_DRM, = Int32(19)
90 | const CAIRO_SURFACE_TYPE_TEE, = Int32(20)
91 | const CAIRO_SURFACE_TYPE_XML, = Int32(21)
92 | const CAIRO_SURFACE_TYPE_SKIA, = Int32(22)
93 | const CAIRO_SURFACE_TYPE_SUBSURFACE, = Int32(23)
94 | const CAIRO_SURFACE_TYPE_COGL = Int32(24)
95 |
96 |
97 | const font_slant_t = Int32
98 | const FONT_SLANT_NORMAL = Int32(0)
99 | const FONT_SLANT_ITALIC = Int32(1)
100 | const FONT_SLANT_OBLIQUE = Int32(2)
101 |
102 | const font_weight_t = Int32
103 | const FONT_WEIGHT_NORMAL = Int32(0)
104 | const FONT_WEIGHT_BOLD = Int32(1)
105 |
106 | const CONTENT_COLOR = Int32(0x1000)
107 | const CONTENT_ALPHA = Int32(0x2000)
108 | const CONTENT_COLOR_ALPHA = Int32(0x3000)
109 |
110 | const FILTER_FAST = 0
111 | const FILTER_GOOD = 1
112 | const FILTER_BEST = 2
113 | const FILTER_NEAREST = 3
114 | const FILTER_BILINEAR = 4
115 | const FILTER_GAUSSIAN = 5
116 |
117 | const EXTEND_NONE = 0
118 | const EXTEND_REPEAT = 1
119 | const EXTEND_REFLECT = 2
120 | const EXTEND_PAD = 3
121 |
122 | const ANTIALIAS_DEFAULT = 0
123 | const ANTIALIAS_NONE = 1
124 | const ANTIALIAS_GRAY = 2
125 | const ANTIALIAS_SUBPIXEL = 3
126 | # next 3 are not available on all Cairo installations (only since 1.12)
127 | const ANTIALIAS_FAST = 4
128 | const ANTIALIAS_GOOD = 5
129 | const ANTIALIAS_BEST = 6
130 |
131 | const OPERATOR_CLEAR = 0
132 | const OPERATOR_SOURCE = 1
133 | const OPERATOR_OVER = 2
134 | const OPERATOR_IN = 3
135 | const OPERATOR_OUT = 4
136 | const OPERATOR_ATOP = 5
137 | const OPERATOR_DEST = 6
138 | const OPERATOR_DEST_OVER = 7
139 | const OPERATOR_DEST_IN = 8
140 | const OPERATOR_DEST_OUT = 9
141 | const OPERATOR_DEST_ATOP = 10
142 | const OPERATOR_XOR = 11
143 | const OPERATOR_ADD = 12
144 | const OPERATOR_SATURATE = 13
145 | const OPERATOR_MULTIPLY = 14
146 | const OPERATOR_SCREEN = 15
147 | const OPERATOR_OVERLAY = 16
148 | const OPERATOR_DARKEN = 17
149 | const OPERATOR_LIGHTEN = 18
150 |
151 |
152 | ## LaTex Token Dicts ##
153 | const _common_token_dict = Dict(
154 | "\\{" => "{",
155 | "\\}" => "}",
156 | "\\_" => "_",
157 | "\\^" => "^",
158 | "\\-" => "-",
159 |
160 | ## ignore stray brackets
161 | "{" => "",
162 | "}" => ""
163 | )
164 |
165 | const _text_token_dict = Dict(
166 | ## non-math symbols (p438)
167 | "\\S" => "\ua7",
168 | "\\P" => "\ub6",
169 | "\\dag" => "\u2020",
170 | "\\ddag" => "\u2021"
171 | )
172 |
173 | const _math_token_dict = Dict(
174 |
175 | "-" => "\u2212", # minus sign
176 |
177 | ## spacing
178 | "\\quad" => "\u2003", # 1 em
179 | "\\qquad" => "\u2003\u2003", # 2 em
180 | "\\," => "\u2006", # 3/18 em
181 | "\\>" => "\u2005", # 4/18 em
182 | "\\;" => "\u2004", # 5/18 em
183 |
184 | ## lowercase greek
185 | "\\alpha" => "\u03b1",
186 | "\\beta" => "\u03b2",
187 | "\\gamma" => "\u03b3",
188 | "\\delta" => "\u03b4",
189 | "\\epsilon" => "\u03b5",
190 | "\\varepsilon" => "\u03f5",
191 | "\\zeta" => "\u03b6",
192 | "\\eta" => "\u03b7",
193 | "\\theta" => "\u03b8",
194 | "\\vartheta" => "\u03d1",
195 | "\\iota" => "\u03b9",
196 | "\\kappa" => "\u03ba",
197 | "\\lambda" => "\u03bb",
198 | "\\mu" => "\u03bc",
199 | "\\nu" => "\u03bd",
200 | "\\xi" => "\u03be",
201 | "\\omicron" => "\u03bf",
202 | "\\pi" => "\u03c0",
203 | "\\varpi" => "\u03d6",
204 | "\\rho" => "\u03c1",
205 | "\\varrho" => "\u03f1",
206 | "\\sigma" => "\u03c3",
207 | "\\varsigma" => "\u03c2",
208 | "\\tau" => "\u03c4",
209 | "\\upsilon" => "\u03c5",
210 | "\\phi" => "\u03d5",
211 | "\\varphi" => "\u03c6",
212 | "\\chi" => "\u03c7",
213 | "\\psi" => "\u03c8",
214 | "\\omega" => "\u03c9",
215 |
216 | ## uppercase greek
217 | "\\Alpha" => "\u0391",
218 | "\\Beta" => "\u0392",
219 | "\\Gamma" => "\u0393",
220 | "\\Delta" => "\u0394",
221 | "\\Epsilon" => "\u0395",
222 | "\\Zeta" => "\u0396",
223 | "\\Eta" => "\u0397",
224 | "\\Theta" => "\u0398",
225 | "\\Iota" => "\u0399",
226 | "\\Kappa" => "\u039a",
227 | "\\Lambda" => "\u039b",
228 | "\\Mu" => "\u039c",
229 | "\\Nu" => "\u039d",
230 | "\\Xi" => "\u039e",
231 | "\\Pi" => "\u03a0",
232 | "\\Rho" => "\u03a1",
233 | "\\Sigma" => "\u03a3",
234 | "\\Tau" => "\u03a4",
235 | "\\Upsilon" => "\u03a5",
236 | "\\Phi" => "\u03a6",
237 | "\\Chi" => "\u03a7",
238 | "\\Psi" => "\u03a8",
239 | "\\Omega" => "\u03a9",
240 |
241 | ## miscellaneous
242 | "\\aleph" => "\u2135",
243 | "\\hbar" => "\u210f",
244 | "\\ell" => "\u2113",
245 | "\\wp" => "\u2118",
246 | "\\Re" => "\u211c",
247 | "\\Im" => "\u2111",
248 | "\\partial" => "\u2202",
249 | "\\infty" => "\u221e",
250 | "\\prime" => "\u2032",
251 | "\\emptyset" => "\u2205",
252 | "\\nabla" => "\u2206",
253 | "\\surd" => "\u221a",
254 | "\\top" => "\u22a4",
255 | "\\bot" => "\u22a5",
256 | "\\|" => "\u2225",
257 | "\\angle" => "\u2220",
258 | "\\triangle" => "\u25b3", # == \bigtriangleup
259 | "\\backslash" => "\u2216",
260 | "\\forall" => "\u2200",
261 | "\\exists" => "\u2203",
262 | "\\neg" => "\uac",
263 | "\\flat" => "\u266d",
264 | "\\natural" => "\u266e",
265 | "\\sharp" => "\u266f",
266 | "\\clubsuit" => "\u2663",
267 | "\\diamondsuit" => "\u2662",
268 | "\\heartsuit" => "\u2661",
269 | "\\spadesuit" => "\u2660",
270 |
271 | ## large operators
272 | "\\sum" => "\u2211",
273 | "\\prod" => "\u220f",
274 | "\\coprod" => "\u2210",
275 | "\\int" => "\u222b",
276 | "\\oint" => "\u222e",
277 | "\\bigcap" => "\u22c2",
278 | "\\bigcup" => "\u22c3",
279 | "\\bigscup" => "\u2a06",
280 | "\\bigvee" => "\u22c1",
281 | "\\bigwedge" => "\u22c0",
282 | "\\bigodot" => "\u2a00",
283 | "\\bigotimes" => "\u2a02",
284 | "\\bigoplus" => "\u2a01",
285 | "\\biguplus" => "\u2a04",
286 |
287 | ## binary operations
288 | "\\pm" => "\ub1",
289 | "\\mp" => "\u2213",
290 | "\\setminus" => "\u2216",
291 | "\\cdot" => "\u22c5",
292 | "\\times" => "\ud7",
293 | "\\ast" => "\u2217",
294 | "\\star" => "\u22c6",
295 | "\\diamond" => "\u22c4",
296 | "\\circ" => "\u2218",
297 | "\\bullet" => "\u2219",
298 | "\\div" => "\uf7",
299 | "\\cap" => "\u2229",
300 | "\\cup" => "\u222a",
301 | "\\uplus" => "\u228c", # 228e?
302 | "\\sqcap" => "\u2293",
303 | "\\sqcup" => "\u2294",
304 | "\\triangleleft" => "\u22b2",
305 | "\\triangleright" => "\u22b3",
306 | "\\wr" => "\u2240",
307 | "\\bigcirc" => "\u25cb",
308 | "\\bigtriangleup" => "\u25b3", # == \triangle
309 | "\\bigtriangledown" => "\u25bd",
310 | "\\vee" => "\u2228",
311 | "\\wedge" => "\u2227",
312 | "\\oplus" => "\u2295",
313 | "\\ominus" => "\u2296",
314 | "\\otimes" => "\u2297",
315 | "\\oslash" => "\u2298",
316 | "\\odot" => "\u2299",
317 | "\\dagger" => "\u2020",
318 | "\\ddagger" => "\u2021",
319 | "\\amalg" => "\u2210",
320 |
321 | ## relations
322 | "\\leq" => "\u2264",
323 | "\\prec" => "\u227a",
324 | "\\preceq" => "\u227c",
325 | "\\ll" => "\u226a",
326 | "\\subset" => "\u2282",
327 | "\\subseteq" => "\u2286",
328 | "\\sqsubseteq" => "\u2291",
329 | "\\in" => "\u2208",
330 | "\\vdash" => "\u22a2",
331 | "\\smile" => "\u2323",
332 | "\\frown" => "\u2322",
333 | "\\geq" => "\u2265",
334 | "\\succ" => "\u227b",
335 | "\\succeq" => "\u227d",
336 | "\\gg" => "\u226b",
337 | "\\supset" => "\u2283",
338 | "\\supseteq" => "\u2287",
339 | "\\sqsupseteq" => "\u2292",
340 | "\\ni" => "\u220b",
341 | "\\dashv" => "\u22a3",
342 | "\\mid" => "\u2223",
343 | "\\parallel" => "\u2225",
344 | "\\equiv" => "\u2261",
345 | "\\sim" => "\u223c",
346 | "\\simeq" => "\u2243",
347 | "\\asymp" => "\u224d",
348 | "\\approx" => "\u2248",
349 | "\\cong" => "\u2245",
350 | "\\bowtie" => "\u22c8",
351 | "\\propto" => "\u221d",
352 | "\\models" => "\u22a7", # 22a8?
353 | "\\doteq" => "\u2250",
354 | "\\perp" => "\u27c2",
355 |
356 | ## arrows
357 | "\\leftarrow" => "\u2190",
358 | "\\Leftarrow" => "\u21d0",
359 | "\\rightarrow" => "\u2192",
360 | "\\Rightarrow" => "\u21d2",
361 | "\\leftrightarrow" => "\u2194",
362 | "\\Leftrightarrow" => "\u21d4",
363 | "\\mapsto" => "\u21a6",
364 | "\\hookleftarrow" => "\u21a9",
365 | "\\leftharpoonup" => "\u21bc",
366 | "\\leftharpoondown" => "\u21bd",
367 | "\\rightleftharpoons" => "\u21cc",
368 | "\\longleftarrow" => "\u27f5",
369 | "\\Longleftarrow" => "\u27f8",
370 | "\\longrightarrow" => "\u27f6",
371 | "\\Longrightarrow" => "\u27f9",
372 | "\\longleftrightarrow" => "\u27f7",
373 | "\\Longleftrightarrow" => "\u27fa",
374 | "\\hookrightarrow" => "\u21aa",
375 | "\\rightharpoonup" => "\u21c0",
376 | "\\rightharpoondown" => "\u21c1",
377 | "\\uparrow" => "\u2191",
378 | "\\Uparrow" => "\u21d1",
379 | "\\downarrow" => "\u2193",
380 | "\\Downarrow" => "\u21d3",
381 | "\\updownarrow" => "\u2195",
382 | "\\Updownarrow" => "\u21d5",
383 | "\\nearrow" => "\u2197",
384 | "\\searrow" => "\u2198",
385 | "\\swarrow" => "\u2199",
386 | "\\nwarrow" => "\u2196",
387 |
388 | ## openings
389 | # "\\lbrack" => "[",
390 | # "\\lbrace" => "{",
391 | "\\langle" => "\u27e8",
392 | "\\lfloor" => "\u230a",
393 | "\\lceil" => "\u2308",
394 |
395 | ## closings
396 | # "\\rbrack" => "]",
397 | # "\\rbrace" => "}",
398 | "\\rangle" => "\u27e9",
399 | "\\rfloor" => "\u230b",
400 | "\\rceil" => "\u2309",
401 |
402 | ## alternate names
403 | "\\ne" => "\u2260",
404 | "\\neq" => "\u2260",
405 | "\\le" => "\u2264",
406 | "\\ge" => "\u2265",
407 | "\\to" => "\u2192",
408 | "\\gets" => "\u2192",
409 | "\\owns" => "\u220b",
410 | "\\land" => "\u2227",
411 | "\\lor" => "\u2228",
412 | "\\lnot" => "\uac",
413 | "\\vert" => "\u2223",
414 | "\\Vert" => "\u2225",
415 |
416 | ## extensions
417 | "\\deg" => "\ub0",
418 | "\\degr" => "\ub0",
419 | "\\degree" => "\ub0",
420 | "\\degrees" => "\ub0",
421 | "\\arcdeg" => "\ub0",
422 | "\\arcmin" => "\u2032",
423 | "\\arcsec" => "\u2033"
424 | )
425 |
426 | const CAIRO_FILL_RULE_WINDING = Int32(0);
427 | const CAIRO_FILL_RULE_EVEN_ODD = Int32(1);
428 |
429 | const CAIRO_LINE_CAP_BUTT = Int32(0);
430 | const CAIRO_LINE_CAP_ROUND = Int32(1);
431 | const CAIRO_LINE_CAP_SQUARE = Int32(2);
432 |
433 | const CAIRO_LINE_JOIN_MITER = Int32(0);
434 | const CAIRO_LINE_JOIN_ROUND = Int32(1);
435 | const CAIRO_LINE_JOIN_BEVEL = Int32(2);
436 |
437 | #typedef enum _cairo_path_data_type {
438 | # CAIRO_PATH_MOVE_TO,
439 | # CAIRO_PATH_LINE_TO,
440 | # CAIRO_PATH_CURVE_TO,
441 | # CAIRO_PATH_CLOSE_PATH
442 | #} cairo_path_data_type_t;
443 |
444 | const CAIRO_PATH_MOVE_TO = Int32(0);
445 | const CAIRO_PATH_LINE_TO = Int32(1);
446 | const CAIRO_PATH_CURVE_TO = Int32(2);
447 | const CAIRO_PATH_CLOSE_PATH = Int32(3);
448 |
449 |
450 |
--------------------------------------------------------------------------------
/src/Cairo.jl:
--------------------------------------------------------------------------------
1 | module Cairo
2 |
3 | import Base.Sys
4 |
5 | # For libcairo
6 | using Cairo_jll
7 | # For libpangocairo
8 | using Pango_jll
9 | # For libgobject
10 | using Glib_jll
11 |
12 | # Deprecate old library variables
13 | Base.@deprecate_binding _jl_libcairo Cairo.libcairo false
14 | Base.@deprecate_binding _jl_libgobject Cairo.libgobject false
15 | Base.@deprecate_binding _jl_libpango Cairo.libpango false
16 | Base.@deprecate_binding _jl_libpangocairo Cairo.libpango false
17 |
18 | using Colors
19 |
20 | import Graphics
21 | using Graphics: BoundingBox, GraphicsContext, GraphicsDevice
22 | import Graphics: arc, clip, clip_preserve, close_path, creategc, device_to_user!, device_to_user_distance!, fill_preserve, height, line_to, move_to, new_path, new_sub_path, paint, rectangle, rel_line_to, rel_move_to, reset_clip, restore, rotate, save, scale, set_dash, set_line_width, set_source, set_source_rgb, set_source_rgba, stroke, stroke_preserve, stroke_transformed, stroke_transformed_preserve, textwidth, translate, user_to_device!, user_to_device_distance!, width, circle, reset_transform
23 | import Base: copy, fill
24 |
25 | libcairo_version = VersionNumber(unsafe_string(
26 | ccall((:cairo_version_string,Cairo.libcairo),Cstring,()) ))
27 | libpango_version = VersionNumber(unsafe_string(
28 | ccall((:pango_version_string,Cairo.libpango),Cstring,()) ))
29 | if !Sys.iswindows()
30 | libpangocairo_version = VersionNumber(unsafe_string(
31 | ccall((:pango_version_string,Cairo.libpangocairo),Cstring,()) ))
32 | libgobject_version = VersionNumber(
33 | unsafe_load(cglobal((:glib_major_version, Cairo.libgobject), Cuint)),
34 | unsafe_load(cglobal((:glib_minor_version, Cairo.libgobject), Cuint)),
35 | unsafe_load(cglobal((:glib_micro_version, Cairo.libgobject), Cuint)))
36 | end
37 |
38 | import Base.show
39 |
40 | include("constants.jl")
41 |
42 | export
43 | # drawing surface and context types
44 | CairoSurface, CairoContext, CairoPattern,
45 |
46 | # surface constructors
47 | CairoRGBSurface, CairoPDFSurface, CairoEPSSurface, CairoXlibSurface,
48 | CairoARGBSurface, CairoSVGSurface, CairoImageSurface, CairoQuartzSurface,
49 | CairoWin32Surface, CairoScriptSurface, CairoRecordingSurface,
50 | CairoPSSurface, surface_create_similar,
51 |
52 | # surface and context management
53 | finish, destroy, status, get_source,
54 | creategc, save, restore, show_page, width, height,
55 |
56 | # pattern
57 | pattern_create_radial, pattern_create_linear,
58 | pattern_add_color_stop_rgb, pattern_add_color_stop_rgba,
59 | pattern_set_filter, pattern_set_extend, pattern_get_surface,
60 |
61 | # mesh patterns (version > 1.12)
62 | CairoPatternMesh,
63 | mesh_pattern_begin_patch, mesh_pattern_end_patch,
64 | mesh_pattern_move_to, mesh_pattern_line_to,
65 | mesh_pattern_curve_to,
66 | mesh_pattern_set_corner_color_rgb,
67 | mesh_pattern_set_corner_color_rgba,
68 |
69 | # drawing attribute manipulation
70 | set_antialias, get_antialias,
71 | set_fill_type, set_line_width, set_dash,
72 | set_source_rgb, set_source_rgba, set_source_surface, set_line_type,
73 | set_line_cap, set_line_join,
74 | set_operator, get_operator, set_source,
75 | CairoMatrix,
76 |
77 | # coordinate systems
78 | reset_transform, rotate, scale, translate, user_to_device!,
79 | device_to_user!, user_to_device_distance!, device_to_user_distance!,
80 | get_matrix, set_matrix,
81 |
82 | # clipping
83 | clip, clip_preserve, reset_clip,
84 |
85 | # fill, stroke, path, and shape commands
86 | fill, fill_preserve, new_path, new_sub_path, close_path, paint, paint_with_alpha, stroke,
87 | stroke_preserve, stroke_transformed, stroke_transformed_preserve,
88 | move_to, line_to, rel_line_to, rel_move_to,
89 | rectangle, circle, arc, arc_negative,
90 | curve_to, rel_curve_to,
91 | path_extents,
92 |
93 | # path copy
94 | copy_path, copy_path_flat, convert_cairo_path_data,
95 |
96 | # other path operations
97 | get_current_point, has_current_point,
98 |
99 | # text
100 | text,
101 | update_layout, show_layout, get_layout_size, layout_text,
102 | set_text, set_latex,
103 | set_font_face, set_font_size, select_font_face,
104 | textwidth, textheight, text_extents,
105 | TeXLexer, tex2pango, show_text, text_path,
106 |
107 | # images
108 | write_to_png, image, read_from_png,
109 |
110 | # push+pop group
111 | push_group, pop_group
112 |
113 | ## head docstring following
114 |
115 | "
116 | Surfaces, the canvas you are painting on
117 |
118 | CairoSurface, CairoRGBSurface, CairoPDFSurface, CairoEPSSurface,
119 | CairoXlibSurface, CairoARGBSurface, CairoSVGSurface,
120 | CairoImageSurface, CairoQuartzSurface,
121 | CairoWin32Surface, CairoScriptSurface, CairoRecordingSurface,
122 | CairoPSSurface,
123 |
124 | Context, the handle to coordinate transformation, paint+Color
125 |
126 | CairoContext, finish, destroy, status, get_source,
127 | creategc, save, restore, show_page, width, height
128 |
129 | Path creation API
130 |
131 | new_path, new_sub_path, close_path,
132 | move_to, line_to, rel_line_to, rel_move_to,
133 | rectangle, circle, arc, arc_negative,
134 | curve_to, rel_curve_to,
135 | path_extents,
136 |
137 |
138 | Stroking and painting API
139 |
140 | fill, fill_preserve, paint, paint_with_alpha, stroke,
141 | stroke_preserve, stroke_transformed, stroke_transformed_preserve
142 |
143 | CairoContext, finish, destroy, status, get_source,
144 | creategc, save, restore, show_page, width, height
145 |
146 | "
147 | Cairo
148 |
149 | function write_to_stream_callback(s::IO, buf::Ptr{UInt8}, len::UInt32)
150 | n = unsafe_write(s,buf,len)
151 | Int32((n == len) ? 0 : 11)
152 | end
153 |
154 | get_stream_callback(::Type{T}) where T = @cfunction write_to_stream_callback Int32 (Ref{T}, Ptr{UInt8}, UInt32)
155 |
156 | function read_from_stream_callback(s::IO, buf::Ptr{UInt8}, len::UInt32)
157 | # wrap the provided buf into a julia Array
158 | b1 = unsafe_wrap(Array,buf,len)
159 |
160 | # read from stream
161 | nb = readbytes!(s,b1,len)
162 |
163 | # provide a return status
164 | (nb == len) ? STATUS_SUCCESS : STATUS_READ_ERROR
165 | end
166 |
167 | get_readstream_callback(::Type{T}) where T = @cfunction read_from_stream_callback Int32 (Ref{T}, Ptr{UInt8}, UInt32)
168 |
169 | abstract type CairoSurface{T<:Union{UInt32,RGB24,ARGB32}} <: GraphicsDevice end
170 |
171 | mutable struct CairoSurfaceBase{T<:Union{UInt32,RGB24,ARGB32}} <: CairoSurface{T}
172 | ptr::Ptr{Nothing}
173 | width::Float64
174 | height::Float64
175 |
176 | function CairoSurface{T}(ptr::Ptr{Nothing}, w, h) where {T}
177 | self = new{T}(ptr, w, h)
178 | finalizer(destroy, self)
179 | self
180 | end
181 | function CairoSurface{T}(ptr::Ptr{Nothing}) where {T}
182 | ccall(
183 | (:cairo_surface_reference,libcairo),
184 | Ptr{Nothing}, (Ptr{Nothing}, ), ptr)
185 | self = new{T}(ptr)
186 | finalizer(destroy, self)
187 | self
188 | end
189 | end
190 |
191 |
192 | mutable struct CairoSurfaceImage{T<:Union{UInt32,RGB24,ARGB32}} <: CairoSurface{T}
193 | ptr::Ptr{Nothing}
194 | width::Float64
195 | height::Float64
196 | data::Matrix{T}
197 |
198 | function CairoSurface{T}(ptr::Ptr{Nothing}, w, h, data::Matrix{T}) where {T}
199 | self = new{T}(ptr, w, h, data)
200 | finalizer(destroy, self)
201 | self
202 | end
203 | end
204 |
205 | mutable struct CairoSurfaceIOStream{T<:Union{UInt32,RGB24,ARGB32}} <: CairoSurface{T}
206 | ptr::Ptr{Nothing}
207 | width::Float64
208 | height::Float64
209 | stream::IO
210 |
211 | function CairoSurface{T}(ptr::Ptr{Nothing}, w, h, stream::IO) where {T}
212 | self = new{T}(ptr, w, h, stream)
213 | finalizer(destroy, self)
214 | self
215 | end
216 | end
217 | function get_stream_ptr(surf::T) where {T<:CairoSurfaceIOStream}
218 | GC.@preserve surf begin
219 | return unsafe_load(Ptr{Ptr{Nothing}}(pointer_from_objref(surf) + fieldoffset(T, 4)))
220 | end
221 | end
222 |
223 |
224 | CairoSurface(ptr, w, h) = CairoSurface{UInt32}(ptr, w, h)
225 | CairoSurface(ptr, w, h, data) = CairoSurface{eltype(data)}(ptr, w, h, data)
226 | CairoSurface(ptr, w, h, stream::IO) = CairoSurface{UInt32}(ptr, w, h, stream)
227 | CairoSurface(ptr) = CairoSurface{UInt32}(ptr)
228 |
229 | width(surface::CairoSurface) = surface.width
230 | height(surface::CairoSurface) = surface.height
231 |
232 | function destroy(surface::CairoSurface)
233 | if surface.ptr == C_NULL
234 | return
235 | end
236 | ccall((:cairo_surface_destroy,libcairo), Nothing, (Ptr{Nothing},), surface.ptr)
237 | surface.ptr = C_NULL
238 | nothing
239 | end
240 |
241 | # function resize(surface::CairoSurface, w, h)
242 | # if OS_NAME == :Linux
243 | # CairoXlibSurfaceSetSize(surface.ptr, w, h)
244 | # elseif OS_NAME == :Darwin
245 | # elseif OS_NAME == :Windows
246 | # else
247 | # error("Unsupported operating system")
248 | # end
249 | # surface.width = w
250 | # surface.height = h
251 | # end
252 |
253 | for name in (:finish,:flush,:mark_dirty)
254 | @eval begin
255 | $name(surface::CairoSurface) =
256 | ccall(($(string("cairo_surface_",name)),libcairo),
257 | Nothing, (Ptr{Nothing},), surface.ptr)
258 | end
259 | end
260 |
261 | function status(surface::CairoSurface)
262 | ccall((:cairo_surface_status,libcairo),
263 | Int32, (Ptr{Nothing},), surface.ptr)
264 | end
265 |
266 | function CairoImageSurface(w::Real, h::Real, format::Integer)
267 | ptr = ccall((:cairo_image_surface_create,libcairo),
268 | Ptr{Nothing}, (Int32,Int32,Int32), format, w, h)
269 | CairoSurface(ptr, w, h)
270 | end
271 |
272 | CairoRGBSurface(w::Real, h::Real) = CairoImageSurface(w, h, FORMAT_RGB24)
273 | CairoARGBSurface(w::Real, h::Real) = CairoImageSurface(w, h, FORMAT_ARGB32)
274 | CairoARGBSurface(img) = CairoImageSurface(img, FORMAT_ARGB32)
275 | CairoRGBSurface(img) = CairoImageSurface(img, FORMAT_RGB24)
276 |
277 | function CairoImageSurface(img::Array{UInt32,2}, format::Integer; flipxy::Bool = true)
278 | if flipxy
279 | img = permutedims(img, (2,1))
280 | end
281 | w,h = size(img)
282 | stride = format_stride_for_width(format, w)
283 | @assert stride == 4w
284 | ptr = ccall((:cairo_image_surface_create_for_data,libcairo),
285 | Ptr{Nothing}, (Ptr{Nothing},Int32,Int32,Int32,Int32),
286 | img, format, w, h, stride)
287 | CairoSurface(ptr, w, h, img)
288 | end
289 |
290 | function CairoImageSurface(img::Matrix{T}) where {T<:Union{RGB24,ARGB32}}
291 | w,h = size(img)
292 | stride = format_stride_for_width(format(T), w)
293 | @assert stride == 4w
294 | ptr = ccall((:cairo_image_surface_create_for_data,libcairo),
295 | Ptr{Nothing}, (Ptr{Nothing},Int32,Int32,Int32,Int32),
296 | img, format(T), w, h, stride)
297 | CairoSurface(ptr, w, h, img)
298 | end
299 |
300 | format(::Type{RGB24}) = FORMAT_RGB24
301 | format(::Type{ARGB32}) = FORMAT_ARGB32
302 | format(surf::CairoSurface{T}) where {T<:Union{RGB24,ARGB32}} = T
303 |
304 | ## PDF ##
305 |
306 | function CairoPDFSurface(stream::T, w::Real, h::Real) where {T<:IO}
307 | callback = get_stream_callback(T)
308 | surf = CairoSurface(C_NULL, w, h, stream)
309 | GC.@preserve surf begin
310 | surf.ptr = ccall((:cairo_pdf_surface_create_for_stream,libcairo), Ptr{Nothing},
311 | (Ptr{Nothing}, Ptr{Nothing}, Float64, Float64), callback,
312 | get_stream_ptr(surf), w, h)
313 | end
314 | return surf
315 | end
316 |
317 | function CairoPDFSurface(filename::AbstractString, w_pts::Real, h_pts::Real)
318 | ptr = ccall((:cairo_pdf_surface_create,libcairo), Ptr{Nothing},
319 | (Ptr{UInt8},Float64,Float64), String(filename), w_pts, h_pts)
320 | CairoSurface(ptr, w_pts, h_pts)
321 | end
322 |
323 | ## EPS ##
324 |
325 | function CairoEPSSurface(stream::T, w::Real, h::Real) where {T<:IO}
326 | callback = get_stream_callback(T)
327 | surf = CairoSurface(C_NULL, w, h, stream)
328 | GC.@preserve surf begin
329 | surf.ptr = ccall((:cairo_ps_surface_create_for_stream,libcairo), Ptr{Nothing},
330 | (Ptr{Nothing}, Ptr{Nothing}, Float64, Float64),
331 | callback, get_stream_ptr(surf), w, h)
332 | ccall((:cairo_ps_surface_set_eps,libcairo), Nothing,
333 | (Ptr{Nothing},Int32), surf.ptr, 1)
334 | end
335 | return surf
336 | end
337 |
338 | function CairoEPSSurface(filename::AbstractString, w_pts::Real, h_pts::Real)
339 | ptr = ccall((:cairo_ps_surface_create,libcairo), Ptr{Nothing},
340 | (Ptr{UInt8},Float64,Float64), String(filename), w_pts, h_pts)
341 | ccall((:cairo_ps_surface_set_eps,libcairo), Nothing,
342 | (Ptr{Nothing},Int32), ptr, 1)
343 | CairoSurface(ptr, w_pts, h_pts)
344 | end
345 |
346 | ## PS ##
347 |
348 | function CairoPSSurface(stream::T, w::Real, h::Real) where {T<:IO}
349 | callback = get_stream_callback(T)
350 | surf = CairoSurface(C_NULL, w, h, stream)
351 | GC.@preserve surf begin
352 | surf.ptr = ccall((:cairo_ps_surface_create_for_stream,libcairo), Ptr{Nothing},
353 | (Ptr{Nothing}, Ptr{Nothing}, Float64, Float64),
354 | callback, get_stream_ptr(surf), w, h)
355 | ccall((:cairo_ps_surface_set_eps,libcairo), Nothing,
356 | (Ptr{Nothing},Int32), surf.ptr, 0)
357 | end
358 | return surf
359 | end
360 |
361 | function CairoPSSurface(filename::AbstractString, w_pts::Real, h_pts::Real)
362 | ptr = ccall((:cairo_ps_surface_create,libcairo), Ptr{Nothing},
363 | (Ptr{UInt8},Float64,Float64), String(filename), w_pts, h_pts)
364 | ccall((:cairo_ps_surface_set_eps,libcairo), Nothing,
365 | (Ptr{Nothing},Int32), ptr, 0)
366 | CairoSurface(ptr, w_pts, h_pts)
367 | end
368 |
369 | ## Xlib ##
370 |
371 | function CairoXlibSurface(display, drawable, visual, w, h)
372 | ptr = ccall((:cairo_xlib_surface_create,libcairo), Ptr{Nothing},
373 | (Ptr{Nothing}, Int, Ptr{Nothing}, Int32, Int32),
374 | display, drawable, visual, w, h)
375 | CairoSurface(ptr, w, h)
376 | end
377 |
378 | CairoXlibSurfaceSetSize(surface, w, h) =
379 | ccall((:cairo_xlib_surface_set_size,libcairo), Nothing,
380 | (Ptr{Nothing}, Int32, Int32),
381 | surface, w, h)
382 |
383 | ## Quartz ##
384 | function CairoQuartzSurface(context, w, h)
385 | ptr = ccall((:cairo_quartz_surface_create_for_cg_context,libcairo),
386 | Ptr{Nothing}, (Ptr{Nothing}, UInt32, UInt32), context, w, h)
387 | CairoSurface(ptr, w, h)
388 | end
389 |
390 | ## Win32 ##
391 |
392 | function CairoWin32Surface(hdc,w,h)
393 | ptr = ccall((:cairo_win32_surface_create, libcairo),
394 | Ptr{Nothing}, (Ptr{Nothing},), hdc)
395 | CairoSurface(ptr,w,h)
396 | end
397 |
398 | ## SVG ##
399 |
400 | function CairoSVGSurface(stream::T, w::Real, h::Real) where {T<:IO}
401 | callback = get_stream_callback(T)
402 | surf = CairoSurface(C_NULL, w, h, stream)
403 | GC.@preserve surf begin
404 | surf.ptr = ccall((:cairo_svg_surface_create_for_stream,libcairo), Ptr{Nothing},
405 | (Ptr{Nothing}, Ptr{Nothing}, Float64, Float64), callback,
406 | get_stream_ptr(surf), w, h)
407 | end
408 | return surf
409 | end
410 |
411 | function CairoSVGSurface(filename::AbstractString, w::Real, h::Real)
412 | ptr = ccall((:cairo_svg_surface_create,libcairo), Ptr{Nothing},
413 | (Ptr{UInt8},Float64,Float64), String(filename), w, h)
414 | CairoSurface(ptr, w, h)
415 | end
416 |
417 | ## PNG ##
418 |
419 | function read_from_png(filename::AbstractString)
420 | ptr = ccall((:cairo_image_surface_create_from_png,libcairo),
421 | Ptr{Nothing}, (Ptr{UInt8},), String(filename))
422 | w = ccall((:cairo_image_surface_get_width,libcairo),
423 | Int32, (Ptr{Nothing},), ptr)
424 | h = ccall((:cairo_image_surface_get_height,libcairo),
425 | Int32, (Ptr{Nothing},), ptr)
426 | CairoSurface(ptr, w, h)
427 | end
428 |
429 | function write_to_png(surface::CairoSurface, stream::T) where {T<:IO}
430 | callback = get_stream_callback(T)
431 | ccall((:cairo_surface_write_to_png_stream,libcairo), status_t,
432 | (Ptr{UInt8},Ptr{Nothing},Any), surface.ptr, callback, stream)
433 | end
434 |
435 | function write_to_png(surface::CairoSurface, filename::AbstractString)
436 | ccall((:cairo_surface_write_to_png,libcairo), status_t,
437 | (Ptr{UInt8},Ptr{UInt8}), surface.ptr, String(filename))
438 | end
439 |
440 | show(io::IO, ::MIME"image/png", surface::CairoSurface) =
441 | write_to_png(surface, io)
442 |
443 | function read_from_png(stream::T) where {T<:IO}
444 | callback = get_readstream_callback(T)
445 | ptr = ccall((:cairo_image_surface_create_from_png_stream, Cairo.libcairo),
446 | Ptr{Nothing}, (Ptr{Nothing},Ref{IO}), callback, stream)
447 | w = ccall((:cairo_image_surface_get_width,Cairo.libcairo),
448 | Int32, (Ptr{Nothing},), ptr)
449 | h = ccall((:cairo_image_surface_get_height,Cairo.libcairo),
450 | Int32, (Ptr{Nothing},), ptr)
451 | Cairo.CairoSurface(ptr, w, h)
452 | end
453 |
454 |
455 | ## Generic ##
456 |
457 | function surface_create_similar(s::CairoSurface, w = width(s), h = height(s))
458 | ptr = ccall((:cairo_surface_create_similar,libcairo), Ptr{Nothing},
459 | (Ptr{Nothing}, Int32, Int32, Int32),
460 | s.ptr, CONTENT_COLOR_ALPHA, w, h)
461 | CairoSurface(ptr, w, h)
462 | end
463 |
464 | # Utilities
465 |
466 | function format_stride_for_width(format::Integer, width::Integer)
467 | ccall((:cairo_format_stride_for_width,libcairo), Int32,
468 | (Int32,Int32), format, width)
469 | end
470 |
471 |
472 | ## Scripting (only target IO stream)
473 |
474 | mutable struct CairoScript <: GraphicsDevice
475 | ptr::Ptr{Nothing}
476 | stream::IO
477 |
478 | function CairoScript(stream::T) where {T<:IO}
479 | callback = get_stream_callback(T)
480 | self = new(C_NULL, stream)
481 | GC.@preserve self begin
482 | self.ptr = ccall((:cairo_script_create_for_stream,libcairo), Ptr{Nothing},
483 | (Ptr{Nothing}, Ptr{Nothing}), callback, get_stream_ptr(self))
484 | end
485 | finalizer(destroy, self)
486 | self
487 | end
488 | end
489 | function get_stream_ptr(s::T) where {T<:CairoScript}
490 | GC.@preserve s begin
491 | return unsafe_load(Ptr{Ptr{Nothing}}(pointer_from_objref(s) + fieldoffset(T, 2)))
492 | end
493 | end
494 |
495 | function destroy(s::CairoScript)
496 | if s.ptr == C_NULL
497 | return
498 | end
499 | ccall((:cairo_device_destroy,libcairo), Nothing, (Ptr{Nothing},), s.ptr)
500 | s.ptr = C_NULL
501 | nothing
502 | end
503 |
504 | function CairoScriptSurface(stream::IO, w::Real, h::Real)
505 | s = CairoScript(stream)
506 | ptr = ccall((:cairo_script_surface_create,libcairo), Ptr{Nothing},
507 | (Ptr{Nothing},Int32,Float64,Float64),s.ptr ,CONTENT_COLOR_ALPHA, w, h)
508 | CairoSurface(ptr, w, h, stream)
509 | end
510 |
511 | function CairoScriptSurface(stream::IO, sc::CairoSurface)
512 | s = CairoScript(stream)
513 | ptr = ccall((:cairo_script_surface_create_for_target,libcairo), Ptr{Nothing},
514 | (Ptr{Nothing},Ptr{Nothing}),s.ptr, sc.ptr)
515 | CairoSurface(ptr, sc.width, sc.height)
516 | end
517 |
518 |
519 |
520 | mutable struct CairoRectangle
521 | x0::Float64
522 | y0::Float64
523 | x1::Float64
524 | y1::Float64
525 | end
526 |
527 | CairoRectangle() = CairoRectangle(0.0, 0.0, 0.0, 0.0)
528 |
529 | function CairoRecordingSurface(content::Int32,extents::CairoRectangle)
530 | ptr = ccall((:cairo_recording_surface_create,libcairo), Ptr{Nothing},
531 | (Int32,Ptr{Nothing}),content, Ref(extents))
532 | CairoSurface(ptr)
533 | end
534 | function CairoRecordingSurface(content::Int32)
535 | ptr = ccall((:cairo_recording_surface_create,libcairo), Ptr{Nothing},
536 | (Int32,Ptr{Nothing}),content, C_NULL)
537 | CairoSurface(ptr)
538 | end
539 |
540 | CairoRecordingSurface() = CairoRecordingSurface(CONTENT_COLOR_ALPHA)
541 |
542 |
543 | function script_from_recording_surface(s::CairoScript,r::CairoSurface)
544 | ccall((:cairo_script_from_recording_surface,libcairo), Int32,
545 | (Ptr{Nothing},Ptr{Nothing}),s.ptr, r.ptr)
546 | end
547 | # -----------------------------------------------------------------------------
548 |
549 | mutable struct CairoContext <: GraphicsContext
550 | ptr::Ptr{Nothing}
551 | surface::CairoSurface
552 | layout::Ptr{Nothing} # cache PangoLayout
553 |
554 | function CairoContext(surface::CairoSurface)
555 | ptr = ccall((:cairo_create,libcairo),
556 | Ptr{Nothing}, (Ptr{Nothing},), surface.ptr)
557 | layout = ccall((:pango_cairo_create_layout,libpangocairo),
558 | Ptr{Nothing}, (Ptr{Nothing},), ptr)
559 | self = new(ptr, surface, layout)
560 | finalizer(destroy, self)
561 | self
562 | end
563 | function CairoContext(ptr::Ptr{Nothing})
564 | ccall((:cairo_reference,libcairo),
565 | Ptr{Nothing}, (Ptr{Nothing},), ptr)
566 | surface_p = ccall((:cairo_get_target,libcairo),
567 | Ptr{Nothing}, (Ptr{Nothing},), ptr)
568 | surface = CairoSurface(surface_p)
569 | layout = ccall((:pango_cairo_create_layout,libpangocairo),
570 | Ptr{Nothing}, (Ptr{Nothing},), ptr)
571 | self = new(ptr,surface,layout)
572 | finalizer(destroy, self)
573 | self
574 | end
575 |
576 |
577 | end
578 |
579 | creategc(s::CairoSurface) = CairoContext(s)
580 |
581 | function destroy(ctx::CairoContext)
582 | if ctx.ptr == C_NULL
583 | return
584 | end
585 | ccall((:g_object_unref,libgobject), Nothing, (Ptr{Nothing},), ctx.layout)
586 | _destroy(ctx)
587 | ctx.ptr = C_NULL
588 | nothing
589 | end
590 |
591 | width(ctx::CairoContext) = width(ctx.surface)
592 | height(ctx::CairoContext) = height(ctx.surface)
593 |
594 | function copy(ctx::CairoContext)
595 | surf = surface_create_similar(ctx.surface)
596 | c = creategc(surf)
597 | set_source_surface(c, ctx.surface)
598 | paint(c)
599 | set_matrix(c, get_matrix(ctx))
600 | c
601 | end
602 |
603 | # Copy a rectangular region
604 | function copy(ctx::CairoContext, bb::BoundingBox)
605 | w = width(bb)
606 | h = height(bb)
607 | surf = surface_create_similar(ctx.surface, ceil(Int,w), ceil(Int,h))
608 | c = creategc(surf)
609 | set_source_surface(c, ctx.surface, -bb.xmin, -bb.ymin)
610 | rectangle(c, 0, 0, w, h)
611 | fill(c)
612 | set_matrix(c, get_matrix(ctx))
613 | c
614 | end
615 |
616 | for (NAME, FUNCTION) in Any[(:_destroy, :cairo_destroy),
617 | (:save, :cairo_save),
618 | (:restore, :cairo_restore),
619 | (:show_page, :cairo_show_page),
620 | (:clip, :cairo_clip),
621 | (:clip_preserve, :cairo_clip_preserve),
622 | (:reset_clip, :cairo_reset_clip),
623 | (:reset_transform, :cairo_identity_matrix),
624 | (:fill, :cairo_fill),
625 | (:fill_preserve, :cairo_fill_preserve),
626 | (:new_path, :cairo_new_path),
627 | (:new_sub_path, :cairo_new_sub_path),
628 | (:close_path, :cairo_close_path),
629 | (:paint, :cairo_paint),
630 | (:stroke_transformed, :cairo_stroke),
631 | (:stroke_transformed_preserve, :cairo_stroke_preserve)]
632 | @eval begin
633 | $NAME(ctx::CairoContext) =
634 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
635 | Nothing, (Ptr{Nothing},), ctx.ptr)
636 | end
637 | end
638 |
639 | function stroke(ctx::CairoContext)
640 | save(ctx)
641 | # use uniform scale for stroking
642 | reset_transform(ctx)
643 | ccall((:cairo_stroke, libcairo), Nothing, (Ptr{Nothing},), ctx.ptr)
644 | restore(ctx)
645 | end
646 |
647 | function stroke_preserve(ctx::CairoContext)
648 | save(ctx)
649 | reset_transform(ctx)
650 | ccall((:cairo_stroke_preserve, libcairo), Nothing, (Ptr{Nothing},), ctx.ptr)
651 | restore(ctx)
652 | end
653 |
654 | function paint_with_alpha(ctx::CairoContext, a)
655 | ccall((:cairo_paint_with_alpha, libcairo),
656 | Nothing, (Ptr{Nothing}, Float64), ctx.ptr, a)
657 | end
658 |
659 | function get_operator(ctx::CairoContext)
660 | Int(ccall((:cairo_get_operator,libcairo), Int32, (Ptr{Nothing},), ctx.ptr))
661 | end
662 |
663 |
664 | for (NAME, FUNCTION) in Any[(:set_fill_type, :cairo_set_fill_rule),
665 | (:set_operator, :cairo_set_operator),
666 | (:set_line_cap, :cairo_set_line_cap),
667 | (:set_line_join, :cairo_set_line_join)]
668 | @eval begin
669 | $NAME(ctx::CairoContext, i0::Integer) =
670 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
671 | Nothing, (Ptr{Nothing},Int32), ctx.ptr, i0)
672 | end
673 | end
674 |
675 | for (NAME, FUNCTION) in Any[(:set_line_width, :cairo_set_line_width),
676 | (:rotate, :cairo_rotate),
677 | (:set_font_size, :cairo_set_font_size)]
678 | @eval begin
679 | $NAME(ctx::CairoContext, d0::Real) =
680 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
681 | Nothing, (Ptr{Nothing},Float64), ctx.ptr, d0)
682 | end
683 | end
684 |
685 | for (NAME, FUNCTION) in Any[(:line_to, :cairo_line_to),
686 | (:move_to, :cairo_move_to),
687 | (:rel_line_to, :cairo_rel_line_to),
688 | (:rel_move_to, :cairo_rel_move_to),
689 | (:scale, :cairo_scale),
690 | (:translate, :cairo_translate)]
691 | @eval begin
692 | $NAME(ctx::CairoContext, d0::Real, d1::Real) =
693 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
694 | Nothing, (Ptr{Nothing},Float64,Float64), ctx.ptr, d0, d1)
695 | end
696 | end
697 |
698 | for (NAME, FUNCTION) in Any[(:curve_to, :cairo_curve_to),
699 | (:rel_curve_to, :cairo_rel_curve_to)]
700 | @eval begin
701 | $NAME(ctx::CairoContext, d0::Real, d1::Real, d2::Real, d3::Real, d4::Real, d5::Real) =
702 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
703 | Nothing, (Ptr{Nothing},Float64,Float64,Float64,Float64,Float64,Float64), ctx.ptr, d0, d1, d2, d3, d4, d5)
704 | end
705 | end
706 |
707 | for (NAME, FUNCTION) in Any[(:arc, :cairo_arc),
708 | (:arc_negative, :cairo_arc_negative)]
709 | @eval begin
710 | $NAME(ctx::CairoContext, xc::Real, yc::Real, radius::Real, angle1::Real, angle2::Real) =
711 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
712 | Nothing, (Ptr{Nothing},Float64,Float64,Float64,Float64,Float64),
713 | ctx.ptr, xc, yc, radius, angle1, angle2)
714 | end
715 | end
716 |
717 |
718 | set_source_rgb(ctx::CairoContext, r::Real, g::Real, b::Real) =
719 | ccall((:cairo_set_source_rgb,libcairo),
720 | Nothing, (Ptr{Nothing},Float64,Float64,Float64), ctx.ptr, r, g, b)
721 |
722 | set_source_rgba(ctx::CairoContext, r::Real, g::Real, b::Real, a::Real) =
723 | ccall((:cairo_set_source_rgba,libcairo), Nothing,
724 | (Ptr{Nothing},Float64,Float64,Float64,Float64),
725 | ctx.ptr, r, g, b, a)
726 |
727 | function set_source(ctx::CairoContext, c::Color)
728 | rgb = convert(RGB, c)
729 | set_source_rgb(ctx, rgb.r, rgb.g, rgb.b)
730 | end
731 |
732 | function set_source(ctx::CairoContext, ac::TransparentColor)
733 | rgba = convert(RGBA, ac)
734 | set_source_rgba(ctx, rgba.r, rgba.g, rgba.b, rgba.alpha)
735 | end
736 |
737 | set_source(dest::CairoContext, src::CairoContext) = set_source_surface(dest, src.surface)
738 |
739 | set_source(dest::CairoContext, src::CairoSurface) = set_source_surface(dest, src)
740 |
741 | rectangle(ctx::CairoContext, x::Real, y::Real, w::Real, h::Real) =
742 | ccall((:cairo_rectangle,libcairo), Nothing,
743 | (Ptr{Nothing},Float64,Float64,Float64,Float64),
744 | ctx.ptr, x, y, w, h)
745 |
746 | function set_dash(ctx::CairoContext, dashes::Vector{Float64}, offset::Real = 0.0)
747 | ccall((:cairo_set_dash,libcairo), Nothing,
748 | (Ptr{Nothing},Ptr{Float64},Int32,Float64), ctx.ptr, dashes, length(dashes), offset)
749 | end
750 |
751 | function set_source_surface(ctx::CairoContext, s::CairoSurface, x::Real = 0.0, y::Real = 0.0)
752 | ccall((:cairo_set_source_surface,libcairo), Nothing,
753 | (Ptr{Nothing},Ptr{Nothing},Float64,Float64), ctx.ptr, s.ptr, x, y)
754 | end
755 |
756 | function set_source(ctx::CairoContext, s::CairoSurface, x::Real, y::Real)
757 | set_source_surface(ctx, s, x, y)
758 | end
759 |
760 |
761 | # cairo_path data and functions
762 |
763 | mutable struct CairoPath_t
764 | status::Cairo.status_t
765 | data::Ptr{Float64}
766 | num_data::UInt32
767 | end
768 |
769 | mutable struct CairoPath <: GraphicsDevice
770 | ptr::Ptr{CairoPath_t}
771 |
772 | function CairoPath(ptr::Ptr{Nothing})
773 | self = new(ptr)
774 | finalizer(destroy, self)
775 | self
776 | end
777 | end
778 |
779 | # Abstract, contains type (moveto,lineto,curveto,closepath) and points
780 | mutable struct CairoPathEntry
781 | element_type::UInt32
782 | points::Array{Float64,1}
783 | end
784 |
785 |
786 | function destroy(path::CairoPath)
787 | if path.ptr == C_NULL
788 | return
789 | end
790 | ccall((:cairo_path_destroy,libcairo), Nothing, (Ptr{Nothing},), path.ptr)
791 | path.ptr = C_NULL
792 | nothing
793 | end
794 |
795 | function copy_path(ctx::CairoContext)
796 | ptr = ccall((:cairo_copy_path, libcairo),
797 | Ptr{Nothing}, (Ptr{Nothing},),ctx.ptr)
798 | path = CairoPath(ptr)
799 | finalizer(destroy, path)
800 | path
801 | end
802 |
803 | function copy_path_flat(ctx::CairoContext)
804 | ptr = ccall((:cairo_copy_path_flat, libcairo),
805 | Ptr{Nothing}, (Ptr{Nothing},),ctx.ptr)
806 | path = CairoPath(ptr)
807 | finalizer(destroy, path)
808 | path
809 | end
810 |
811 | function convert_cairo_path_data(p::CairoPath)
812 | c = unsafe_load(p.ptr)
813 |
814 | # The original data (pointed by c.data) is an array of Unions. We
815 | # define here by Float64 (most data is) and reinterpret in the header.
816 |
817 | path_data = CairoPathEntry[]
818 | @static if VERSION >= v"0.7"
819 | c_data = unsafe_wrap(Array, c.data, (Int(c.num_data*2), 1), own=false)
820 | else
821 | c_data = unsafe_wrap(Array, c.data, (Int(c.num_data*2), 1), false)
822 | end
823 |
824 | data_index = 1
825 | while data_index <= ((c.num_data)*2)
826 |
827 | # read header (reinterpret a Float64 to UInt64 and split to UInt32 x 2)
828 | element_length = reinterpret(UInt64,c_data[data_index]) >> 32
829 | element_type = reinterpret(UInt64,c_data[data_index]) & 0xffffffff
830 |
831 | # copy points x,y
832 | points = Vector{Float64}(undef, (element_length - 1) * 2)
833 | for i=1:(element_length-1)*2
834 | points[i] = c_data[data_index+i+1]
835 | end
836 |
837 | g = CairoPathEntry(element_type,points)
838 | push!(path_data,g)
839 |
840 | # goto next element
841 | data_index += (element_length*2)
842 |
843 | end
844 | path_data
845 | end
846 |
847 | # other path operations
848 |
849 | function get_current_point(ctx::CairoContext)
850 |
851 | x = Ref{Cdouble}(0)
852 | y = Ref{Cdouble}(0)
853 | ccall((:cairo_get_current_point, libcairo),
854 | Nothing, (Ptr{Nothing},Ref{Cdouble},Ref{Cdouble}),ctx.ptr,x,y)
855 |
856 | x[],y[]
857 | end
858 |
859 | function has_current_point(ctx::CairoContext)
860 | Bool(ccall((:cairo_has_current_point, libcairo),
861 | Cint, (Ptr{Nothing},),ctx.ptr))
862 | end
863 |
864 | # user<->device coordinate translation
865 |
866 | for (fname,cname) in ((:user_to_device!,:cairo_user_to_device),
867 | (:device_to_user!,:cairo_device_to_user),
868 | (:user_to_device_distance!,:cairo_user_to_device_distance),
869 | (:device_to_user_distance!,:cairo_device_to_user_distance))
870 | @eval begin
871 | function ($fname)(ctx::CairoContext, p::Vector{Float64})
872 | ccall(($(Expr(:quote,cname)),libcairo),
873 | Nothing, (Ptr{Nothing}, Ptr{Float64}, Ptr{Float64}),
874 | ctx.ptr, pointer(p,1), pointer(p,2))
875 | p
876 | end
877 | end
878 | end
879 |
880 | function image(ctx::CairoContext, s::CairoSurface, x, y, w, h)
881 | rectangle(ctx, x, y, w, h)
882 | save(ctx)
883 | translate(ctx, x, y)
884 | scale(ctx, w/s.width, h/s.height)
885 | set_source_surface(ctx, s, 0, 0)
886 | if abs(w) > s.width && abs(h) > s.height
887 | # use NEAREST filter when stretching an image
888 | # it's usually better to see pixels than a blurry mess when viewing
889 | # a small image
890 | p = get_source(ctx)
891 | pattern_set_filter(p, FILTER_NEAREST)
892 | end
893 | fill(ctx)
894 | restore(ctx)
895 | end
896 |
897 | image(ctx::CairoContext, img::Array{UInt32,2}, x, y, w, h) =
898 | image(ctx, CairoRGBSurface(img), x, y, w, h)
899 |
900 | function push_group(ctx::CairoContext)
901 | if ctx.ptr == C_NULL
902 | return
903 | end
904 | ccall((:cairo_push_group, libcairo), Nothing, (Ptr{Nothing},),ctx.ptr)
905 | nothing
906 | end
907 |
908 | function pop_group(ctx::CairoContext)
909 | if ctx.ptr == C_NULL
910 | return
911 | end
912 | ptr = ccall((:cairo_pop_group, libcairo), Ptr{Nothing}, (Ptr{Nothing},),ctx.ptr)
913 | pattern = CairoPattern(ptr)
914 | finalizer(destroy, pattern)
915 | pattern
916 | end
917 |
918 | # -----------------------------------------------------------------------------
919 |
920 | mutable struct CairoPattern
921 | ptr::Ptr{Nothing}
922 | end
923 |
924 | function CairoPattern(s::CairoSurface)
925 | ptr = ccall((:cairo_pattern_create_for_surface, libcairo),
926 | Ptr{Nothing}, (Ptr{Nothing},), s.ptr)
927 | # Ideally we'd check the status, but at least for certain releases of the library
928 | # the return value seems not to be set properly (random values are returned)
929 | # status = ccall((:cairo_pattern_status, libcairo),
930 | # Cint, (Ptr{Nothing},), s.ptr)
931 | # if status != 0
932 | # error("Error creating Cairo pattern: ", bytestring(
933 | # ccall((:cairo_status_to_string, libcairo),
934 | # Ptr{UInt8}, (Cint,), status)))
935 | # end
936 | pattern = CairoPattern(ptr)
937 | finalizer(destroy, pattern)
938 | pattern
939 | end
940 |
941 | set_source(dest::CairoContext, src::CairoPattern) =
942 | ccall((:cairo_set_source, libcairo),
943 | Nothing, (Ptr{Nothing}, Ptr{Nothing}), dest.ptr, src.ptr)
944 |
945 | function get_source(ctx::CairoContext)
946 | CairoPattern(ccall((:cairo_get_source,libcairo),
947 | Ptr{Nothing}, (Ptr{Nothing},), ctx.ptr))
948 | end
949 |
950 | function pattern_set_filter(p::CairoPattern, f)
951 | ccall((:cairo_pattern_set_filter,libcairo), Nothing,
952 | (Ptr{Nothing},Int32), p.ptr, f)
953 | end
954 |
955 | function pattern_set_extend(p::CairoPattern, val)
956 | ccall((:cairo_pattern_set_extend,libcairo), Nothing,
957 | (Ptr{Nothing},Int32), p.ptr, val)
958 | end
959 |
960 | function pattern_create_radial(cx0::Real, cy0::Real, radius0::Real, cx1::Real, cy1::Real, radius1::Real)
961 | ptr = ccall((:cairo_pattern_create_radial, libcairo),
962 | Ptr{Nothing}, (Float64,Float64,Float64,Float64,Float64,Float64),cx0,cy0,radius0,cx1,cy1,radius1)
963 | pattern = CairoPattern(ptr)
964 | finalizer(destroy, pattern)
965 | pattern
966 | end
967 |
968 | function pattern_create_linear(x0::Real, y0::Real, x1::Real, y1::Real)
969 | ptr = ccall((:cairo_pattern_create_linear, libcairo),
970 | Ptr{Nothing}, (Float64,Float64,Float64,Float64),x0,y0,x1,y1)
971 | pattern = CairoPattern(ptr)
972 | finalizer(destroy, pattern)
973 | pattern
974 | end
975 |
976 | function pattern_add_color_stop_rgb(pat::CairoPattern, offset::Real, red::Real, green::Real, blue::Real)
977 | ccall((:cairo_pattern_add_color_stop_rgb, libcairo),
978 | Nothing, (Ptr{Nothing},Float64,Float64,Float64,Float64),pat.ptr,offset,red,green,blue)
979 | end
980 |
981 | function pattern_add_color_stop_rgba(pat::CairoPattern, offset::Real, red::Real, green::Real, blue::Real, alpha::Real)
982 | ccall((:cairo_pattern_add_color_stop_rgba, libcairo),
983 | Nothing, (Ptr{Nothing},Float64,Float64,Float64,Float64,Float64),pat.ptr,offset,red,green,blue,alpha)
984 | end
985 |
986 | function pattern_get_surface(pat::CairoPattern)
987 | ptrref = Ref{Ptr{Nothing}}()
988 | status = ccall((:cairo_pattern_get_surface, libcairo), Cint,
989 | (Ptr{Nothing}, Ref{Ptr{Nothing}}), pat.ptr, ptrref)
990 | if status == STATUS_PATTERN_TYPE_MISMATCH
991 | error("Cannot get surface from a non-surface pattern.")
992 | end
993 | ptr = ptrref.x
994 |
995 | ccall((:cairo_surface_reference, libcairo), Ptr{Nothing}, (Ptr{Nothing},), ptr)
996 | typ = ccall((:cairo_surface_get_type, libcairo), Cint, (Ptr{Nothing},), ptr)
997 |
998 | w = 0.0
999 | h = 0.0
1000 | if typ == CAIRO_SURFACE_TYPE_IMAGE
1001 | w = ccall((:cairo_image_surface_get_width, libcairo),
1002 | Int32, (Ptr{Nothing},), ptr)
1003 | h = ccall((:cairo_image_surface_get_height, libcairo),
1004 | Int32, (Ptr{Nothing},), ptr)
1005 | end
1006 | return CairoSurface(ptr, w, h)
1007 | end
1008 |
1009 | function destroy(pat::CairoPattern)
1010 | if pat.ptr == C_NULL
1011 | return
1012 | end
1013 | ccall((:cairo_pattern_destroy,libcairo), Nothing, (Ptr{Nothing},), pat.ptr)
1014 | pat.ptr = C_NULL
1015 | nothing
1016 | end
1017 |
1018 | # mesh pattern
1019 |
1020 | # create mesh pattern
1021 | function CairoPatternMesh()
1022 | ptr = ccall((:cairo_pattern_create_mesh, libcairo),
1023 | Ptr{Nothing}, ())
1024 | pattern = CairoPattern(ptr)
1025 | #status = ccall((:cairo_pattern_status, libcairo),
1026 | # Cint, (Ptr{Nothing},), pattern.ptr)
1027 | #if status != 0
1028 | # error("Error creating Cairo pattern: ", bytestring(
1029 | # ccall((:cairo_status_to_string, libcairo),
1030 | # Ptr{Uint8}, (Cint,), status)))
1031 | #end
1032 | finalizer(destroy, pattern)
1033 | pattern
1034 | end
1035 |
1036 | #for (NAME, FUNCTION) in Any[(:set_line_width, :cairo_set_line_width),
1037 | # (:rotate, :cairo_rotate),
1038 | # (:set_font_size, :cairo_set_font_size)]
1039 | # @eval begin
1040 | # $NAME(ctx::CairoContext, d0::Real) =
1041 | # ccall(($(Expr(:quote,FUNCTION)),libcairo),
1042 | # Nothing, (Ptr{Nothing},Float64), ctx.ptr, d0)
1043 | # end
1044 | #end
1045 |
1046 | for (NAME, FUNCTION) in Any[(:mesh_pattern_begin_patch, :cairo_mesh_pattern_begin_patch),
1047 | (:mesh_pattern_end_patch, :cairo_mesh_pattern_end_patch)]
1048 | @eval begin
1049 | $NAME(pattern::CairoPattern) =
1050 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
1051 | Nothing, (Ptr{Nothing},), pattern.ptr)
1052 | end
1053 | end
1054 |
1055 | for (NAME, FUNCTION) in Any[(:mesh_pattern_line_to, :cairo_mesh_pattern_line_to),
1056 | (:mesh_pattern_move_to, :cairo_mesh_pattern_move_to)]
1057 | @eval begin
1058 | $NAME(pattern::CairoPattern, d0::Real, d1::Real) =
1059 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
1060 | Nothing, (Ptr{Nothing},Float64,Float64), pattern.ptr, d0, d1)
1061 | end
1062 | end
1063 |
1064 | for (NAME, FUNCTION) in Any[(:mesh_pattern_curve_to, :cairo_mesh_pattern_curve_to)]
1065 |
1066 | @eval begin
1067 | $NAME(pattern::CairoPattern, d0::Real, d1::Real, d2::Real, d3::Real, d4::Real, d5::Real) =
1068 | ccall(($(Expr(:quote,FUNCTION)),libcairo),
1069 | Nothing, (Ptr{Nothing},Float64,Float64,Float64,Float64,Float64,Float64), pattern.ptr, d0, d1, d2, d3, d4, d5)
1070 | end
1071 | end
1072 |
1073 |
1074 | function mesh_pattern_set_corner_color_rgb(pat::CairoPattern, corner_num::Real, red::Real, green::Real, blue::Real)
1075 | ccall((:cairo_mesh_pattern_set_corner_color_rgb, libcairo),
1076 | Nothing, (Ptr{Nothing},Int32,Float64,Float64,Float64),pat.ptr,corner_num,red,green,blue)
1077 | end
1078 |
1079 | function mesh_pattern_set_corner_color_rgba(pat::CairoPattern, corner_num::Real, red::Real, green::Real, blue::Real, alpha::Real)
1080 | ccall((:cairo_mesh_pattern_set_corner_color_rgba, libcairo),
1081 | Nothing, (Ptr{Nothing},Int32,Float64,Float64,Float64,Float64),pat.ptr,corner_num,red,green,blue,alpha)
1082 | end
1083 |
1084 | # ----
1085 |
1086 | set_antialias(ctx::CairoContext, a) =
1087 | ccall((:cairo_set_antialias,libcairo), Nothing,
1088 | (Ptr{Nothing},Cint), ctx.ptr, a)
1089 |
1090 | get_antialias(ctx::CairoContext) =
1091 | ccall((:cairo_get_antialias,libcairo), Cint,
1092 | (Ptr{Nothing},), ctx.ptr)
1093 |
1094 | # -----------------------------------------------------------------------------
1095 |
1096 | struct CairoMatrix
1097 | xx::Float64
1098 | yx::Float64
1099 | xy::Float64
1100 | yy::Float64
1101 | x0::Float64
1102 | y0::Float64
1103 | end
1104 |
1105 | CairoMatrix() = CairoMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
1106 |
1107 | function get_matrix(ctx::CairoContext)
1108 | m = [CairoMatrix()]
1109 | ccall((:cairo_get_matrix, libcairo), Nothing, (Ptr{Nothing}, Ptr{Nothing}), ctx.ptr, m)
1110 | m[1]
1111 | end
1112 |
1113 | function set_matrix(ctx::CairoContext, m::CairoMatrix)
1114 | ccall((:cairo_set_matrix, libcairo), Nothing, (Ptr{Nothing}, Ptr{Nothing}), ctx.ptr, [m])
1115 | end
1116 |
1117 | function set_matrix(p::CairoPattern, m::CairoMatrix)
1118 | ccall((:cairo_pattern_set_matrix, libcairo), Nothing, (Ptr{Nothing}, Ptr{Nothing}), p.ptr, [m])
1119 | end
1120 |
1121 |
1122 | # -----------------------------------------------------------------------------
1123 | function set_line_type(ctx::CairoContext, nick::AbstractString)
1124 | if nick == "solid"
1125 | dash = Float64[]
1126 | elseif nick == "dotted" || nick == "dot"
1127 | dash = [1.,3.]
1128 | elseif nick == "dotdashed"
1129 | dash = [1.,3.,4.,4.]
1130 | elseif nick == "longdashed"
1131 | dash = [6.,6.]
1132 | elseif nick == "shortdashed" || nick == "dash" || nick == "dashed"
1133 | dash = [4.,4.]
1134 | elseif nick == "dotdotdashed"
1135 | dash = [1.,3.,1.,3.,4.,4.]
1136 | elseif nick == "dotdotdotdashed"
1137 | dash = [1.,3.,1.,3.,1.,3.,4.,4.]
1138 | else
1139 | error("unknown line type ", nick)
1140 | end
1141 | set_dash(ctx, dash)
1142 | end
1143 |
1144 | # -----------------------------------------------------------------------------
1145 | # text commands
1146 |
1147 | function set_font_face(ctx::CairoContext, str::AbstractString)
1148 | fontdesc = ccall((:pango_font_description_from_string,libpango),
1149 | Ptr{Nothing}, (Ptr{UInt8},), String(str))
1150 | ccall((:pango_layout_set_font_description,libpango), Nothing,
1151 | (Ptr{Nothing},Ptr{Nothing}), ctx.layout, fontdesc)
1152 | ccall((:pango_font_description_free,libpango), Nothing,
1153 | (Ptr{Nothing},), fontdesc)
1154 | end
1155 |
1156 | function set_text(ctx::CairoContext, text::AbstractString, markup::Bool = false)
1157 | if markup
1158 | ccall((:pango_layout_set_markup,libpango), Nothing,
1159 | (Ptr{Nothing},Ptr{UInt8},Int32), ctx.layout, String(text), -1)
1160 | else
1161 | # clear attributes (from previous set markups)
1162 | ccall((:pango_layout_set_attributes,libpango), Nothing,
1163 | (Ptr{Nothing},Ptr{Nothing}), ctx.layout, C_NULL)
1164 |
1165 | ccall((:pango_layout_set_text,libpango), Nothing,
1166 | (Ptr{Nothing},Ptr{UInt8},Int32), ctx.layout, String(text), -1)
1167 | end
1168 | text
1169 | end
1170 |
1171 | function get_layout_size(ctx::CairoContext)
1172 | w = Vector{Int32}(undef, 2)
1173 | ccall((:pango_layout_get_pixel_size,libpango), Nothing,
1174 | (Ptr{Nothing},Ptr{Int32},Ptr{Int32}), ctx.layout, pointer(w,1), pointer(w,2))
1175 | w
1176 | end
1177 |
1178 | function update_layout(ctx::CairoContext)
1179 | ccall((:pango_cairo_update_layout,libpangocairo), Nothing,
1180 | (Ptr{Nothing},Ptr{Nothing}), ctx.ptr, ctx.layout)
1181 | end
1182 |
1183 | function show_layout(ctx::CairoContext)
1184 | ccall((:pango_cairo_show_layout,libpangocairo), Nothing,
1185 | (Ptr{Nothing},Ptr{Nothing}), ctx.ptr, ctx.layout)
1186 | end
1187 |
1188 | text_extents(ctx::CairoContext,value::AbstractString) =
1189 | text_extents!(ctx,value, Matrix{Float64}(undef, 6, 1))
1190 |
1191 | function text_extents!(ctx::CairoContext,value::AbstractString,extents)
1192 | ccall((:cairo_text_extents, libcairo),
1193 | Nothing, (Ptr{Nothing}, Ptr{UInt8}, Ptr{Float64}),
1194 | ctx.ptr, String(value), extents)
1195 | extents
1196 | end
1197 |
1198 | function path_extents(ctx::CairoContext)
1199 | dx1 = Cdouble[0]
1200 | dx2 = Cdouble[0]
1201 | dy1 = Cdouble[0]
1202 | dy2 = Cdouble[0]
1203 |
1204 | ccall((:cairo_path_extents, libcairo),
1205 | Nothing, (Ptr{Nothing}, Ptr{Cdouble}, Ptr{Cdouble},
1206 | Ptr{Cdouble}, Ptr{Cdouble}),
1207 | ctx.ptr, dx1, dy1, dx2, dy2)
1208 |
1209 | return(dx1[1],dy1[1],dx2[1],dy2[1])
1210 | end
1211 |
1212 |
1213 | function show_text(ctx::CairoContext,value::AbstractString)
1214 | ccall((:cairo_show_text, libcairo),
1215 | Nothing, (Ptr{Nothing}, Ptr{UInt8}),
1216 | ctx.ptr, String(value))
1217 | end
1218 |
1219 | function text_path(ctx::CairoContext,value::AbstractString)
1220 | ccall((:cairo_text_path, libcairo),
1221 | Nothing, (Ptr{Nothing}, Ptr{UInt8}),
1222 | ctx.ptr, String(value))
1223 | end
1224 |
1225 |
1226 | function select_font_face(ctx::CairoContext,family::AbstractString,slant,weight)
1227 | ccall((:cairo_select_font_face, libcairo),
1228 | Nothing, (Ptr{Nothing}, Ptr{UInt8},
1229 | font_slant_t, font_weight_t),
1230 | ctx.ptr, String(family),
1231 | slant, weight)
1232 | end
1233 |
1234 | function align2offset(a::AbstractString)
1235 | if a == "center" return 0.5
1236 | elseif a == "left" return 0.0
1237 | elseif a == "right" return 1.0
1238 | elseif a == "top" return 0.0
1239 | elseif a == "bottom" return 1.0
1240 | end
1241 | @assert false
1242 | end
1243 |
1244 | function text(ctx::CairoContext, x::Real, y::Real, str::AbstractString;
1245 | halign::AbstractString = "left", valign::AbstractString = "bottom", angle::Real = 0, markup::Bool=false)
1246 | move_to(ctx, x, y)
1247 | save(ctx)
1248 | reset_transform(ctx)
1249 | rotate(ctx, -angle*pi/180.)
1250 |
1251 | set_text(ctx, str, markup)
1252 | update_layout(ctx)
1253 |
1254 | extents = get_layout_size(ctx)
1255 | dxrel = -align2offset(halign)
1256 | dyrel = align2offset(valign)
1257 | rel_move_to(ctx, dxrel*extents[1], -dyrel*extents[2])
1258 |
1259 | show_layout(ctx)
1260 | restore(ctx)
1261 | w, h = Graphics.device_to_user(ctx, extents[1], extents[2])
1262 | BoundingBox(x+dxrel*w, x+(dxrel+1)*w, y-dyrel*h, y+(1-dyrel)*h)
1263 | end
1264 |
1265 | function textwidth(ctx::CairoContext, str::AbstractString, markup::Bool = false)
1266 | set_text(ctx, str, markup)
1267 | extents = get_layout_size(ctx)
1268 | extents[1]
1269 | end
1270 |
1271 | function textheight(ctx::CairoContext, str::AbstractString, markup::Bool = false)
1272 | set_text(ctx, str, markup)
1273 | extents = get_layout_size(ctx)
1274 | extents[2]
1275 | end
1276 |
1277 | set_latex(ctx::CairoContext, str::AbstractString, fontsize::Real) = set_text(ctx, tex2pango(str, fontsize), true)
1278 |
1279 | mutable struct TeXLexer
1280 | str::String
1281 | len::Int
1282 | pos::Int
1283 | token_stack::Array{String,1}
1284 |
1285 | function TeXLexer(str::AbstractString)
1286 | s = String(str)
1287 | new(s, lastindex(s), 1, String[])
1288 | end
1289 | end
1290 |
1291 | function get_token(self::TeXLexer)
1292 | if self.pos > self.len
1293 | return nothing
1294 | end
1295 |
1296 | if length(self.token_stack) > 0
1297 | return pop!(self.token_stack)
1298 | end
1299 |
1300 | str = self.str[self.pos:end]
1301 | re_control_sequence = r"^\\[a-zA-Z]+[ ]?|^\\[^a-zA-Z][ ]?"
1302 | m = match(re_control_sequence, str)
1303 | if m !== nothing
1304 | token = m.match
1305 | self.pos = self.pos + sizeof(token)
1306 | # consume trailing space
1307 | if length(token) > 2 && token[end] == ' '
1308 | token = token[1:end-1]
1309 | end
1310 | else
1311 | @static if VERSION >= v"0.7"
1312 | token, self.pos = iterate(self.str, self.pos)
1313 | else
1314 | token, self.pos = next(self.str, self.pos)
1315 | end
1316 | token = string(token)
1317 | end
1318 |
1319 | return token
1320 | end
1321 |
1322 | function put_token(self::TeXLexer, token)
1323 | push!(self.token_stack, token)
1324 | end
1325 |
1326 | function peek(self::TeXLexer)
1327 | token = get_token(self)
1328 | put_token(self, token)
1329 | return token
1330 | end
1331 |
1332 | function map_text_token(token::AbstractString)
1333 | if haskey(_text_token_dict, token)
1334 | return _text_token_dict[token]
1335 | else
1336 | return get(_common_token_dict, token, token)
1337 | end
1338 | end
1339 |
1340 | function map_math_token(token::AbstractString)
1341 | if haskey(_math_token_dict, token)
1342 | return _math_token_dict[token]
1343 | else
1344 | return get(_common_token_dict, token, token)
1345 | end
1346 | end
1347 |
1348 | function math_group(lexer::TeXLexer)
1349 | output = ""
1350 | bracketmode = false
1351 | while true
1352 | token = get_token(lexer)
1353 | if token == nothing
1354 | break
1355 | end
1356 |
1357 | if token == "{"
1358 | bracketmode = true
1359 | elseif token == "}"
1360 | break
1361 | else
1362 | output = string(output, map_math_token(token))
1363 | if !bracketmode
1364 | break
1365 | end
1366 | end
1367 | end
1368 | return output
1369 | end
1370 |
1371 | #font_code = [ "\\f0", "\\f1", "\\f2", "\\f3" ]
1372 |
1373 | function tex2pango(str::AbstractString, fontsize::Real)
1374 | output = ""
1375 | mathmode = true
1376 | font_stack = Any[]
1377 | font = 1
1378 | script_size = fontsize/1.618034
1379 |
1380 | lexer = TeXLexer(str)
1381 | while true
1382 | token = get_token(lexer)
1383 | if token == nothing
1384 | break
1385 | end
1386 |
1387 | more_output = ""
1388 |
1389 | if token == "\$"
1390 | # mathmode = !mathmode
1391 | more_output = "\$"
1392 | elseif token == "{"
1393 | push!(font_stack, font)
1394 | elseif token == "}"
1395 | old_font = pop!(font_stack)
1396 | if old_font != font
1397 | font = old_font
1398 | # more_output = font_code[font]
1399 | end
1400 | elseif token == "\\rm"
1401 | font = 1
1402 | # more_output = font_code[font]
1403 | elseif token == "\\it"
1404 | font = 2
1405 | # more_output = font_code[font]
1406 | elseif token == "\\bf"
1407 | font = 3
1408 | # more_output = font_code[font]
1409 | elseif !mathmode
1410 | more_output = map_text_token(token)
1411 | elseif token == "_"
1412 | more_output = string("", math_group(lexer), "")
1413 | #if peek(lexer) == "^"
1414 | # more_output = string("\\mk", more_output, "\\rt")
1415 | #end
1416 | elseif token == "^"
1417 | more_output = string("", math_group(lexer), "")
1418 | #if peek(lexer) == "_"
1419 | # more_output = string("\\mk", more_output, "\\rt")
1420 | #end
1421 | else
1422 | more_output = map_math_token(token)
1423 | end
1424 |
1425 | output = string(output, more_output)
1426 | end
1427 | return output
1428 | end
1429 |
1430 |
1431 | @deprecate text(ctx::CairoContext,x::Real,y::Real,str::AbstractString,fontsize::Real,halign::AbstractString,valign,angle) text(ctx,x,y,set_latex(ctx,str,fontsize),halign=halign,valign=valign,angle=angle,markup=true)
1432 | @deprecate layout_text(ctx::CairoContext, str::AbstractString, fontsize::Real) set_latex(ctx, str, fontsize)
1433 | @deprecate textwidth(ctx::CairoContext, str::AbstractString, fontsize::Real) textwidth(ctx, tex2pango(str, fontsize), true)
1434 | @deprecate textheight(ctx::CairoContext, str::AbstractString, fontsize::Real) textheight(ctx, tex2pango(str, fontsize), true)
1435 | @deprecate cairo_write_to_ios_callback(s::Ptr{Nothing}, buf::Ptr{UInt8}, len::UInt32) write_to_ios_callback(s, buf, len)
1436 | @deprecate cairo_write_to_stream_callback(s::IO, buf::Ptr{UInt8}, len::UInt32) write_to_stream_callback(s, buf, len)
1437 | @deprecate text_extents(ctx::CairoContext,value::AbstractString,extents) text_extents!(ctx,value,extents)
1438 |
1439 | end # module
1440 |
--------------------------------------------------------------------------------