Skip to content

Commit bbb8667

Browse files
committed
Merge pull request #84472 from xiongyaohua/canvas_item_draw_circle_non_filled
Extend `CanvasItem::draw_circle()`, making it also draw unfilled circle.
2 parents 3dca334 + 1f2aa17 commit bbb8667

File tree

5 files changed

+95
-5
lines changed

5 files changed

+95
-5
lines changed

doc/classes/CanvasItem.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,14 @@
7777
<param index="0" name="position" type="Vector2" />
7878
<param index="1" name="radius" type="float" />
7979
<param index="2" name="color" type="Color" />
80+
<param index="3" name="filled" type="bool" default="true" />
81+
<param index="4" name="width" type="float" default="-1.0" />
82+
<param index="5" name="antialiased" type="bool" default="false" />
8083
<description>
81-
Draws a colored, filled circle. See also [method draw_arc], [method draw_polyline] and [method draw_polygon].
84+
Draws a circle. See also [method draw_arc], [method draw_polyline], and [method draw_polygon].
85+
If [param filled] is [code]true[/code], the circle will be filled with the [param color] specified. If [param filled] is [code]false[/code], the circle will be drawn as a stroke with the [param color] and [param width] specified.
86+
If [param width] is negative, then two-point primitives will be drawn instead of a four-point ones. This means that when the CanvasItem is scaled, the lines will remain thin. If this behavior is not desired, then pass a positive [param width] like [code]1.0[/code].
87+
[b]Note:[/b] [param width] is only effective if [param filled] is [code]false[/code].
8288
</description>
8389
</method>
8490
<method name="draw_colored_polygon">

misc/extension_api_validation/4.2-stable.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,10 @@ Validate extension JSON: Error: Field 'classes/TextEdit/methods/set_selection_mo
323323

324324
Removed optional arguments set_selection_mode, use set_selection_origin_line/column instead.
325325
Compatibility methods registered.
326+
327+
328+
GH-84472
329+
--------
330+
Validate extension JSON: Error: Field 'classes/CanvasItem/methods/draw_circle/arguments': size changed value in new API, from 3 to 6.
331+
332+
Optional arguments added. Compatibility methods registered.

scene/main/canvas_item.compat.inc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**************************************************************************/
2+
/* canvas_item.compat.inc */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#ifndef DISABLE_DEPRECATED
32+
33+
void CanvasItem::_draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) {
34+
draw_circle(p_pos, p_radius, p_color, true, -1.0, false);
35+
}
36+
37+
void CanvasItem::_bind_compatibility_methods() {
38+
ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_compat_84472);
39+
}
40+
41+
#endif

scene/main/canvas_item.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
/**************************************************************************/
3030

3131
#include "canvas_item.h"
32+
#include "canvas_item.compat.inc"
3233

3334
#include "scene/2d/canvas_group.h"
3435
#include "scene/main/canvas_layer.h"
@@ -726,11 +727,40 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
726727
}
727728
}
728729

729-
void CanvasItem::draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color) {
730+
void CanvasItem::draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color, bool p_filled, real_t p_width, bool p_antialiased) {
730731
ERR_THREAD_GUARD;
731732
ERR_DRAW_GUARD;
732733

733-
RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
734+
if (p_filled) {
735+
if (p_width != -1.0) {
736+
WARN_PRINT("The draw_circle() \"width\" argument has no effect when \"filled\" is \"true\".");
737+
}
738+
739+
RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
740+
} else if (p_width >= 2.0 * p_radius) {
741+
RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color);
742+
} else {
743+
// Tessellation count is hardcoded. Keep in sync with the same variable in `RendererCanvasCull::canvas_item_add_circle()`.
744+
const int circle_segments = 64;
745+
746+
Vector<Vector2> points;
747+
points.resize(circle_segments + 1);
748+
749+
Vector2 *points_ptr = points.ptrw();
750+
const real_t circle_point_step = Math_TAU / circle_segments;
751+
752+
for (int i = 0; i < circle_segments; i++) {
753+
float angle = i * circle_point_step;
754+
points_ptr[i].x = Math::cos(angle) * p_radius;
755+
points_ptr[i].y = Math::sin(angle) * p_radius;
756+
points_ptr[i] += p_pos;
757+
}
758+
points_ptr[circle_segments] = points_ptr[0];
759+
760+
Vector<Color> colors = { p_color };
761+
762+
RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width, p_antialiased);
763+
}
734764
}
735765

736766
void CanvasItem::draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate) {
@@ -1163,7 +1193,7 @@ void CanvasItem::_bind_methods() {
11631193
ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::draw_multiline, DEFVAL(-1.0));
11641194
ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0));
11651195
ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0));
1166-
ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle);
1196+
ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color", "filled", "width", "antialiased"), &CanvasItem::draw_circle, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false));
11671197
ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)));
11681198
ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false));
11691199
ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false), DEFVAL(true));

scene/main/canvas_item.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ class CanvasItem : public Node {
166166

167167
void _notification(int p_what);
168168
static void _bind_methods();
169+
170+
#ifndef DISABLE_DEPRECATED
171+
void _draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color);
172+
static void _bind_compatibility_methods();
173+
#endif
174+
169175
void _validate_property(PropertyInfo &p_property) const;
170176

171177
_FORCE_INLINE_ void set_hide_clip_children(bool p_value) { hide_clip_children = p_value; }
@@ -273,7 +279,7 @@ class CanvasItem : public Node {
273279
void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0);
274280
void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0);
275281
void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0);
276-
void draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color);
282+
void draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false);
277283
void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1));
278284
void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
279285
void draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false);

0 commit comments

Comments
 (0)