+#ifndef _di_f_utf_is_print_not_
+ f_status_t f_utf_is_print_not(const f_string_t sequence, const f_number_unsigned_t width_max) {
+
+ if (width_max < 1) return F_data_not;
+
+ if (macro_f_utf_byte_width_is(*sequence)) {
+ if (macro_f_utf_byte_width_is(*sequence) > width_max) return F_status_set_error(F_complete_not_utf);
+ if (macro_f_utf_byte_width_is(*sequence) == 1) return F_status_set_error(F_utf_fragment);
+
+ f_utf_char_t utf = 0;
+
+ {
+ const f_status_t status = private_f_utf_char_to_character(sequence, width_max, &utf);
+ if (F_status_is_error(status)) return status;
+ }
+
+ // Control, combining, joiner, and zero-width characters are non-printing.
+ if (private_f_utf_character_is_control(utf)) return F_true;
+ if (private_f_utf_character_is_combining(utf)) return F_true;
+ if (private_f_utf_character_is_joiner(utf)) return F_true;
+ if (private_f_utf_character_is_zero_width(utf)) return F_true;
+
+ return private_f_utf_character_is_print_not(utf);
+ }
+
+ // These control characters are non-printing.
+ if (*sequence >= 0x00 && *sequence < 0x09) return F_true;
+ if (*sequence > 0x0b && *sequence < 0x20) return F_true;
+ if (*sequence == 0x7f) return F_true;
+
+ return F_false;
+ }
+#endif // _di_f_utf_is_print_not_
+