summaryrefslogtreecommitdiff
path: root/src/ml_cairo_matrix.c
blob: 17ecff53093972cabc0d0089a172fced6ff79697 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**************************************************************************/
/*  cairo-ocaml -- Objective Caml bindings for Cairo                      */
/*  Copyright © 2004-2005 Olivier Andrieu                                 */
/*                                                                        */
/*  This code is free software and is licensed under the terms of the     */
/*  GNU Lesser General Public License version 2.1 (the "LGPL").           */
/**************************************************************************/

#include "ml_cairo.h"

#ifdef ARCH_ALIGN_DOUBLE
void
ml_convert_cairo_matrix_in (value v, cairo_matrix_t *mat)
{
  mat->xx = Double_field (v, 0);
  mat->yx = Double_field (v, 1);
  mat->xy = Double_field (v, 2);
  mat->yy = Double_field (v, 3);
  mat->x0 = Double_field (v, 4);
  mat->y0 = Double_field (v, 5);
}

value
ml_convert_cairo_matrix_out (const cairo_matrix_t *mat)
{
  value v;
  v = caml_alloc_small (6 * Double_wosize, Double_array_tag);
  Store_double_field (v, 0, mat->xx);
  Store_double_field (v, 1, mat->yx);
  Store_double_field (v, 2, mat->xy);
  Store_double_field (v, 3, mat->yy);
  Store_double_field (v, 4, mat->x0);
  Store_double_field (v, 5, mat->y0);
  return v;
}
#endif

/* matrix_init */
/* matrix_init_identity */
/* matrix_init_translate */
/* matrix_init_scale */
/* matrix_init_rotate */

CAMLprim value
ml_cairo_matrix_translate (value m, value x, value y)
{
#ifndef ARCH_ALIGN_DOUBLE
  CAMLparam3(m, x, y);
  value v = cairo_matrix_alloc();
  cairo_copy_matrix (v, m);
  cairo_matrix_translate (cairo_matrix_t_val (v), Double_val (x), Double_val (y));
  CAMLreturn (v);
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (m, &mat);
  cairo_matrix_translate (&mat, Double_val (x), Double_val (y));
  return ml_convert_cairo_matrix_out (&mat);
#endif
}

CAMLprim value
ml_cairo_matrix_scale (value m, value x, value y)
{
#ifndef ARCH_ALIGN_DOUBLE
  CAMLparam3(m, x, y);
  value v = cairo_matrix_alloc();
  cairo_copy_matrix (v, m);
  cairo_matrix_scale (cairo_matrix_t_val (v), Double_val (x), Double_val (y));
  CAMLreturn (v);
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (m, &mat);
  cairo_matrix_scale (&mat, Double_val (x), Double_val (y));
  return ml_convert_cairo_matrix_out (&mat);
#endif
}

CAMLprim value
ml_cairo_matrix_rotate (value m, value a)
{
#ifndef ARCH_ALIGN_DOUBLE
  CAMLparam2(m, a);
  value v = cairo_matrix_alloc();
  cairo_copy_matrix (v, m);
  cairo_matrix_rotate (cairo_matrix_t_val (v), Double_val (a));
  CAMLreturn (v);
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (m, &mat);
  cairo_matrix_rotate (&mat, Double_val (a));
  return ml_convert_cairo_matrix_out (&mat);
#endif
}

CAMLprim value
ml_cairo_matrix_invert (value m)
{
#ifndef ARCH_ALIGN_DOUBLE
  CAMLparam1(m);
  value v = cairo_matrix_alloc();
  cairo_copy_matrix (v, m);
  cairo_matrix_invert (cairo_matrix_t_val (v));
  CAMLreturn (v);
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (m, &mat);
  cairo_matrix_invert (&mat);
  return ml_convert_cairo_matrix_out (&mat);
#endif
}

CAMLprim value
ml_cairo_matrix_multiply (value a, value b)
{
#ifndef ARCH_ALIGN_DOUBLE
  CAMLparam2(a, b);
  value r = cairo_matrix_alloc();
  cairo_matrix_multiply (cairo_matrix_t_val (r),
			 cairo_matrix_t_val (a),
			 cairo_matrix_t_val (b));
  CAMLreturn (r);
#else
  cairo_matrix_t r, m_a, m_b;
  ml_convert_cairo_matrix_in (a, &m_a);
  ml_convert_cairo_matrix_in (b, &m_b);
  cairo_matrix_multiply (&r, &m_a, &m_b);
  return ml_convert_cairo_matrix_out (&r);
#endif
}

CAMLprim value
ml_cairo_matrix_transform_distance (value m, value p)
{
  double x = Double_field (p, 0);
  double y = Double_field (p, 1);
#ifndef ARCH_ALIGN_DOUBLE
  cairo_matrix_transform_distance (cairo_matrix_t_val (m), &x, &y);
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (m, &mat);
  cairo_matrix_transform_distance (&mat, &x, &y);
#endif
  return ml_cairo_point (x, y);
}

CAMLprim value
ml_cairo_matrix_transform_point (value m, value p)
{
  double x = Double_field (p, 0);
  double y = Double_field (p, 1);
#ifndef ARCH_ALIGN_DOUBLE
  cairo_matrix_transform_point (cairo_matrix_t_val (m), &x, &y);
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (m, &mat);
  cairo_matrix_transform_point (&mat, &x, &y);
#endif
  return ml_cairo_point (x, y);
}