Skip to content

Commit eca3239

Browse files
committed
[WIP] Presort text draw calls.
1 parent 53be3b7 commit eca3239

File tree

11 files changed

+359
-52
lines changed

11 files changed

+359
-52
lines changed

doc/classes/TextServer.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@
244244
- Each contour is closed. The last point of a contour uses the first point of a contour as its next point, and vice versa. The first point can be [constant CONTOUR_CURVE_TAG_OFF_CONIC] point.
245245
</description>
246246
</method>
247+
<method name="font_get_glyph_draw_info" qualifiers="const">
248+
<return type="void" />
249+
<param index="0" name="font_rid" type="RID" />
250+
<param index="1" name="priority" type="RID" />
251+
<param index="2" name="size" type="int" />
252+
<param index="3" name="pos" type="Vector2" />
253+
<param index="4" name="index" type="int" />
254+
<param index="5" name="color" type="Color" default="Color(1, 1, 1, 1)" />
255+
<param index="6" name="oversampling" type="float" default="0.0" />
256+
<description>
257+
</description>
258+
</method>
247259
<method name="font_get_glyph_index" qualifiers="const">
248260
<return type="int" />
249261
<param index="0" name="font_rid" type="RID" />
@@ -271,6 +283,19 @@
271283
Returns glyph offset from the baseline.
272284
</description>
273285
</method>
286+
<method name="font_get_glyph_outline_draw_info" qualifiers="const">
287+
<return type="void" />
288+
<param index="0" name="font_rid" type="RID" />
289+
<param index="1" name="priority" type="RID" />
290+
<param index="2" name="size" type="int" />
291+
<param index="3" name="outline_size" type="int" />
292+
<param index="4" name="pos" type="Vector2" />
293+
<param index="5" name="index" type="int" />
294+
<param index="6" name="color" type="Color" default="Color(1, 1, 1, 1)" />
295+
<param index="7" name="oversampling" type="float" default="0.0" />
296+
<description>
297+
</description>
298+
</method>
274299
<method name="font_get_glyph_size" qualifiers="const">
275300
<return type="Vector2" />
276301
<param index="0" name="font_rid" type="RID" />
@@ -2199,6 +2224,18 @@
21992224
<constant name="SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE" value="16" enum="SubpixelPositioning">
22002225
Maximum font size which will use "one quarter of the pixel" subpixel positioning in [constant SUBPIXEL_POSITIONING_AUTO] mode.
22012226
</constant>
2227+
<constant name="DRAW_CALL_NULL" value="0" enum="DrawCallType">
2228+
</constant>
2229+
<constant name="DRAW_CALL_NORMAL" value="1" enum="DrawCallType">
2230+
</constant>
2231+
<constant name="DRAW_CALL_MSDF" value="2" enum="DrawCallType">
2232+
</constant>
2233+
<constant name="DRAW_CALL_LCD" value="3" enum="DrawCallType">
2234+
</constant>
2235+
<constant name="DRAW_CALL_HEX" value="4" enum="DrawCallType">
2236+
</constant>
2237+
<constant name="DRAW_CALL_CUSTOM" value="5" enum="DrawCallType">
2238+
</constant>
22022239
<constant name="FEATURE_SIMPLE_LAYOUT" value="1" enum="Feature">
22032240
TextServer supports simple text layouts.
22042241
</constant>

