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
|
# File 'ext/psd_native/mask.c', line 3
VALUE psd_native_mask_apply_bang(VALUE self) {
psd_logger("debug", "Applying mask with native code");
int doc_width = FIX2INT(rb_iv_get(self, "@doc_width"));
int doc_height = FIX2INT(rb_iv_get(self, "@doc_height"));
VALUE layer = rb_iv_get(self, "@layer");
VALUE canvas = rb_iv_get(self, "@canvas");
VALUE mask = rb_funcall(layer, rb_intern("mask"), 0);
VALUE *mask_data = RARRAY_PTR(rb_funcall(rb_funcall(layer, rb_intern("image"), 0), rb_intern("mask_data"), 0));
int mask_height = FIX2INT(rb_funcall(mask, rb_intern("height"), 0));
int mask_width = FIX2INT(rb_funcall(mask, rb_intern("width"), 0));
int mask_left = FIX2INT(rb_funcall(mask, rb_intern("left"), 0));
int mask_top = FIX2INT(rb_funcall(mask, rb_intern("top"), 0));
int layer_height = FIX2INT(rb_funcall(layer, rb_intern("height"), 0));
int layer_width = FIX2INT(rb_funcall(layer, rb_intern("width"), 0));
int layer_left = FIX2INT(rb_funcall(layer, rb_intern("left"), 0));
int layer_top = FIX2INT(rb_funcall(layer, rb_intern("top"), 0));
PIXEL color;
int x, y, doc_x, doc_y, layer_x, layer_y, alpha;
int i = 0;
for (y = 0; y < mask_height; y++) {
for (x = 0; x < mask_width; x++) {
doc_x = mask_left + x;
doc_y = mask_top + y;
layer_x = doc_x - layer_left;
layer_y = doc_y - layer_top;
if (layer_x < 0 || layer_x >= layer_width || layer_y < 0 || layer_y >= layer_height) continue;
color = FIX2UINT(rb_funcall(canvas, rb_intern("[]"), 2, INT2FIX(layer_x), INT2FIX(layer_y)));
if (doc_x < 0 || doc_x >= doc_width || doc_y < 0 || doc_y > doc_height) {
alpha = 0;
} else {
alpha = mask_data[i];
}
color = (color & 0xffffff00) | (A(color) * alpha / 255);
rb_funcall(canvas, rb_intern("[]="), 3, INT2FIX(layer_x), INT2FIX(layer_y), INT2FIX(color));
i++;
}
}
return Qnil;
}
|