summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/image.cpp57
-rw-r--r--core/image.h1
-rw-r--r--core/variant_op.cpp42
3 files changed, 80 insertions, 20 deletions
diff --git a/core/image.cpp b/core/image.cpp
index e0cf82d920..023a058667 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1646,6 +1646,62 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
}
}
+void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
+
+ ERR_FAIL_COND(p_src.is_null());
+ ERR_FAIL_COND(p_mask.is_null());
+ int dsize = data.size();
+ int srcdsize = p_src->data.size();
+ int maskdsize = p_mask->data.size();
+ ERR_FAIL_COND(dsize == 0);
+ ERR_FAIL_COND(srcdsize == 0);
+ ERR_FAIL_COND(maskdsize == 0);
+ ERR_FAIL_COND(p_src->width != p_mask->width);
+ ERR_FAIL_COND(p_src->height != p_mask->height);
+ ERR_FAIL_COND(format != p_src->format);
+
+ Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ return;
+
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+
+ PoolVector<uint8_t>::Write wp = data.write();
+ uint8_t *dst_data_ptr = wp.ptr();
+
+ PoolVector<uint8_t>::Read rp = p_src->data.read();
+ const uint8_t *src_data_ptr = rp.ptr();
+
+ int pixel_size = get_format_pixel_size(format);
+
+ Ref<Image> msk = p_mask;
+ msk->lock();
+
+ for (int i = 0; i < dest_rect.size.y; i++) {
+
+ for (int j = 0; j < dest_rect.size.x; j++) {
+
+ int src_x = clipped_src_rect.position.x + j;
+ int src_y = clipped_src_rect.position.y + i;
+
+ if (msk->get_pixel(src_x, src_y).a != 0) {
+
+ int dst_x = dest_rect.position.x + j;
+ int dst_y = dest_rect.position.y + i;
+
+ const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size];
+ uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size];
+
+ for (int k = 0; k < pixel_size; k++) {
+ dst[k] = src[k];
+ }
+ }
+ }
+ }
+
+ msk->unlock();
+}
+
void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
ERR_FAIL_COND(p_src.is_null());
@@ -2199,6 +2255,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy);
ClassDB::bind_method(D_METHOD("blit_rect", "src:Image", "src_rect", "dst"), &Image::blit_rect);
+ ClassDB::bind_method(D_METHOD("blit_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blit_rect_mask);
ClassDB::bind_method(D_METHOD("blend_rect", "src:Image", "src_rect", "dst"), &Image::blend_rect);
ClassDB::bind_method(D_METHOD("blend_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blend_rect_mask);
ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill);
diff --git a/core/image.h b/core/image.h
index 3323afdc4b..e523f703fa 100644
--- a/core/image.h
+++ b/core/image.h
@@ -283,6 +283,7 @@ public:
void normalmap_to_xy();
void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+ void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
void fill(const Color &c);
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 7b2d0f6886..a463a5a23f 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -2236,30 +2236,30 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
return _data._int > 0;
} break;
case REAL: {
- r_iter = 0.0;
+ r_iter = 0;
return _data._real > 0.0;
} break;
case VECTOR2: {
- real_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
- real_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+ int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
+ int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
r_iter = from;
return from < to;
} break;
case VECTOR3: {
- real_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
- real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
- real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+ int64_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
+ int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+ int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
r_iter = from;
if (from == to) {
return false;
} else if (from < to) {
- return step > 0.0;
+ return step > 0;
} else {
- return step < 0.0;
+ return step < 0;
}
//return true;
} break;
@@ -2387,7 +2387,6 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
valid = true;
switch (type) {
case INT: {
-
int64_t idx = r_iter;
idx++;
if (idx >= _data._int)
@@ -2396,33 +2395,36 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
case REAL: {
-
- double idx = r_iter;
- idx += 1.0;
+ int64_t idx = r_iter;
+ idx++;
if (idx >= _data._real)
return false;
r_iter = idx;
return true;
} break;
case VECTOR2: {
- real_t idx = r_iter;
- idx += 1.0;
- if (idx >= reinterpret_cast<const Vector2 *>(_data._mem)->y)
+ int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+
+ int64_t idx = r_iter;
+ idx++;
+
+ if (idx >= to)
return false;
+
r_iter = idx;
return true;
} break;
case VECTOR3: {
- real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
- real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+ int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+ int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
- real_t idx = r_iter;
+ int64_t idx = r_iter;
idx += step;
- if (step < 0.0 && idx <= to)
+ if (step < 0 && idx <= to)
return false;
- if (step > 0.0 && idx >= to)
+ if (step > 0 && idx >= to)
return false;
r_iter = idx;