Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .projections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"lib/*.ex": {
"alternate": "test/{}_test.exs",
"type": "source",
"template": [
"defmodule {camelcase|capitalize|dot} do",
"end"
]
},
"test/*_test.exs": {
"alternate": "lib/{}.ex",
"type": "test",
"template": [
"defmodule {camelcase|capitalize|dot}Test do",
" use ExUnit.Case, async: true",
"",
" alias {camelcase|capitalize|dot}",
"end"
]
}
}
111 changes: 111 additions & 0 deletions lib/xairo/context.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
defmodule Xairo.Context do
@moduledoc false

defstruct [:context]

def new(%Xairo.ImageSurface{surface: surface}) do
with {:ok, context} <- Xairo.Native.context_new_from_image_surface(surface) do
%__MODULE__{
context: context
}
end
end

def status(%__MODULE__{context: ctx}) do
with {:ok, _} <- Xairo.Native.context_status(ctx), do: :ok
end

def set_source_rgb(%__MODULE__{context: ctx} = this, r, g, b) do
Xairo.Native.context_set_source_rgb(ctx, r / 1, g / 1, b / 1)
this
end

def set_source_rgba(%__MODULE__{context: ctx} = this, r, g, b, a) do
Xairo.Native.context_set_source_rgba(ctx, r / 1, g / 1, b / 1, a / 1)
this
end

def paint(%__MODULE__{context: ctx} = this) do
with {:ok, _} <- Xairo.Native.context_paint(ctx), do: this
end

def paint_with_alpha(%__MODULE__{context: ctx} = this, alpha) do
with {:ok, _} <- Xairo.Native.context_paint_with_alpha(ctx, alpha / 1), do: this
end

def stroke(%__MODULE__{context: ctx} = this) do
with {:ok, _} <- Xairo.Native.context_stroke(ctx), do: this
end

def stroke_preserve(%__MODULE__{context: ctx} = this) do
with {:ok, _} <- Xairo.Native.context_stroke_preserve(ctx), do: this
end

def fill(%__MODULE__{context: ctx} = this) do
with {:ok, _} <- Xairo.Native.context_fill(ctx), do: this
end

def fill_preserve(%__MODULE__{context: ctx} = this) do
with {:ok, _} <- Xairo.Native.context_fill_preserve(ctx), do: this
end

def move_to(%__MODULE__{context: ctx} = this, x, y) do
Xairo.Native.context_move_to(ctx, x / 1, y / 1)
this
end

def line_to(%__MODULE__{context: ctx} = this, x, y) do
Xairo.Native.context_line_to(ctx, x / 1, y / 1)
this
end

def curve_to(%__MODULE__{context: ctx} = this, x1, y1, x2, y2, x3, y3) do
Xairo.Native.context_curve_to(ctx, x1 / 1, y1 / 1, x2 / 1, y2 / 1, x3 / 1, y3 / 1)
this
end

def rel_move_to(%__MODULE__{context: ctx} = this, x, y) do
Xairo.Native.context_rel_move_to(ctx, x / 1, y / 1)
this
end

def rel_line_to(%__MODULE__{context: ctx} = this, x, y) do
Xairo.Native.context_rel_line_to(ctx, x / 1, y / 1)
this
end

def rel_curve_to(%__MODULE__{context: ctx} = this, x1, y1, x2, y2, x3, y3) do
Xairo.Native.context_rel_curve_to(ctx, x1 / 1, y1 / 1, x2 / 1, y2 / 1, x3 / 1, y3 / 1)
this
end

def arc(%__MODULE__{context: ctx} = this, cx, cy, r, a1, a2) do
Xairo.Native.context_arc(ctx, cx / 1, cy / 1, r / 1, a1 / 1, a2 / 1)
this
end

def arc_negative(%__MODULE__{context: ctx} = this, cx, cy, r, a1, a2) do
Xairo.Native.context_arc_negative(ctx, cx / 1, cy / 1, r / 1, a1 / 1, a2 / 1)
this
end

def new_path(%__MODULE__{context: ctx} = this) do
Xairo.Native.context_new_path(ctx)
this
end

def new_sub_path(%__MODULE__{context: ctx} = this) do
Xairo.Native.context_new_sub_path(ctx)
this
end

def rectangle(%__MODULE__{context: ctx} = this, x, y, w, h) do
Xairo.Native.context_rectangle(ctx, x / 1, y / 1, w / 1, h / 1)
this
end

def close_path(%__MODULE__{context: ctx} = this) do
Xairo.Native.context_close_path(ctx)
this
end
end
33 changes: 33 additions & 0 deletions lib/xairo/image_surface.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
defmodule Xairo.ImageSurface do
@moduledoc false

defstruct [:surface]

def new(format, width, height) do
with {:ok, image_surface} <- Xairo.Native.image_surface_create(format, width, height) do
%__MODULE__{
surface: image_surface
}
end
end

def format(%__MODULE__{surface: surface}) do
Xairo.Native.image_surface_format(surface)
end

def width(%__MODULE__{surface: surface}) do
Xairo.Native.image_surface_width(surface)
end

def height(%__MODULE__{surface: surface}) do
Xairo.Native.image_surface_height(surface)
end

def stride(%__MODULE__{surface: surface}) do
Xairo.Native.image_surface_stride(surface)
end

def write_to_png(%__MODULE__{surface: surface}, filename) do
Xairo.Native.image_surface_write_to_png(surface, filename)
end
end
32 changes: 32 additions & 0 deletions lib/xairo/native.ex
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,37 @@ defmodule Xairo.Native do

