1 /* libmypaint - The MyPaint Brush Library
2  * Copyright (C) 2008 Martin Renold <martinxyz@gmx.ch>
3  * Copyright (C) 2012 Jon Nordby <jononor@gmail.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "config.h"
19 
20 #include <assert.h>
21 
22 #include "mypaint-surface.h"
23 
24 #include "helpers.h"
25 
26 
27 /**
28  * MyPaintSurface:
29  */
30 struct MyPaintSurface2;
31 
32 /**
33   * mypaint_surface_draw_dab:
34   *
35   * Draw a dab onto the surface.
36   */
37 int
mypaint_surface_draw_dab(MyPaintSurface * self,float x,float y,float radius,float color_r,float color_g,float color_b,float opaque,float hardness,float alpha_eraser,float aspect_ratio,float angle,float lock_alpha,float colorize)38 mypaint_surface_draw_dab(MyPaintSurface *self,
39                        float x, float y,
40                        float radius,
41                        float color_r, float color_g, float color_b,
42                        float opaque, float hardness,
43                        float alpha_eraser,
44                        float aspect_ratio, float angle,
45                        float lock_alpha,
46                        float colorize
47                        )
48 {
49     assert(self->draw_dab);
50     return self->draw_dab(self, x, y, radius, color_r, color_g, color_b,
51                    opaque, hardness, alpha_eraser, aspect_ratio, angle,
52                    lock_alpha, colorize);
53 }
54 
55 void
mypaint_surface_get_color(MyPaintSurface * self,float x,float y,float radius,float * color_r,float * color_g,float * color_b,float * color_a)56 mypaint_surface_get_color(MyPaintSurface *self,
57                         float x, float y,
58                         float radius,
59                         float * color_r, float * color_g, float * color_b, float * color_a
60                         )
61 {
62     assert(self->get_color);
63     self->get_color(self, x, y, radius, color_r, color_g, color_b, color_a);
64 }
65 
66 
67 /**
68  * mypaint_surface_init: (skip)
69  *
70  * Initialize the surface. The reference count will be set to 1.
71  * Note: Only intended to be called from subclasses of #MyPaintSurface
72  **/
73 void
mypaint_surface_init(MyPaintSurface * self)74 mypaint_surface_init(MyPaintSurface *self)
75 {
76     self->refcount = 1;
77 }
78 
79 /**
80  * mypaint_surface_ref: (skip)
81  *
82  * Increase the reference count.
83  **/
84 void
mypaint_surface_ref(MyPaintSurface * self)85 mypaint_surface_ref(MyPaintSurface *self)
86 {
87     self->refcount++;
88 }
89 
90 /**
91  * mypaint_surface_unref: (skip)
92  *
93  * Decrease the reference count.
94  **/
95 void
mypaint_surface_unref(MyPaintSurface * self)96 mypaint_surface_unref(MyPaintSurface *self)
97 {
98     self->refcount--;
99     if (self->refcount == 0) {
100         assert(self->destroy);
101         self->destroy(self);
102     }
103 }
104 
mypaint_surface_get_alpha(MyPaintSurface * self,float x,float y,float radius)105 float mypaint_surface_get_alpha (MyPaintSurface *self, float x, float y, float radius)
106 {
107     float color_r, color_g, color_b, color_a;
108     mypaint_surface_get_color(self, x, y, radius, &color_r, &color_g, &color_b, &color_a);
109     return color_a;
110 }
111 
112 void
mypaint_surface_save_png(MyPaintSurface * self,const char * path,int x,int y,int width,int height)113 mypaint_surface_save_png(MyPaintSurface *self, const char *path, int x, int y, int width, int height)
114 {
115     if (self->save_png) {
116         self->save_png(self, path, x, y, width, height);
117     }
118 }
119 
120 void
mypaint_surface_begin_atomic(MyPaintSurface * self)121 mypaint_surface_begin_atomic(MyPaintSurface *self)
122 {
123     if (self->begin_atomic)
124         self->begin_atomic(self);
125 }
126 
127 /**
128  * mypaint_surface_end_atomic:
129  * @roi: (out) (allow-none) (transfer none): Invalidation rectangle
130  *
131  * Returns: s
132  */
133 void
mypaint_surface_end_atomic(MyPaintSurface * self,MyPaintRectangle * roi)134 mypaint_surface_end_atomic(MyPaintSurface *self, MyPaintRectangle *roi)
135 {
136     assert(self->end_atomic);
137     self->end_atomic(self, roi);
138 }
139 
140 
141 /* -- Extended interface -- */
142 
143 // The extended interface is not exposed via GObject introspection
144 
145 
146 /**
147  * MyPaintSurface2: (skip)
148  */
149 struct MyPaintSurface2;
150 
151 /**
152  * mypaint_surface2_to_surface: (skip)
153  *
154  * Access the parent MyPaintSurface.
155  *
156  */
mypaint_surface2_to_surface(MyPaintSurface2 * self)157 MyPaintSurface* mypaint_surface2_to_surface(MyPaintSurface2 *self)
158 {
159   return &self->parent;
160 }
161 
162 /**
163  * mypaint_surface2_get_color: (skip)
164  */
165 void
mypaint_surface2_get_color(MyPaintSurface2 * self,float x,float y,float radius,float * color_r,float * color_g,float * color_b,float * color_a,float paint)166 mypaint_surface2_get_color(
167   MyPaintSurface2 *self,
168   float x, float y,
169   float radius,
170   float * color_r, float * color_g, float * color_b, float * color_a,
171   float paint
172   )
173 {
174     assert(self->get_color_pigment);
175     self->get_color_pigment(self, x, y, radius, color_r, color_g, color_b, color_a, paint);
176 }
177 
178 /**
179  * mypaint_surface2_draw_dab: (skip)
180  *
181  * Draw a dab with support for posterization and spectral blending.
182  */
183 int
mypaint_surface2_draw_dab(MyPaintSurface2 * self,float x,float y,float radius,float color_r,float color_g,float color_b,float opaque,float hardness,float alpha_eraser,float aspect_ratio,float angle,float lock_alpha,float colorize,float posterize,float posterize_num,float paint)184 mypaint_surface2_draw_dab(
185   MyPaintSurface2 *self,
186   float x, float y,
187   float radius,
188   float color_r, float color_g, float color_b,
189   float opaque, float hardness,
190   float alpha_eraser,
191   float aspect_ratio, float angle,
192   float lock_alpha,
193   float colorize,
194   float posterize,
195   float posterize_num,
196   float paint
197   )
198 {
199     assert(self->draw_dab_pigment);
200     return self->draw_dab_pigment(
201       self, x, y, radius, color_r, color_g, color_b,
202       opaque, hardness, alpha_eraser, aspect_ratio, angle,
203       lock_alpha, colorize, posterize, posterize_num, paint
204       );
205 }
206 
207 
208 /**
209  * mypaint_surface2_end_atomic: (skip)
210  * @roi: (out) (allow-none) (transfer none): Invalidated rectangles will be stored here.
211  * The value of roi->num_rectangles must be at least 1, and roi->rectangles must point to
212  * sufficient accessible memory to contain n = roi->num_rectangles of MyPaintRectangle structs.
213  *
214  * Returns: s
215  */
216 void
mypaint_surface2_end_atomic(MyPaintSurface2 * self,MyPaintRectangles * roi)217 mypaint_surface2_end_atomic(MyPaintSurface2 *self, MyPaintRectangles *roi)
218 {
219     assert(self->end_atomic_multi);
220     self->end_atomic_multi(self, roi);
221 }
222