瀏覽代碼

Added 'blit_rect_mask' method

dumitru-stama 8 年之前
父節點
當前提交
e9e39dd6dc
共有 4 個文件被更改,包括 110 次插入5 次删除
  1. 65 2
      core/image.cpp
  2. 1 0
      core/image.h
  3. 2 0
      core/variant_call.cpp
  4. 42 3
      doc/base/classes.xml

+ 65 - 2
core/image.cpp

@@ -2217,6 +2217,69 @@ void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
 	}
 }
 
+void Image::blit_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();
+	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);
+
+	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 mp = p_mask.data.read();
+	const unsigned char *mask_data_ptr = mp.ptr();
+
+	if ((format == FORMAT_INDEXED || format == FORMAT_INDEXED_ALPHA) && (p_src.format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED_ALPHA)) {
+
+		Point2i desti(p_dest.x, p_dest.y);
+		Point2i srci(rrect.pos.x, rrect.pos.y);
+
+		for (int i = 0; i < rrect.size.y; i++) {
+
+			if (i + desti.y < 0 || i + desti.y >= height)
+				continue;
+			for (int j = 0; j < rrect.size.x; j++) {
+
+				if (j + desti.x < 0 || j + desti.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) {
+					dst_data_ptr[width * (desti.y + i) + desti.x + j] = src_data_ptr[p_src.width * (srci.y + i) + srci.x + j];
+				}
+			}
+		}
+
+	} 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) {
+					_put_pixel(p_dest.x + j, p_dest.y + i, p_src._get_pixel(rrect.pos.x + j, rrect.pos.y + i, src_data_ptr, srcdsize), dst_data_ptr);
+				}
+			}
+		}
+	}
+}
+
 void Image::blend_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
 
 	int dsize = data.size();
@@ -2234,7 +2297,7 @@ void Image::blend_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
 	DVector<uint8_t>::Read rp = p_src.data.read();
 	const unsigned char *src_data_ptr = rp.ptr();
 
-	if (format == FORMAT_INDEXED || format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED_ALPHA) {
+	if (format == FORMAT_INDEXED || format == FORMAT_INDEXED_ALPHA || p_src.format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED_ALPHA) {
 
 		return;
 
@@ -2287,7 +2350,7 @@ void Image::blend_rect_mask(const Image &p_src, const Image &p_mask, const Rect2
 	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) {
+	if (format == FORMAT_INDEXED || format == FORMAT_INDEXED_ALPHA || p_src.format == FORMAT_INDEXED || p_src.format == FORMAT_INDEXED_ALPHA) {
 
 		return;
 

+ 1 - 0
core/image.h

@@ -351,6 +351,7 @@ public:
 	void normalmap_to_xy();
 
 	void blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+	void blit_rect_mask(const Image &p_src, const Image &p_mask, 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);
 

+ 2 - 0
core/variant_call.cpp

@@ -621,6 +621,7 @@ struct _VariantCall {
 	VCALL_PTR3R(Image, resized);
 	VCALL_PTR0R(Image, get_data);
 	VCALL_PTR3(Image, blit_rect);
+	VCALL_PTR4(Image, blit_rect_mask);
 	VCALL_PTR3(Image, blend_rect);
 	VCALL_PTR4(Image, blend_rect_mask);
 	VCALL_PTR1(Image, fill);
@@ -1474,6 +1475,7 @@ void register_variant_methods() {
 	ADDFUNC3(IMAGE, IMAGE, Image, resized, INT, "x", INT, "y", INT, "interpolation", varray(((int)Image::INTERPOLATE_BILINEAR)));
 	ADDFUNC0(IMAGE, RAW_ARRAY, Image, get_data, varray());
 	ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0));
+	ADDFUNC4(IMAGE, NIL, Image, blit_rect_mask, IMAGE, "src", IMAGE, "mask", 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));

+ 42 - 3
doc/base/classes.xml

@@ -15890,6 +15890,19 @@
 				Copy a "src_rect" [Rect2] from "src" [Image] to this [Image] on coordinates "dest".
 			</description>
 		</method>
+		<method name="blit_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>
+				Blits a "src_rect" [Rect2] from "src" [Image] to this [Image] using a "mask" [Image] on coordinates "dest". Alpha channel is required for "mask", will copy src pixel onto dest 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="brush_transfer">
 			<argument index="0" name="src" type="Image">
 			</argument>
@@ -31944,6 +31957,30 @@
 				Return a copy of the [Rect2] grown a given amount of units towards all the sides.
 			</description>
 		</method>
+		<method name="grow_individual">
+			<return type="Rect2">
+			</return>
+			<argument index="0" name="left" type="float">
+			</argument>
+			<argument index="1" name="top" type="float">
+			</argument>
+			<argument index="2" name="right" type="float">
+			</argument>
+			<argument index="3" name=" bottom" type="float">
+			</argument>
+			<description>
+			</description>
+		</method>
+		<method name="grow_margin">
+			<return type="Rect2">
+			</return>
+			<argument index="0" name="margin" type="int">
+			</argument>
+			<argument index="1" name="by" type="float">
+			</argument>
+			<description>
+			</description>
+		</method>
 		<method name="has_no_area">
 			<return type="bool">
 			</return>
@@ -32651,7 +32688,7 @@
 			</description>
 		</method>
 		<method name="get_v_scroll">
-			<return type="Object">
+			<return type="VScrollBar">
 			</return>
 			<description>
 			</description>
@@ -32726,7 +32763,7 @@
 			</description>
 		</method>
 		<method name="push_font">
-			<argument index="0" name="font" type="Object">
+			<argument index="0" name="font" type="Font">
 			</argument>
 			<description>
 			</description>
@@ -37939,7 +37976,9 @@
 		</constant>
 		<constant name="FLAG_SHADED" value="1">
 		</constant>
-		<constant name="FLAG_MAX" value="2">
+		<constant name="FLAG_DOUBLE_SIDED" value="2">
+		</constant>
+		<constant name="FLAG_MAX" value="3">
 		</constant>
 		<constant name="ALPHA_CUT_DISABLED" value="0">
 		</constant>