[Complex Text Layouts] Provide access to glyph contour points.
This commit is contained in:
parent
2a66714bfb
commit
0d3fa2a125
16 changed files with 141 additions and 2 deletions
|
@ -258,6 +258,22 @@
|
|||
Returns advance of the glyph.
|
||||
</description>
|
||||
</method>
|
||||
<method name="font_get_glyph_contours" qualifiers="const">
|
||||
<return type="Dictionary">
|
||||
</return>
|
||||
<argument index="0" name="font" type="RID">
|
||||
</argument>
|
||||
<argument index="1" name="size" type="int">
|
||||
</argument>
|
||||
<argument index="2" name="index" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Returns outline contours of the glyph in a Dictionary.
|
||||
[code]points[/code] - [PackedVector3Array], containing outline points. [code]x[/code] and [code]y[/code] are point coordinates. [code]z[/code] is the type of the point, using the [enum ContourPointTag] values.
|
||||
[code]contours[/code] - [PackedInt32Array], containing indices the end points of each contour.
|
||||
[code]orientation[/code] - [bool], contour orientation. If [code]true[/code], clockwise contours must be filled.
|
||||
</description>
|
||||
</method>
|
||||
<method name="font_get_glyph_index" qualifiers="const">
|
||||
<return type="int">
|
||||
</return>
|
||||
|
@ -1301,5 +1317,14 @@
|
|||
<constant name="FEATURE_USE_SUPPORT_DATA" value="128" enum="Feature">
|
||||
TextServer require external data file for some features.
|
||||
</constant>
|
||||
<constant name="CONTOUR_CURVE_TAG_ON" value="1" enum="ContourPointTag">
|
||||
Contour point is on the curve.
|
||||
</constant>
|
||||
<constant name="CONTOUR_CURVE_TAG_OFF_CONIC" value="0" enum="ContourPointTag">
|
||||
Contour point isn't on the curve, but serves as a control point for a conic (quadratic) Bézier arc.
|
||||
</constant>
|
||||
<constant name="CONTOUR_CURVE_TAG_OFF_CUBIC" value="2" enum="ContourPointTag">
|
||||
Contour point isn't on the curve, but serves as a control point for a cubic Bézier arc.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
||||
|
|
|
@ -118,6 +118,7 @@ typedef struct {
|
|||
godot_vector2 (*font_get_glyph_kerning)(void *, godot_rid *, uint32_t, uint32_t, int);
|
||||
godot_vector2 (*font_draw_glyph)(void *, godot_rid *, godot_rid *, int, const godot_vector2 *, uint32_t, const godot_color *);
|
||||
godot_vector2 (*font_draw_glyph_outline)(void *, godot_rid *, godot_rid *, int, int, const godot_vector2 *, uint32_t, const godot_color *);
|
||||
bool (*font_get_glyph_contours)(void *, godot_rid *, int, uint32_t, godot_packed_vector3_array *, godot_packed_int32_array *, bool *);
|
||||
float (*font_get_oversampling)(void *);
|
||||
void (*font_set_oversampling)(void *, float);
|
||||
godot_packed_string_array (*get_system_fonts)(void *);
|
||||
|
|
|
@ -359,6 +359,12 @@ Vector2 TextServerGDNative::font_draw_glyph_outline(RID p_font, RID p_canvas, in
|
|||
return advance;
|
||||
}
|
||||
|
||||
bool TextServerGDNative::font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
|
||||
ERR_FAIL_COND_V(interface == nullptr, false);
|
||||
ERR_FAIL_COND_V(interface->font_get_glyph_contours == nullptr, false);
|
||||
return interface->font_get_glyph_contours(data, (godot_rid *)&p_font, p_size, p_index, (godot_packed_vector3_array *)&r_points, (godot_packed_int32_array *)&r_contours, (bool *)&r_orientation);
|
||||
}
|
||||
|
||||
float TextServerGDNative::font_get_oversampling() const {
|
||||
ERR_FAIL_COND_V(interface == nullptr, 1.f);
|
||||
return interface->font_get_oversampling(data);
|
||||
|
|
|
@ -126,6 +126,8 @@ public:
|
|||
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
|
||||
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
|
||||
|
||||
virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
|
||||
|
||||
virtual float font_get_oversampling() const override;
|
||||
virtual void font_set_oversampling(float p_oversampling) override;
|
||||
|
||||
|
|
|
@ -997,6 +997,29 @@ Vector2 DynamicFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, in
|
|||
return advance;
|
||||
}
|
||||
|
||||
bool DynamicFontDataAdvanced::get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
DataAtSize *fds = const_cast<DynamicFontDataAdvanced *>(this)->get_data_for_size(p_size);
|
||||
ERR_FAIL_COND_V(fds == nullptr, false);
|
||||
|
||||
int error = FT_Load_Glyph(fds->face, p_index, FT_LOAD_NO_BITMAP | (force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
|
||||
ERR_FAIL_COND_V(error, false);
|
||||
|
||||
r_points.clear();
|
||||
r_contours.clear();
|
||||
|
||||
float h = fds->ascent;
|
||||
float scale = (1.0 / 64.0) / oversampling * fds->scale_color_font;
|
||||
for (short i = 0; i < fds->face->glyph->outline.n_points; i++) {
|
||||
r_points.push_back(Vector3(fds->face->glyph->outline.points[i].x * scale, h - fds->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fds->face->glyph->outline.tags[i])));
|
||||
}
|
||||
for (short i = 0; i < fds->face->glyph->outline.n_contours; i++) {
|
||||
r_contours.push_back(fds->face->glyph->outline.contours[i]);
|
||||
}
|
||||
r_orientation = (FT_Outline_Get_Orientation(&fds->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
DynamicFontDataAdvanced::~DynamicFontDataAdvanced() {
|
||||
clear_cache();
|
||||
if (library != nullptr) {
|
||||
|
|
|
@ -186,6 +186,8 @@ public:
|
|||
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
|
||||
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
|
||||
|
||||
virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
|
||||
|
||||
virtual ~DynamicFontDataAdvanced() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ struct FontDataAdvanced {
|
|||
virtual bool has_outline() const = 0;
|
||||
virtual float get_base_size() const = 0;
|
||||
|
||||
virtual bool is_lang_supported(const String &p_lang) const { return false; };
|
||||
virtual bool is_script_supported(uint32_t p_script) const { return false; };
|
||||
virtual bool is_lang_supported(const String &p_lang) const { return true; };
|
||||
virtual bool is_script_supported(uint32_t p_script) const { return true; };
|
||||
|
||||
virtual bool has_char(char32_t p_char) const = 0;
|
||||
virtual String get_supported_chars() const = 0;
|
||||
|
@ -107,6 +107,8 @@ struct FontDataAdvanced {
|
|||
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
|
||||
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
|
||||
|
||||
virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { return false; };
|
||||
|
||||
virtual ~FontDataAdvanced(){};
|
||||
};
|
||||
|
||||
|
|
|
@ -906,6 +906,13 @@ Vector2 TextServerAdvanced::font_draw_glyph_outline(RID p_font, RID p_canvas, in
|
|||
return fd->draw_glyph_outline(p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
|
||||
}
|
||||
|
||||
bool TextServerAdvanced::font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
const FontDataAdvanced *fd = font_owner.getornull(p_font);
|
||||
ERR_FAIL_COND_V(!fd, false);
|
||||
return fd->get_glyph_contours(p_size, p_index, r_points, r_contours, r_orientation);
|
||||
}
|
||||
|
||||
float TextServerAdvanced::font_get_oversampling() const {
|
||||
return oversampling;
|
||||
}
|
||||
|
|
|
@ -188,6 +188,8 @@ public:
|
|||
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
|
||||
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
|
||||
|
||||
virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
|
||||
|
||||
virtual float font_get_oversampling() const override;
|
||||
virtual void font_set_oversampling(float p_oversampling) override;
|
||||
|
||||
|
|
|
@ -680,6 +680,29 @@ Vector2 DynamicFontDataFallback::draw_glyph_outline(RID p_canvas, int p_size, in
|
|||
return advance;
|
||||
}
|
||||
|
||||
bool DynamicFontDataFallback::get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
DataAtSize *fds = const_cast<DynamicFontDataFallback *>(this)->get_data_for_size(p_size);
|
||||
ERR_FAIL_COND_V(fds == nullptr, false);
|
||||
|
||||
int error = FT_Load_Glyph(fds->face, p_index, FT_LOAD_NO_BITMAP | (force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
|
||||
ERR_FAIL_COND_V(error, false);
|
||||
|
||||
r_points.clear();
|
||||
r_contours.clear();
|
||||
|
||||
float h = fds->ascent;
|
||||
float scale = (1.0 / 64.0) / oversampling * fds->scale_color_font;
|
||||
for (short i = 0; i < fds->face->glyph->outline.n_points; i++) {
|
||||
r_points.push_back(Vector3(fds->face->glyph->outline.points[i].x * scale, h - fds->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fds->face->glyph->outline.tags[i])));
|
||||
}
|
||||
for (short i = 0; i < fds->face->glyph->outline.n_contours; i++) {
|
||||
r_contours.push_back(fds->face->glyph->outline.contours[i]);
|
||||
}
|
||||
r_orientation = (FT_Outline_Get_Orientation(&fds->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
DynamicFontDataFallback::~DynamicFontDataFallback() {
|
||||
clear_cache();
|
||||
if (library != nullptr) {
|
||||
|
|
|
@ -164,6 +164,8 @@ public:
|
|||
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
|
||||
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
|
||||
|
||||
virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
|
||||
|
||||
virtual ~DynamicFontDataFallback() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ struct FontDataFallback {
|
|||
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
|
||||
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
|
||||
|
||||
virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { return false; };
|
||||
|
||||
virtual ~FontDataFallback(){};
|
||||
};
|
||||
|
||||
|
|
|
@ -452,6 +452,13 @@ Vector2 TextServerFallback::font_draw_glyph_outline(RID p_font, RID p_canvas, in
|
|||
return fd->draw_glyph_outline(p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
|
||||
}
|
||||
|
||||
bool TextServerFallback::font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
const FontDataFallback *fd = font_owner.getornull(p_font);
|
||||
ERR_FAIL_COND_V(!fd, false);
|
||||
return fd->get_glyph_contours(p_size, p_index, r_points, r_contours, r_orientation);
|
||||
}
|
||||
|
||||
float TextServerFallback::font_get_oversampling() const {
|
||||
return oversampling;
|
||||
}
|
||||
|
|
|
@ -137,6 +137,8 @@ public:
|
|||
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
|
||||
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
|
||||
|
||||
virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
|
||||
|
||||
virtual float font_get_oversampling() const override;
|
||||
virtual void font_set_oversampling(float p_oversampling) override;
|
||||
|
||||
|
|
|
@ -291,6 +291,8 @@ void TextServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_hex_code_box_size", "size", "index"), &TextServer::get_hex_code_box_size);
|
||||
ClassDB::bind_method(D_METHOD("draw_hex_code_box", "canvas", "size", "pos", "index", "color"), &TextServer::draw_hex_code_box);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("font_get_glyph_contours", "font", "size", "index"), &TextServer::_font_get_glyph_contours);
|
||||
|
||||
/* Shaped text buffer interface */
|
||||
|
||||
ClassDB::bind_method(D_METHOD("create_shaped_text", "direction", "orientation"), &TextServer::create_shaped_text, DEFVAL(DIRECTION_AUTO), DEFVAL(ORIENTATION_HORIZONTAL));
|
||||
|
@ -403,6 +405,11 @@ void TextServer::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(FEATURE_FONT_SYSTEM);
|
||||
BIND_ENUM_CONSTANT(FEATURE_FONT_VARIABLE);
|
||||
BIND_ENUM_CONSTANT(FEATURE_USE_SUPPORT_DATA);
|
||||
|
||||
/* FT Contour Point Types */
|
||||
BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_ON);
|
||||
BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_OFF_CONIC);
|
||||
BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_OFF_CUBIC);
|
||||
}
|
||||
|
||||
Vector3 TextServer::hex_code_box_font_size[2] = { Vector3(5, 5, 1), Vector3(10, 10, 2) };
|
||||
|
@ -1212,6 +1219,21 @@ RID TextServer::_create_font_memory(const PackedByteArray &p_data, const String
|
|||
return create_font_memory(p_data.ptr(), p_data.size(), p_type, p_base_size);
|
||||
}
|
||||
|
||||
Dictionary TextServer::_font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index) const {
|
||||
Vector<Vector3> points;
|
||||
Vector<int32_t> contours;
|
||||
bool orientation;
|
||||
bool ok = font_get_glyph_contours(p_font, p_size, p_index, points, contours, orientation);
|
||||
Dictionary out;
|
||||
|
||||
if (ok) {
|
||||
out["points"] = points;
|
||||
out["contours"] = contours;
|
||||
out["orientation"] = orientation;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void TextServer::_shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) {
|
||||
Vector<Vector2i> overrides;
|
||||
for (int i = 0; i < p_override.size(); i++) {
|
||||
|
|
|
@ -99,6 +99,12 @@ public:
|
|||
FEATURE_USE_SUPPORT_DATA = 1 << 7
|
||||
};
|
||||
|
||||
enum ContourPointTag {
|
||||
CONTOUR_CURVE_TAG_ON = 0x01,
|
||||
CONTOUR_CURVE_TAG_OFF_CONIC = 0x00,
|
||||
CONTOUR_CURVE_TAG_OFF_CUBIC = 0x02
|
||||
};
|
||||
|
||||
struct Glyph {
|
||||
int start = -1; // Start offset in the source string.
|
||||
int end = -1; // End offset in the source string.
|
||||
|
@ -286,6 +292,8 @@ public:
|
|||
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
|
||||
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
|
||||
|
||||
virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const = 0;
|
||||
|
||||
virtual float font_get_oversampling() const = 0;
|
||||
virtual void font_set_oversampling(float p_oversampling) = 0;
|
||||
|
||||
|
@ -372,6 +380,8 @@ public:
|
|||
/* GDScript wrappers */
|
||||
RID _create_font_memory(const PackedByteArray &p_data, const String &p_type, int p_base_size = 16);
|
||||
|
||||
Dictionary _font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index) const;
|
||||
|
||||
Array _shaped_text_get_glyphs(RID p_shaped) const;
|
||||
Dictionary _shaped_text_get_carets(RID p_shaped, int p_position) const;
|
||||
|
||||
|
@ -454,5 +464,6 @@ VARIANT_ENUM_CAST(TextServer::LineBreakFlag);
|
|||
VARIANT_ENUM_CAST(TextServer::GraphemeFlag);
|
||||
VARIANT_ENUM_CAST(TextServer::Hinting);
|
||||
VARIANT_ENUM_CAST(TextServer::Feature);
|
||||
VARIANT_ENUM_CAST(TextServer::ContourPointTag);
|
||||
|
||||
#endif // TEXT_SERVER_H
|
||||
|
|
Loading…
Reference in a new issue