33 b.add_input<
decl::Float>(
"Character Spacing").default_value(1.0f).min(0.0f);
34 b.add_input<
decl::Float>(
"Word Spacing").default_value(1.0f).min(0.0f);
35 b.add_input<
decl::Float>(
"Line Spacing").default_value(1.0f).min(0.0f);
37 auto &height =
b.add_input<
decl::Float>(
"Text Box Height")
41 .make_available([](
bNode &node) {
45 auto &remainder =
b.add_output<
decl::String>(
"Remainder").make_available([](
bNode &node) {
48 b.add_output<
decl::Int>(
"Line").field_on_all();
51 const bNode *node =
b.node_or_null();
52 if (node !=
nullptr) {
66 uiTemplateID(layout, C,
ptr,
"font",
nullptr,
"FONT_OT_open",
"FONT_OT_unlink");
91 const std::optional<Bounds<float3>> bounds =
bounds::min_max(curves.positions());
94 if (!bounds.has_value()) {
95 return {0.0f, 0.0f, 0.0f};
98 const float3 max = bounds->max;
100 switch (pivot_mode) {
102 return (
min + max) / 2;
112 return float3((
min.x + max.x) / 2, max.y, 0.0f);
114 return float3(max.x, max.y, 0.0f);
116 return {0.0f, 0.0f, 0.0f};
146 params.error_message_add(NodeWarningType::Error,
TIP_(
"Font not specified"));
151 layout.
text =
params.extract_input<std::string>(
"String");
152 if (layout.
text.empty()) {
164 const float font_size = std::max(
params.extract_input<
float>(
"Size"), 0.0f);
165 const float char_spacing =
params.extract_input<
float>(
"Character Spacing");
166 const float word_spacing =
params.extract_input<
float>(
"Word Spacing");
167 const float line_spacing =
params.extract_input<
float>(
"Line Spacing");
168 const float textbox_w =
params.extract_input<
float>(
"Text Box Width");
171 params.extract_input<
float>(
"Text Box Height");
173 Curve cu = dna::shallow_zero_initialize();
177 cu.smallcaps_scale = 0.75f;
180 cu.spacemode = align_x;
181 cu.align_y = align_y;
182 cu.fsize = font_size;
183 cu.spacing = char_spacing;
184 cu.wordspace = word_spacing;
185 cu.linedist = line_spacing;
187 cu.overflow = overflow;
189 cu.tb->
w = textbox_w;
190 cu.tb->h = textbox_h;
194 cu.len_char32 = len_chars;
198 cu.str =
static_cast<char *
>(
MEM_mallocN(len_bytes +
sizeof(
char32_t), __func__));
199 memcpy(cu.str, layout.
text.c_str(), len_bytes + 1);
205 const char32_t *r_text =
nullptr;
208 nullptr, &cu,
FO_DUPLI,
nullptr, &r_text, &text_len, &
text_free, &chartransdata);
211 MEM_freeN(
const_cast<char32_t *
>(r_text));
224 layout.
text.c_str(), layout.
text.size(), i + 1);
226 layout.
text = layout.
text.substr(0, offset);
231 if (
params.anonymous_attribute_output_is_required(
"Line")) {
233 for (
const int i : layout.
positions.index_range()) {
260 bool pivot_required =
params.anonymous_attribute_output_is_required(
"Pivot Point");
266 Curve cu = dna::shallow_zero_initialize();
275 if (curves_id ==
nullptr) {
276 if (pivot_required) {
279 handles.add_new(layout.
char_codes[i], instances.add_reference({}));
289 curves.transform(size_matrix);
291 if (pivot_required) {
297 handles.add_new(layout.
char_codes[i], instances.add_reference(std::move(geometry_set)));
306 instances.resize(layout.
positions.size());
311 for (const int i : range) {
312 handles[i] = char_handles.lookup(layout.char_codes[i]);
313 transforms[i] = math::from_location<float4x4>(
314 {layout.positions[i].x, layout.positions[i].y, 0});
325 if (std::optional<std::string> line_id =
params.get_output_anonymous_attribute_id_if_needed(
329 *line_id, AttrDomain::Instance);
334 if (std::optional<std::string> pivot_id =
params.get_output_anonymous_attribute_id_if_needed(
338 attributes.lookup_or_add_for_write_only_span<
float3>(*pivot_id, AttrDomain::Instance);
352 params.set_default_remaining_outputs();
359 params.set_output(
"Remainder", std::move(layout->truncated_text));
362 if (layout->positions.is_empty()) {
364 params.set_default_remaining_outputs();
369 std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
374 params.set_output(
"Curve Instances", GeometrySet::from_instances(instances.release()));
387 "NodeGeometryStringToCurves",
void BKE_nurbList_free(ListBase *lb)
Low-level operations for curves.
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_GEOMETRY
VFont * BKE_vfont_builtin_get()
void BKE_vfont_build_char(Curve *cu, ListBase *nubase, unsigned int character, const CharInfo *info, float ofsx, float ofsy, float rot, int charidx, float fsize)
bool BKE_vfont_to_curve_ex(Object *ob, Curve *cu, eEditFontMode mode, ListBase *r_nubase, const char32_t **r_text, int *r_text_len, bool *r_text_free, CharTrans **r_chartransdata)
int BLI_str_utf8_offset_from_index(const char *str, size_t str_len, int index_target) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w, const char *__restrict src_c, size_t dst_w_maxncpy) ATTR_NONNULL(1
size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONNULL(1
GeometryNodeStringToCurvesAlignXMode
@ GEO_NODE_STRING_TO_CURVES_ALIGN_X_LEFT
GeometryNodeStringToCurvesPivotMode
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_MIDPOINT
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_RIGHT
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_CENTER
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_LEFT
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_CENTER
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_TOP_RIGHT
@ GEO_NODE_STRING_TO_CURVES_PIVOT_MODE_BOTTOM_LEFT
GeometryNodeStringToCurvesAlignYMode
@ GEO_NODE_STRING_TO_CURVES_ALIGN_Y_TOP_BASELINE
GeometryNodeStringToCurvesOverflowMode
@ GEO_NODE_STRING_TO_CURVES_MODE_TRUNCATE
@ GEO_NODE_STRING_TO_CURVES_MODE_SCALE_TO_FIT
@ GEO_NODE_STRING_TO_CURVES_MODE_OVERFLOW
#define NOD_REGISTER_NODE(REGISTER_FUNC)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiTemplateID(uiLayout *layout, const bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter=UI_TEMPLATE_ID_FILTER_ALL, bool live_icon=false, const char *text=nullptr)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
void reinitialize(const int64_t new_size)
IndexRange index_range() const
void resize(const int64_t new_size)
local_group_size(16, 16) .push_constant(Type b
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
Curves * curve_legacy_to_curves(const Curve &curve_legacy)
void node_type_size(bNodeType *ntype, int width, int minwidth, int maxwidth)
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void node_register_type(bNodeType *ntype)
std::optional< Bounds< T > > min_max(const std::optional< Bounds< T > > &a, const T &b)
void debug_randomize_curve_order(bke::CurvesGeometry *curves)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
static Map< int, int > create_curve_instances(GeoNodeExecParams ¶ms, TextLayout &layout, bke::Instances &instances)
static void add_instances_from_handles(bke::Instances &instances, const Map< int, int > &char_handles, const TextLayout &layout)
static void create_attributes(GeoNodeExecParams ¶ms, const TextLayout &layout, bke::Instances &instances)
static void node_init(bNodeTree *, bNode *node)
static float3 get_pivot_point(GeoNodeExecParams ¶ms, bke::CurvesGeometry &curves)
static void node_layout(uiLayout *layout, bContext *C, PointerRNA *ptr)
static std::optional< TextLayout > get_text_layout(GeoNodeExecParams ¶ms)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static void node_register()
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 2 > float2
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
static void text_free(SpaceLink *sl)
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
MutableVArraySpan< T > span
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
Vector< char32_t > char_codes
std::string truncated_text
Array< int > line_numbers
Map< int, float3 > pivot_points
Vector< float2 > positions