doc/classes/TextServerExtension.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,19 @@
224224
Returns outline contours of the glyph.
225225
</description>
226226
</method>
227+
<method name="_font_get_glyph_draw_info" qualifiers="virtual const">
228+
<return type="void" />
229+
<param index="0" name="font_rid" type="RID" />
230+
<param index="1" name="priority" type="int" />
231+
<param index="2" name="size" type="int" />
232+
<param index="3" name="pos" type="Vector2" />
233+
<param index="4" name="index" type="int" />
234+
<param index="5" name="color" type="Color" />
235+
<param index="6" name="oversampling" type="float" />
236+
<param index="7" name="info" type="GlyphDrawCall*" />
237+
<description>
238+
</description>
239+
</method>
227240
<method name="_font_get_glyph_index" qualifiers="virtual required const">
228241
<return type="int" />
229242
<param index="0" name="font_rid" type="RID" />
@@ -251,6 +264,20 @@
251264
Returns glyph offset from the baseline.
252265
</description>
253266
</method>
267+
<method name="_font_get_glyph_outline_draw_info" qualifiers="virtual const">
268+
<return type="void" />
269+
<param index="0" name="font_rid" type="RID" />
270+
<param index="1" name="priority" type="int" />
271+
<param index="2" name="size" type="int" />
272+
<param index="3" name="outline_size" type="int" />
273+
<param index="4" name="pos" type="Vector2" />
274+
<param index="5" name="index" type="int" />
275+
<param index="6" name="color" type="Color" />
276+
<param index="7" name="oversampling" type="float" />
277+
<param index="8" name="info" type="GlyphDrawCall*" />
278+
<description>
279+
</description>
280+
</method>
254281
<method name="_font_get_glyph_size" qualifiers="virtual required const">
255282
<return type="Vector2" />
256283
<param index="0" name="font_rid" type="RID" />

modules/text_server_adv/text_server_adv.cpp

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,12 +3908,24 @@ void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2
39083908
#endif
39093909
}
39103910

3911-
void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
3911+
#ifdef GDEXTENSION
3912+
void TextServerAdvanced::_font_get_glyph_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling, GDExtensionPtr<GlyphDrawCall> p_ret) const {
3913+
*p_ret = font_get_glyph_draw_info(p_font, p_priority, p_size, p_pos, p_index, p_color, p_oversampling);
3914+
}
3915+
3916+
void TextServerAdvanced::_font_get_glyph_outline_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling, GDExtensionPtr<GlyphDrawCall> p_ret) const {
3917+
*p_ret = font_get_glyph_outline_draw_info(p_font, p_priority, p_size, p_outline_size, p_pos, p_index, p_color, p_oversampling);
3918+
}
3919+
#endif
3920+
3921+
GlyphDrawCall TextServerAdvanced::font_get_glyph_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
3922+
GlyphDrawCall ret;
3923+
39123924
if (p_index == 0) {
3913-
return; // Non visual character, skip.
3925+
return ret; // Non visual character, skip.
39143926
}
3915-
FontAdvanced *fd = _get_font_data(p_font_rid);
3916-
ERR_FAIL_NULL(fd);
3927+
FontAdvanced *fd = _get_font_data(p_font);
3928+
ERR_FAIL_NULL_V(fd, ret);
39173929

39183930
MutexLock lock(fd->mutex);
39193931

@@ -3946,7 +3958,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
39463958
}
39473959

39483960
FontForSizeAdvanced *ffsd = nullptr;
3949-
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
3961+
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0), ret);
39503962

39513963
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
39523964
bool lcd_aa = false;
@@ -3974,11 +3986,11 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
39743986

39753987
FontGlyph fgl;
39763988
if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
3977-
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
3989+
return ret; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
39783990
}
39793991

