Browse Source

Added two new methods 'blend_rect_mask' and 'fill'

d 8 years ago
parent
commit
48f8931d48
4 changed files with 104 additions and 1 deletions
  1. 75 0
      core/image.cpp
  2. 4 0
      core/image.h
  3. 4 0
      core/variant_call.cpp
  4. 21 1
      doc/base/classes.xml

+ 75 - 0
core/image.cpp

@@ -2263,6 +2263,81 @@ void Image::blend_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
 	}
 }
 
+void Image::blend_rect_mask(const Image &p_src, const Image &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
+
+	int dsize = data.size();
+	int srcdsize = p_src.data.size();
+	int maskdsize = p_mask.data.size();
+	int dst_data_size = data.size();
+	ERR_FAIL_COND(dsize == 0);
+	ERR_FAIL_COND(srcdsize == 0);
+	ERR_FAIL_COND(maskdsize == 0);
+	ERR_FAIL_COND(dst_data_size == 0);
+	ERR_FAIL_COND(p_src.width != p_mask.width);
+	ERR_FAIL_COND(p_src.height != p_mask.height);
+
+	Rect2 rrect = Rect2(0, 0, p_src.width, p_src.height).clip(p_src_rect);
+
+	DVector<uint8_t>::Write wp = data.write();
+	unsigned char *dst_data_ptr = wp.ptr();
+
+	DVector<uint8_t>::Read rp = p_src.data.read();
+	const unsigned char *src_data_ptr = rp.ptr();
+
+	DVector<uint8_t>::Read mrp = p_mask.data.read();
+	const unsigned char *mask_data_ptr = mrp.ptr();
+
+	if (format == FORMAT_INDEXED || format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED_ALPHA) {
+
+		return;
+
+	} else {
+
+		for (int i = 0; i < rrect.size.y; i++) {
+
+			if (i + p_dest.y < 0 || i + p_dest.y >= height)
+				continue;
+			for (int j = 0; j < rrect.size.x; j++) {
+
+				if (j + p_dest.x < 0 || j + p_dest.x >= width)
+					continue;
+
+				BColor msk = p_mask._get_pixel(rrect.pos.x + j, rrect.pos.y + i, mask_data_ptr, maskdsize);
+				if (msk.a != 0) {
+					BColor src = p_src._get_pixel(rrect.pos.x + j, rrect.pos.y + i, src_data_ptr, srcdsize);
+					BColor dst = _get_pixel(p_dest.x + j, p_dest.y + i, dst_data_ptr, dst_data_size);
+					float ba = (float) dst.a / 255.0;
+					float fa = (float) src.a / 255.0;
+					dst.r = (uint8_t) (fa*src.r + ba*(1.0 - fa) * dst.r);
+					dst.g = (uint8_t) (fa*src.g + ba*(1.0 - fa) * dst.g);
+					dst.b = (uint8_t) (fa*src.b + ba*(1.0 - fa) * dst.b);
+					dst.a = (uint8_t) (255.0 * (fa + ba * (1.0 - fa)));
+					_put_pixel(p_dest.x + j, p_dest.y + i, dst, dst_data_ptr);
+				}
+			}
+		}
+	}
+}
+
+void Image::fill(const Color &p_color) {
+	int dsize = data.size();
+	ERR_FAIL_COND(dsize == 0);
+
+	DVector<uint8_t>::Write wp = data.write();
+	unsigned char *dst_data_ptr = wp.ptr();
+	
+	BColor c = BColor(p_color.r*255, p_color.g*255, p_color.b*255, p_color.a*255);
+
+	for (int i = 0; i < height; i++) {
+
+		for (int j = 0; j < width; j++) {
+
+			_put_pixel(j, i, c, dst_data_ptr);
+		}
+	}
+	
+}
+
 Image (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL;
 Image (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL;
 

+ 4 - 0
core/image.h

@@ -352,6 +352,10 @@ public:
 
 	void blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
 	void blend_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+	void blend_rect_mask(const Image &p_src, const Image &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
+
+	void fill(const Color &p_color);
+	
 	void brush_transfer(const Image &p_src, const Image &p_brush, const Point2 &p_dest);
 	Image brushed(const Image &p_src, const Image &p_brush, const Point2 &p_dest) const;
 

+ 4 - 0
core/variant_call.cpp

@@ -622,6 +622,8 @@ struct _VariantCall {
 	VCALL_PTR0R(Image, get_data);
 	VCALL_PTR3(Image, blit_rect);
 	VCALL_PTR3(Image, blend_rect);
+	VCALL_PTR4(Image, blend_rect_mask);
+	VCALL_PTR1(Image, fill);
 	VCALL_PTR1R(Image, converted);
 	VCALL_PTR0(Image, fix_alpha_edges);
 
@@ -1473,6 +1475,8 @@ void register_variant_methods() {
 	ADDFUNC0(IMAGE, RAW_ARRAY, Image, get_data, varray());
 	ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0));
 	ADDFUNC3(IMAGE, NIL, Image, blend_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0));
+	ADDFUNC4(IMAGE, NIL, Image, blend_rect_mask, IMAGE, "src", IMAGE, "mask", RECT2, "src_rect", VECTOR2, "dest", varray(0));
+	ADDFUNC1(IMAGE, NIL, Image, fill, COLOR, "color", varray(0));
 	ADDFUNC1(IMAGE, IMAGE, Image, converted, INT, "format", varray(0));
 	ADDFUNC0(IMAGE, NIL, Image, fix_alpha_edges, varray());
 

+ 21 - 1
doc/base/classes.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<doc version="2.1.3.stable.custom_build" name="Engine Types">
+<doc version="2.1.4.beta.custom_build" name="Engine Types">
 <class name="@GDScript" category="Core">
 	<brief_description>
 		Built-in GDScript functions.
@@ -15866,6 +15866,19 @@
 				Alpha-blends a "src_rect" [Rect2] from "src" [Image] to this [Image] on coordinates "dest".
 			</description>
 		</method>
+		<method name="blend_rect_mask">
+			<argument index="0" name="src" type="Image">
+			</argument>
+			<argument index="1" name="mask" type="Image">
+			</argument>
+			<argument index="2" name="src_rect" type="Rect2">
+			</argument>
+			<argument index="3" name="dest" type="Vector2" default="0">
+			</argument>
+			<description>
+				Alpha-blends a "src_rect" [Rect2] from "src" [Image] to this [Image] using a "mask" [Image] on coordinates "dest". Alpha channels are required for both "src" and "mask", dest pixels and src pixels will blend if the corresponding mask pixel's alpha value is not 0. "src" [Image] and "mask" [Image] *must* have the same size (width and height) but they can have different formats
+			</description>
+		</method>
 		<method name="blit_rect">
 			<argument index="0" name="src" type="Image">
 			</argument>
@@ -15933,6 +15946,13 @@
 				Return whether this [Image] is empty(no data).
 			</description>
 		</method>
+		<method name="fill">
+			<argument index="0" name="color" type="Color" default="0">
+			</argument>
+			<description>
+				Fills an [Image] with a specified [Color]
+			</description>
+		</method>
 		<method name="fix_alpha_edges">
 			<description>
 			</description>