def set_surface_pattern_source(_i, _p), do: error()

def image_surface_create(_f, _w, _h), do: error()
def image_surface_format(_is), do: error()
def image_surface_width(_is), do: error()
def image_surface_height(_is), do: error()
def image_surface_stride(_is), do: error()
def image_surface_write_to_png(_is, _f), do: error()

def context_new_from_image_surface(_is), do: error()
def context_status(_c), do: error()
def context_set_source_rgb(_c, _r, _g, _b), do: error()
def context_set_source_rgba(_c, _r, _g, _b, _a), do: error()
def context_stroke(_c), do: error()
def context_stroke_preserve(_c), do: error()
def context_fill(_c), do: error()
def context_fill_preserve(_c), do: error()
def context_paint(_c), do: error()
def context_paint_with_alpha(_c, _a), do: error()
def context_move_to(_c, _x, _y), do: error()
def context_line_to(_c, _x, _y), do: error()
def context_rel_move_to(_c, _x, _y), do: error()
def context_rel_line_to(_c, _x, _y), do: error()
def context_rectangle(_c, _x, _y, _w, _h), do: error()
def context_close_path(_c), do: error()
def context_curve_to(_c, _x1, _y1, _x2, _y2, _x3, _y3), do: error()
def context_rel_curve_to(_c, _x1, _y1, _x2, _y2, _x3, _y3), do: error()
def context_arc(_c, _x, _y, _r, _a1, _a2), do: error()
def context_arc_negative(_c, _x, _y, _r, _a1, _a2), do: error()
def context_new_path(_c), do: error()
def context_new_sub_path(_c), do: error()

def stride_for_width(_f, _w), do: error()

defp error, do: :erlang.nif_error(:nif_not_loaded)
end
11 changes: 11 additions & 0 deletions lib/xairo/utilities.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule Xairo.Utilities do
@moduledoc false

def stride_for_width(format, width) do
case Xairo.Native.stride_for_width(format, width) do
{:ok, stride} -> stride
{:error, _} = error -> error
error -> {:error, error}
end
end
end
146 changes: 146 additions & 0 deletions native/xairo/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
use crate::error::XairoError;
use crate::image_surface::ImageSurface;
use rustler::ResourceArc;

pub struct ContextRaw {
pub context: cairo::Context,
}

unsafe impl Send for ContextRaw {}
unsafe impl Sync for ContextRaw {}

pub type Context = ResourceArc<ContextRaw>;

#[rustler::nif]
fn context_new_from_image_surface(surface: ImageSurface) -> Result<Context, XairoError> {
match cairo::Context::new(&surface.surface) {
Ok(context) => Ok(ResourceArc::new(ContextRaw { context })),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_status(context: Context) -> Result<(), XairoError> {
match context.context.status() {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_set_source_rgb(context: Context, r: f64, g: f64, b: f64) {
context.context.set_source_rgb(r, g, b);
}

#[rustler::nif]
fn context_set_source_rgba(context: Context, r: f64, g: f64, b: f64, a: f64) {
context.context.set_source_rgba(r, g, b, a);
}

#[rustler::nif]
fn context_paint(context: Context) -> Result<(), XairoError> {
match context.context.paint() {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_paint_with_alpha(context: Context, alpha: f64) -> Result<(), XairoError> {
match context.context.paint_with_alpha(alpha) {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_fill(context: Context) -> Result<(), XairoError> {
match context.context.fill() {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_fill_preserve(context: Context) -> Result<(), XairoError> {
match context.context.fill_preserve() {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_stroke(context: Context) -> Result<(), XairoError> {
match context.context.stroke() {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_stroke_preserve(context: Context) -> Result<(), XairoError> {
match context.context.stroke_preserve() {
Ok(_) => Ok(()),
Err(err) => Err(err.into()),
}
}

#[rustler::nif]
fn context_move_to(context: Context, x: f64, y: f64) {
context.context.move_to(x, y);
}

#[rustler::nif]
fn context_rel_move_to(context: Context, x: f64, y: f64) {
context.context.rel_move_to(x, y);
}

#[rustler::nif]
fn context_line_to(context: Context, x: f64, y: f64) {
context.context.line_to(x, y);
}

#[rustler::nif]
fn context_rel_line_to(context: Context, x: f64, y: f64) {
context.context.rel_line_to(x, y);
}

#[rustler::nif]
fn context_rectangle(context: Context, x: f64, y: f64, w: f64, h: f64) {
context.context.rectangle(x, y, w, h);
}

#[rustler::nif]
fn context_close_path(context: Context) {
context.context.close_path();
}

#[rustler::nif]
fn context_curve_to(context: Context, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) {
context.context.curve_to(x1, y1, x2, y2, x3, y3);
}

#[rustler::nif]
fn context_rel_curve_to(context: Context, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64, y3: f64) {
context.context.rel_curve_to(x1, y1, x2, y2, x3, y3);
}

#[rustler::nif]
fn context_arc(context: Context, cx: f64, cy: f64, r: f64, a1: f64, a2: f64) {
context.context.arc(cx, cy, r, a1, a2);
}

#[rustler::nif]
fn context_arc_negative(context: Context, cx: f64, cy: f64, r: f64, a1: f64, a2: f64) {
context.context.arc_negative(cx, cy, r, a1, a2);
}

#[rustler::nif]
fn context_new_path(context: Context) {
context.context.new_path();
}

#[rustler::nif]
fn context_new_sub_path(context: Context) {
context.context.new_sub_path();
}
Loading