39803992
if (fgl.found) {
3981-
ERR_FAIL_COND(fgl.texture_idx < -1 || fgl.texture_idx >= ffsd->textures.size());
3993+
ERR_FAIL_COND_V(fgl.texture_idx < -1 || fgl.texture_idx >= ffsd->textures.size(), ret);
39823994

39833995
if (fgl.texture_idx != -1) {
39843996
Color modulate = p_color;
@@ -4011,10 +4023,18 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
40114023
Point2 cpos = p_pos;
40124024
cpos += fgl.rect.position * (double)p_size / (double)fd->msdf_source_size;
40134025
Size2 csize = fgl.rect.size * (double)p_size / (double)fd->msdf_source_size;
4014-
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, 0, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
4026+
ret.priority = p_priority;
4027+
ret.texture = texture;
4028+
ret.dst_rect = Rect2(cpos, csize);
4029+
ret.src_rect = fgl.uv_rect;
4030+
ret.modulate = modulate;
4031+
ret.outline_size = 0;
4032+
ret.px_range = fd->msdf_range;
4033+
ret.scale = (double)p_size / (double)fd->msdf_source_size;
4034+
ret.draw_type = DRAW_CALL_MSDF;
40154035
} else {
40164036
Point2 cpos = p_pos;
4017-
double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
4037+
double scale = _font_get_scale(p_font, p_size) / oversampling_factor;
40184038
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
40194039
cpos.x = cpos.x + 0.125;
40204040
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
@@ -4043,23 +4063,30 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
40434063
csize /= oversampling_factor;
40444064
}
40454065
cpos += gpos;
4046-
if (lcd_aa) {
4047-
RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate);
4048-
} else {
4049-
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, false, false);
4050-
}
4066+
ret.priority = p_priority;
4067+
ret.texture = texture;
4068+
ret.dst_rect = Rect2(cpos, csize);
4069+
ret.src_rect = fgl.uv_rect;
4070+
ret.modulate = modulate;
4071+
ret.outline_size = 0;
4072+
ret.px_range = 0.0;
4073+
ret.scale = 0.0;
4074+
ret.draw_type = lcd_aa ? DRAW_CALL_LCD : DRAW_CALL_NORMAL;
40514075
}
40524076
}
40534077
}
40544078
}
4079+
4080+
return ret;
40554081
}
40564082

4057-
void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
4083+
GlyphDrawCall TextServerAdvanced::font_get_glyph_outline_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
4084+
GlyphDrawCall ret;
40584085
if (p_index == 0) {
4059-
return; // Non visual character, skip.
4086+
return ret; // Non visual character, skip.
40604087
}
4061-
FontAdvanced *fd = _get_font_data(p_font_rid);
4062-
ERR_FAIL_NULL(fd);
4088+
FontAdvanced *fd = _get_font_data(p_font);
4089+
ERR_FAIL_NULL_V(fd, ret);
40634090

40644091
MutexLock lock(fd->mutex);
40654092

@@ -4092,7 +4119,7 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
40924119
}
40934120

40944121
FontForSizeAdvanced *ffsd = nullptr;
4095-
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
4122+
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0), ret);
40964123

40974124
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
40984125
bool lcd_aa = false;
@@ -4120,11 +4147,11 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
41204147

41214148
FontGlyph fgl;
41224149
if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
4123-
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
4150+
return ret; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
41244151
}
41254152

41264153
if (fgl.found) {
4127-
ERR_FAIL_COND(fgl.texture_idx < -1 || fgl.texture_idx >= ffsd->textures.size());
4154+
ERR_FAIL_COND_V(fgl.texture_idx < -1 || fgl.texture_idx >= ffsd->textures.size(), ret);
41284155

41294156
if (fgl.texture_idx != -1) {
41304157
Color modulate = p_color;
@@ -4153,10 +4180,18 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
41534180
Point2 cpos = p_pos;
41544181
cpos += fgl.rect.position * (double)p_size / (double)fd->msdf_source_size;
41554182
Size2 csize = fgl.rect.size * (double)p_size / (double)fd->msdf_source_size;
4156-
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, p_outline_size, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
4183+
ret.priority = p_priority;
4184+
ret.texture = texture;
4185+
ret.dst_rect = Rect2(cpos, csize);
4186+
ret.src_rect = fgl.uv_rect;
4187+
ret.modulate = modulate;
4188+
ret.outline_size = p_outline_size;
4189+
ret.px_range = fd->msdf_range;
4190+
ret.scale = (double)p_size / (double)fd->msdf_source_size;
4191+
ret.draw_type = DRAW_CALL_MSDF;
41574192
} else {
41584193
Point2 cpos = p_pos;
4159-
double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
4194+
double scale = _font_get_scale(p_font, p_size) / oversampling_factor;
41604195
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
41614196
cpos.x = cpos.x + 0.125;
41624197
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
@@ -4185,15 +4220,46 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
41854220
csize /= oversampling_factor;
41864221
}
41874222
cpos += gpos;
4188-
if (lcd_aa) {
4189-
RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate);
4190-
} else {
4191-
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, false, false);
4192-
}
4223+
ret.priority = p_priority;
4224+
ret.texture = texture;
4225+
ret.dst_rect = Rect2(cpos, csize);
4226+
ret.src_rect = fgl.uv_rect;
4227+
ret.modulate = modulate;
4228+
ret.outline_size = p_outline_size;
4229+
ret.px_range = 0.0;
4230+
ret.scale = 0.0;
4231+
ret.draw_type = lcd_aa ? DRAW_CALL_LCD : DRAW_CALL_NORMAL;
41934232
}
41944233
}
41954234
}
41964235
}
4236+
return ret;
4237+
}
4238+
4239+
void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
4240+
if (RenderingServer::get_singleton() != nullptr) {
4241+
const GlyphDrawCall &ret = font_get_glyph_draw_info(p_font_rid, 0, p_size, p_pos, p_index, p_color, p_oversampling);
4242+
if (ret.draw_type == DRAW_CALL_MSDF) {
4243+
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, ret.dst_rect, ret.texture, ret.src_rect, ret.modulate, 0, ret.px_range, ret.scale);
4244+
} else if (ret.draw_type == DRAW_CALL_LCD) {
4245+
RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, ret.dst_rect, ret.texture, ret.src_rect, ret.modulate);
4246+
} else if (ret.draw_type == DRAW_CALL_NORMAL) {
4247+
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, ret.dst_rect, ret.texture, ret.src_rect, ret.modulate, false, false);
4248+
}
4249+
}
4250+
}
4251+
4252+
void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
4253+
if (RenderingServer::get_singleton() != nullptr) {
4254+
const GlyphDrawCall &ret = font_get_glyph_outline_draw_info(p_font_rid, 0, p_size, p_outline_size, p_pos, p_index, p_color, p_oversampling);
4255+
if (ret.draw_type == DRAW_CALL_MSDF) {
4256+
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, ret.dst_rect, ret.texture, ret.src_rect, ret.modulate, ret.outline_size, ret.px_range, ret.scale);
4257+
} else if (ret.draw_type == DRAW_CALL_LCD) {
4258+
RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, ret.dst_rect, ret.texture, ret.src_rect, ret.modulate);
4259+
} else if (ret.draw_type == DRAW_CALL_NORMAL) {
4260+
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, ret.dst_rect, ret.texture, ret.src_rect, ret.modulate, false, false);
4261+
}
4262+
}
41974263
}
41984264

41994265
bool TextServerAdvanced::_font_is_language_supported(const RID &p_font_rid, const String &p_language) const {

modules/text_server_adv/text_server_adv.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,17 @@ class TextServerAdvanced : public TextServerExtension {
930930
MODBIND7C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &, float);
931931
MODBIND8C(font_draw_glyph_outline, const RID &, const RID &, int64_t, int64_t, const Vector2 &, int64_t, const Color &, float);
932932

933+
#ifdef GDEXTENSION
934+
MODBIND8C(font_get_glyph_draw_info, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &, float, GDExtensionPtr<GlyphDrawCall>);
935+
MODBIND9C(font_get_glyph_outline_draw_info, RID, int64_t, int64_t, int64_t, const Vector2 &, int64_t, const Color &, float, GDExtensionPtr<GlyphDrawCall>);
936+
937+
GlyphDrawCall font_get_glyph_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
938+
GlyphDrawCall font_get_glyph_outline_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const;
939+
#else
940+
virtual GlyphDrawCall font_get_glyph_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const override;
941+
virtual GlyphDrawCall font_get_glyph_outline_draw_info(const RID &p_font, int64_t p_priority, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1), float p_oversampling = 0.0) const override;
942+
#endif
943+
933944
MODBIND2RC(bool, font_is_language_supported, const RID &, const String &);
934945
MODBIND3(font_set_language_support_override, const RID &, const String &, bool);
935946
MODBIND2R(bool, font_get_language_support_override, const RID &, const String &);

0 commit comments

Comments
 (0)