Blender  V3.3
editfont.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <wchar.h>
13 
14 #include "MEM_guardedalloc.h"
15 
16 #include "BLI_blenlib.h"
17 #include "BLI_math.h"
18 #include "BLI_string_cursor_utf8.h"
19 #include "BLI_utildefines.h"
20 
21 #include "DNA_curve_types.h"
22 #include "DNA_object_types.h"
23 #include "DNA_scene_types.h"
24 #include "DNA_text_types.h"
25 #include "DNA_vfont_types.h"
26 
27 #include "BKE_context.h"
28 #include "BKE_curve.h"
29 #include "BKE_lib_id.h"
30 #include "BKE_main.h"
31 #include "BKE_object.h"
32 #include "BKE_report.h"
33 #include "BKE_vfont.h"
34 
35 #include "DEG_depsgraph.h"
36 #include "DEG_depsgraph_query.h"
37 
38 #include "RNA_access.h"
39 #include "RNA_define.h"
40 
41 #include "WM_api.h"
42 #include "WM_types.h"
43 
44 #include "ED_curve.h"
45 #include "ED_object.h"
46 #include "ED_outliner.h"
47 #include "ED_screen.h"
48 #include "ED_view3d.h"
49 
50 #include "UI_interface.h"
51 
52 #include "curve_intern.h"
53 
54 #define MAXTEXT 32766
55 
56 static int kill_selection(Object *obedit, int ins);
57 
58 /* -------------------------------------------------------------------- */
62 static char32_t findaccent(char32_t char1, const char code)
63 {
64  char32_t new = 0;
65 
66  if (char1 == 'a') {
67  if (code == '`') {
68  new = 224;
69  }
70  else if (code == 39) {
71  new = 225;
72  }
73  else if (code == '^') {
74  new = 226;
75  }
76  else if (code == '~') {
77  new = 227;
78  }
79  else if (code == '"') {
80  new = 228;
81  }
82  else if (code == 'o') {
83  new = 229;
84  }
85  else if (code == 'e') {
86  new = 230;
87  }
88  else if (code == '-') {
89  new = 170;
90  }
91  }
92  else if (char1 == 'c') {
93  if (code == ',') {
94  new = 231;
95  }
96  else if (code == '|') {
97  new = 162;
98  }
99  else if (code == 'o') {
100  new = 169;
101  }
102  }
103  else if (char1 == 'e') {
104  if (code == '`') {
105  new = 232;
106  }
107  else if (code == 39) {
108  new = 233;
109  }
110  else if (code == '^') {
111  new = 234;
112  }
113  else if (code == '"') {
114  new = 235;
115  }
116  }
117  else if (char1 == 'i') {
118  if (code == '`') {
119  new = 236;
120  }
121  else if (code == 39) {
122  new = 237;
123  }
124  else if (code == '^') {
125  new = 238;
126  }
127  else if (code == '"') {
128  new = 239;
129  }
130  }
131  else if (char1 == 'n') {
132  if (code == '~') {
133  new = 241;
134  }
135  }
136  else if (char1 == 'o') {
137  if (code == '`') {
138  new = 242;
139  }
140  else if (code == 39) {
141  new = 243;
142  }
143  else if (code == '^') {
144  new = 244;
145  }
146  else if (code == '~') {
147  new = 245;
148  }
149  else if (code == '"') {
150  new = 246;
151  }
152  else if (code == '/') {
153  new = 248;
154  }
155  else if (code == '-') {
156  new = 186;
157  }
158  else if (code == 'e') {
159  new = 339;
160  }
161  else if (code == 'c') {
162  new = 169;
163  }
164  else if (code == 'r') {
165  new = 174;
166  }
167  }
168  else if (char1 == 'r') {
169  if (code == 'o') {
170  new = 174;
171  }
172  }
173  else if (char1 == 's') {
174  if (code == 's') {
175  new = 167;
176  }
177  }
178  else if (char1 == 't') {
179  if (code == 'm') {
180  new = 8482;
181  }
182  }
183  else if (char1 == 'u') {
184  if (code == '`') {
185  new = 249;
186  }
187  else if (code == 39) {
188  new = 250;
189  }
190  else if (code == '^') {
191  new = 251;
192  }
193  else if (code == '"') {
194  new = 252;
195  }
196  }
197  else if (char1 == 'y') {
198  if (code == 39) {
199  new = 253;
200  }
201  else if (code == '"') {
202  new = 255;
203  }
204  }
205  else if (char1 == 'A') {
206  if (code == '`') {
207  new = 192;
208  }
209  else if (code == 39) {
210  new = 193;
211  }
212  else if (code == '^') {
213  new = 194;
214  }
215  else if (code == '~') {
216  new = 195;
217  }
218  else if (code == '"') {
219  new = 196;
220  }
221  else if (code == 'o') {
222  new = 197;
223  }
224  else if (code == 'e') {
225  new = 198;
226  }
227  }
228  else if (char1 == 'C') {
229  if (code == ',') {
230  new = 199;
231  }
232  }
233  else if (char1 == 'E') {
234  if (code == '`') {
235  new = 200;
236  }
237  else if (code == 39) {
238  new = 201;
239  }
240  else if (code == '^') {
241  new = 202;
242  }
243  else if (code == '"') {
244  new = 203;
245  }
246  }
247  else if (char1 == 'I') {
248  if (code == '`') {
249  new = 204;
250  }
251  else if (code == 39) {
252  new = 205;
253  }
254  else if (code == '^') {
255  new = 206;
256  }
257  else if (code == '"') {
258  new = 207;
259  }
260  }
261  else if (char1 == 'N') {
262  if (code == '~') {
263  new = 209;
264  }
265  }
266  else if (char1 == 'O') {
267  if (code == '`') {
268  new = 210;
269  }
270  else if (code == 39) {
271  new = 211;
272  }
273  else if (code == '^') {
274  new = 212;
275  }
276  else if (code == '~') {
277  new = 213;
278  }
279  else if (code == '"') {
280  new = 214;
281  }
282  else if (code == '/') {
283  new = 216;
284  }
285  else if (code == 'e') {
286  new = 141;
287  }
288  }
289  else if (char1 == 'U') {
290  if (code == '`') {
291  new = 217;
292  }
293  else if (code == 39) {
294  new = 218;
295  }
296  else if (code == '^') {
297  new = 219;
298  }
299  else if (code == '"') {
300  new = 220;
301  }
302  }
303  else if (char1 == 'Y') {
304  if (code == 39) {
305  new = 221;
306  }
307  }
308  else if (char1 == '1') {
309  if (code == '4') {
310  new = 188;
311  }
312  if (code == '2') {
313  new = 189;
314  }
315  }
316  else if (char1 == '3') {
317  if (code == '4') {
318  new = 190;
319  }
320  }
321  else if (char1 == ':') {
322  if (code == '-') {
323  new = 247;
324  }
325  }
326  else if (char1 == '-') {
327  if (code == ':') {
328  new = 247;
329  }
330  if (code == '|') {
331  new = 8224;
332  }
333  if (code == '+') {
334  new = 177;
335  }
336  }
337  else if (char1 == '|') {
338  if (code == '-') {
339  new = 8224;
340  }
341  if (code == '=') {
342  new = 8225;
343  }
344  }
345  else if (char1 == '=') {
346  if (code == '|') {
347  new = 8225;
348  }
349  }
350  else if (char1 == '+') {
351  if (code == '-') {
352  new = 177;
353  }
354  }
355 
356  if (new) {
357  return new;
358  }
359  return char1;
360 }
361 
362 static int insert_into_textbuf(Object *obedit, uintptr_t c)
363 {
364  Curve *cu = obedit->data;
365  EditFont *ef = cu->editfont;
366 
367  if (ef->len < MAXTEXT - 1) {
368  int x;
369 
370  for (x = ef->len; x > ef->pos; x--) {
371  ef->textbuf[x] = ef->textbuf[x - 1];
372  }
373  for (x = ef->len; x > ef->pos; x--) {
374  ef->textbufinfo[x] = ef->textbufinfo[x - 1];
375  }
376  ef->textbuf[ef->pos] = c;
377  ef->textbufinfo[ef->pos] = cu->curinfo;
378  ef->textbufinfo[ef->pos].kern = 0;
379  ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
380 
381  ef->pos++;
382  ef->len++;
383  ef->textbuf[ef->len] = '\0';
384 
385  return 1;
386  }
387  return 0;
388 }
389 
390 static void text_update_edited(bContext *C, Object *obedit, int mode)
391 {
392  Curve *cu = obedit->data;
393  EditFont *ef = cu->editfont;
394 
395  BLI_assert(ef->len >= 0);
396 
397  /* run update first since it can move the cursor */
398  if (mode == FO_EDIT) {
399  /* re-tesselllate */
400  DEG_id_tag_update(obedit->data, 0);
401  }
402  else {
403  /* depsgraph runs above, but since we're not tagging for update, call direct */
404  /* We need evaluated data here. */
407  }
408 
409  cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
410 
411  if (obedit->totcol > 0) {
412  obedit->actcol = cu->curinfo.mat_nr;
413 
414  /* since this array is calloc'd, it can be 0 even though we try ensure
415  * (mat_nr > 0) almost everywhere */
416  if (obedit->actcol < 1) {
417  obedit->actcol = 1;
418  }
419  }
420 
423 }
424 
425 static int kill_selection(Object *obedit, int ins) /* ins == new character len */
426 {
427  Curve *cu = obedit->data;
428  EditFont *ef = cu->editfont;
429  int selend, selstart, direction;
430  int getfrom;
431 
432  direction = BKE_vfont_select_get(obedit, &selstart, &selend);
433  if (direction) {
434  int size;
435  if (ef->pos >= selstart) {
436  ef->pos = selstart + ins;
437  }
438  if ((direction == -1) && ins) {
439  selstart += ins;
440  selend += ins;
441  }
442  getfrom = selend + 1;
443  size = ef->len - selend; /* This is equivalent to: `(ef->len - getfrom) + 1(null)`. */
444  memmove(ef->textbuf + selstart, ef->textbuf + getfrom, sizeof(*ef->textbuf) * size);
445  memmove(ef->textbufinfo + selstart, ef->textbufinfo + getfrom, sizeof(CharInfo) * size);
446  ef->len -= ((selend - selstart) + 1);
447  ef->selstart = ef->selend = 0;
448  }
449 
450  return direction;
451 }
452 
455 /* -------------------------------------------------------------------- */
459 /* text_update_edited(C, scene, obedit, 1, FO_EDIT); */
460 static bool font_paste_wchar(Object *obedit,
461  const char32_t *str,
462  const size_t str_len,
463  /* optional */
464  struct CharInfo *str_info)
465 {
466  Curve *cu = obedit->data;
467  EditFont *ef = cu->editfont;
468  int selend, selstart;
469 
470  if (BKE_vfont_select_get(obedit, &selstart, &selend) == 0) {
471  selstart = selend = 0;
472  }
473 
474  /* Verify that the copy buffer => [copy buffer len] + ef->len < MAXTEXT */
475  if ((ef->len + str_len) - (selend - selstart) <= MAXTEXT) {
476 
477  kill_selection(obedit, 0);
478 
479  if (str_len) {
480  int size = (ef->len * sizeof(*ef->textbuf)) - (ef->pos * sizeof(*ef->textbuf)) +
481  sizeof(*ef->textbuf);
482  memmove(ef->textbuf + ef->pos + str_len, ef->textbuf + ef->pos, size);
483  memcpy(ef->textbuf + ef->pos, str, str_len * sizeof(*ef->textbuf));
484 
485  memmove(ef->textbufinfo + ef->pos + str_len,
486  ef->textbufinfo + ef->pos,
487  (ef->len - ef->pos + 1) * sizeof(CharInfo));
488  if (str_info) {
489  memcpy(ef->textbufinfo + ef->pos, str_info, str_len * sizeof(CharInfo));
490  }
491  else {
492  memset(ef->textbufinfo + ef->pos, '\0', str_len * sizeof(CharInfo));
493  }
494 
495  ef->len += str_len;
496  ef->pos += str_len;
497  }
498 
499  return true;
500  }
501 
502  return false;
503 }
504 
505 static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
506 {
507  Object *obedit = CTX_data_edit_object(C);
508  bool retval;
509 
510  int tmplen;
511 
512  char32_t *mem = MEM_mallocN((sizeof(*mem) * (str_len + 1)), __func__);
513 
514  tmplen = BLI_str_utf8_as_utf32(mem, str, str_len + 1);
515 
516  retval = font_paste_wchar(obedit, mem, tmplen, NULL);
517 
518  MEM_freeN(mem);
519 
520  return retval;
521 }
522 
525 /* -------------------------------------------------------------------- */
529 static int paste_from_file(bContext *C, ReportList *reports, const char *filepath)
530 {
531  Object *obedit = CTX_data_edit_object(C);
532  char *strp;
533  size_t filelen;
534  int retval;
535 
536  strp = BLI_file_read_text_as_mem(filepath, 1, &filelen);
537  if (strp == NULL) {
538  BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filepath);
539  return OPERATOR_CANCELLED;
540  }
541  strp[filelen] = 0;
542 
543  if (font_paste_utf8(C, strp, filelen)) {
544  text_update_edited(C, obedit, FO_EDIT);
545  retval = OPERATOR_FINISHED;
546  }
547  else {
548  BKE_reportf(reports, RPT_ERROR, "File too long %s", filepath);
549  retval = OPERATOR_CANCELLED;
550  }
551 
552  MEM_freeN(strp);
553 
554  return retval;
555 }
556 
558 {
559  char *filepath;
560  int retval;
561 
562  filepath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0, NULL);
563  retval = paste_from_file(C, op->reports, filepath);
564  MEM_freeN(filepath);
565 
566  return retval;
567 }
568 
569 static int paste_from_file_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
570 {
571  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
572  return paste_from_file_exec(C, op);
573  }
574 
576 
577  return OPERATOR_RUNNING_MODAL;
578 }
579 
581 {
582  /* identifiers */
583  ot->name = "Paste File";
584  ot->description = "Paste contents from file";
585  ot->idname = "FONT_OT_text_paste_from_file";
586 
587  /* api callbacks */
591 
592  /* flags */
594 
595  /* properties */
598  FILE_SPECIAL,
603 }
604 
607 /* -------------------------------------------------------------------- */
611 static void txt_add_object(bContext *C,
612  const TextLine *firstline,
613  int totline,
614  const float offset[3])
615 {
616  Main *bmain = CTX_data_main(C);
619  ViewLayer *view_layer = CTX_data_view_layer(C);
620  Curve *cu;
621  Object *obedit;
622  Base *base;
623  const struct TextLine *tmp;
624  int nchars = 0, nbytes = 0;
625  char *s;
626  int a;
627  const float rot[3] = {0.0f, 0.0f, 0.0f};
628 
629  obedit = BKE_object_add(bmain, view_layer, OB_FONT, NULL);
630  base = view_layer->basact;
631 
632  /* seems to assume view align ? TODO: look into this, could be an operator option. */
634 
636 
637  add_v3_v3(obedit->loc, offset);
638 
639  cu = obedit->data;
641  id_us_plus(&cu->vfont->id);
642 
643  for (tmp = firstline, a = 0; nbytes < MAXTEXT && a < totline; tmp = tmp->next, a++) {
644  size_t nchars_line, nbytes_line;
645  nchars_line = BLI_strlen_utf8_ex(tmp->line, &nbytes_line);
646  nchars += nchars_line + 1;
647  nbytes += nbytes_line + 1;
648  }
649 
650  if (cu->str) {
651  MEM_freeN(cu->str);
652  }
653  if (cu->strinfo) {
654  MEM_freeN(cu->strinfo);
655  }
656 
657  cu->str = MEM_mallocN(nbytes + 4, "str");
658  cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
659 
660  cu->len = 0;
661  cu->len_char32 = nchars - 1;
662  cu->pos = 0;
663 
664  s = cu->str;
665 
666  for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) {
667  size_t nbytes_line;
668 
669  nbytes_line = BLI_strcpy_rlen(s, tmp->line);
670 
671  s += nbytes_line;
672  cu->len += nbytes_line;
673 
674  if (tmp->next) {
675  nbytes_line = BLI_strcpy_rlen(s, "\n");
676 
677  s += nbytes_line;
678  cu->len += nbytes_line;
679  }
680  }
681 
682  cu->pos = cu->len_char32;
683  *s = '\0';
684 
686 }
687 
688 void ED_text_to_object(bContext *C, const Text *text, const bool split_lines)
689 {
690  Main *bmain = CTX_data_main(C);
692  const TextLine *line;
693  float offset[3];
694  int linenum = 0;
695 
696  if (!text || !text->lines.first) {
697  return;
698  }
699 
700  if (split_lines) {
701  for (line = text->lines.first; line; line = line->next) {
702  /* skip lines with no text, but still make space for them */
703  if (line->line[0] == '\0') {
704  linenum++;
705  continue;
706  }
707 
708  /* do the translation */
709  offset[0] = 0;
710  offset[1] = -linenum;
711  offset[2] = 0;
712 
713  if (rv3d) {
714  mul_mat3_m4_v3(rv3d->viewinv, offset);
715  }
716 
717  txt_add_object(C, line, 1, offset);
718 
719  linenum++;
720  }
721  }
722  else {
723  offset[0] = 0.0f;
724  offset[1] = 0.0f;
725  offset[2] = 0.0f;
726 
728  }
729 
732 }
733 
736 /* -------------------------------------------------------------------- */
740 static const EnumPropertyItem style_items[] = {
741  {CU_CHINFO_BOLD, "BOLD", 0, "Bold", ""},
742  {CU_CHINFO_ITALIC, "ITALIC", 0, "Italic", ""},
743  {CU_CHINFO_UNDERLINE, "UNDERLINE", 0, "Underline", ""},
744  {CU_CHINFO_SMALLCAPS, "SMALL_CAPS", 0, "Small Caps", ""},
745  {0, NULL, 0, NULL, NULL},
746 };
747 
748 static int set_style(bContext *C, const int style, const bool clear)
749 {
750  Object *obedit = CTX_data_edit_object(C);
751  Curve *cu = obedit->data;
752  EditFont *ef = cu->editfont;
753  int i, selstart, selend;
754 
755  if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
756  return OPERATOR_CANCELLED;
757  }
758 
759  for (i = selstart; i <= selend; i++) {
760  if (clear) {
761  ef->textbufinfo[i].flag &= ~style;
762  }
763  else {
764  ef->textbufinfo[i].flag |= style;
765  }
766  }
767 
768  DEG_id_tag_update(obedit->data, 0);
770 
771  return OPERATOR_FINISHED;
772 }
773 
775 {
776  const int style = RNA_enum_get(op->ptr, "style");
777  const bool clear = RNA_boolean_get(op->ptr, "clear");
778 
779  return set_style(C, style, clear);
780 }
781 
783 {
784  /* identifiers */
785  ot->name = "Set Style";
786  ot->description = "Set font style";
787  ot->idname = "FONT_OT_style_set";
788 
789  /* api callbacks */
792 
793  /* flags */
795 
796  /* properties */
797  RNA_def_enum(
798  ot->srna, "style", style_items, CU_CHINFO_BOLD, "Style", "Style to set selection to");
799  RNA_def_boolean(ot->srna, "clear", 0, "Clear", "Clear style rather than setting it");
800 }
801 
804 /* -------------------------------------------------------------------- */
809 {
810  Object *obedit = CTX_data_edit_object(C);
811  Curve *cu = obedit->data;
812  int style, clear, selstart, selend;
813 
814  if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
815  return OPERATOR_CANCELLED;
816  }
817 
818  style = RNA_enum_get(op->ptr, "style");
819 
820  cu->curinfo.flag ^= style;
821  clear = (cu->curinfo.flag & style) == 0;
822 
823  return set_style(C, style, clear);
824 }
825 
827 {
828  /* identifiers */
829  ot->name = "Toggle Style";
830  ot->description = "Toggle font style";
831  ot->idname = "FONT_OT_style_toggle";
832 
833  /* api callbacks */
836 
837  /* flags */
839 
840  /* properties */
841  RNA_def_enum(
842  ot->srna, "style", style_items, CU_CHINFO_BOLD, "Style", "Style to set selection to");
843 }
844 
847 /* -------------------------------------------------------------------- */
852 {
853  Object *obedit = CTX_data_edit_object(C);
854  Curve *cu = obedit->data;
855  EditFont *ef = cu->editfont;
856 
857  if (ef->len) {
858  ef->selstart = 1;
859  ef->selend = ef->len;
860  ef->pos = ef->len;
861 
863 
864  return OPERATOR_FINISHED;
865  }
866  return OPERATOR_CANCELLED;
867 }
868 
870 {
871  /* identifiers */
872  ot->name = "Select All";
873  ot->description = "Select all text";
874  ot->idname = "FONT_OT_select_all";
875 
876  /* api callbacks */
879 
880  /* flags */
882 }
883 
886 /* -------------------------------------------------------------------- */
890 static void copy_selection(Object *obedit)
891 {
892  int selstart, selend;
893 
894  if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
895  Curve *cu = obedit->data;
896  EditFont *ef = cu->editfont;
897  char *buf = NULL;
898  char32_t *text_buf;
899  size_t len_utf8;
900 
901  /* internal clipboard (for style) */
903  ef->textbuf + selstart, ef->textbufinfo + selstart, selend - selstart + 1);
904  BKE_vfont_clipboard_get(&text_buf, NULL, &len_utf8, NULL);
905 
906  /* system clipboard */
907  buf = MEM_mallocN(len_utf8 + 1, __func__);
908  if (buf) {
909  BLI_str_utf32_as_utf8(buf, text_buf, len_utf8 + 1);
910  WM_clipboard_text_set(buf, false);
911  MEM_freeN(buf);
912  }
913  }
914 }
915 
917 {
918  Object *obedit = CTX_data_edit_object(C);
919 
920  copy_selection(obedit);
921 
922  return OPERATOR_FINISHED;
923 }
924 
926 {
927  /* identifiers */
928  ot->name = "Copy Text";
929  ot->description = "Copy selected text to clipboard";
930  ot->idname = "FONT_OT_text_copy";
931 
932  /* api callbacks */
935 }
936 
939 /* -------------------------------------------------------------------- */
944 {
945  Object *obedit = CTX_data_edit_object(C);
946  int selstart, selend;
947 
948  if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
949  return OPERATOR_CANCELLED;
950  }
951 
952  copy_selection(obedit);
953  kill_selection(obedit, 0);
954 
955  text_update_edited(C, obedit, FO_EDIT);
956 
957  return OPERATOR_FINISHED;
958 }
959 
961 {
962  /* identifiers */
963  ot->name = "Cut Text";
964  ot->description = "Cut selected text to clipboard";
965  ot->idname = "FONT_OT_text_cut";
966 
967  /* api callbacks */
968  ot->exec = cut_text_exec;
970 
971  /* flags */
973 }
974 
977 /* -------------------------------------------------------------------- */
981 static bool paste_selection(Object *obedit, ReportList *reports)
982 {
983  char32_t *text_buf;
984  CharInfo *info_buf;
985  size_t len;
986 
987  BKE_vfont_clipboard_get(&text_buf, &info_buf, NULL, &len);
988 
989  if (font_paste_wchar(obedit, text_buf, len, info_buf)) {
990  return true;
991  }
992 
993  BKE_report(reports, RPT_WARNING, "Text too long");
994  return false;
995 }
996 
998 {
999  Object *obedit = CTX_data_edit_object(C);
1000  int retval;
1001  size_t len_utf8;
1002  char32_t *text_buf;
1003 
1004  /* Store both clipboards as utf8 for comparison,
1005  * Give priority to the internal 'vfont' clipboard with its 'CharInfo' text styles
1006  * as long as its synchronized with the systems clipboard. */
1007  struct {
1008  char *buf;
1009  int len;
1010  } clipboard_system = {NULL}, clipboard_vfont = {NULL};
1011 
1012  clipboard_system.buf = WM_clipboard_text_get(false, &clipboard_system.len);
1013 
1014  if (clipboard_system.buf == NULL) {
1015  return OPERATOR_CANCELLED;
1016  }
1017 
1018  BKE_vfont_clipboard_get(&text_buf, NULL, &len_utf8, NULL);
1019 
1020  if (text_buf) {
1021  clipboard_vfont.buf = MEM_mallocN(len_utf8 + 1, __func__);
1022 
1023  if (clipboard_vfont.buf == NULL) {
1024  MEM_freeN(clipboard_system.buf);
1025  return OPERATOR_CANCELLED;
1026  }
1027 
1028  BLI_str_utf32_as_utf8(clipboard_vfont.buf, text_buf, len_utf8 + 1);
1029  }
1030 
1031  if (clipboard_vfont.buf && STREQ(clipboard_vfont.buf, clipboard_system.buf)) {
1032  retval = paste_selection(obedit, op->reports) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1033  }
1034  else {
1035  if ((clipboard_system.len <= MAXTEXT) &&
1036  font_paste_utf8(C, clipboard_system.buf, clipboard_system.len)) {
1037  text_update_edited(C, obedit, FO_EDIT);
1038  retval = OPERATOR_FINISHED;
1039  }
1040  else {
1041  BKE_report(op->reports, RPT_ERROR, "Clipboard too long");
1042  retval = OPERATOR_CANCELLED;
1043  }
1044 
1045  /* free the existent clipboard buffer */
1047  }
1048 
1049  if (retval != OPERATOR_CANCELLED) {
1050  text_update_edited(C, obedit, FO_EDIT);
1051  }
1052 
1053  /* cleanup */
1054  if (clipboard_vfont.buf) {
1055  MEM_freeN(clipboard_vfont.buf);
1056  }
1057 
1058  MEM_freeN(clipboard_system.buf);
1059 
1060  return retval;
1061 }
1062 
1064 {
1065  /* identifiers */
1066  ot->name = "Paste Text";
1067  ot->description = "Paste text from clipboard";
1068  ot->idname = "FONT_OT_text_paste";
1069 
1070  /* api callbacks */
1071  ot->exec = paste_text_exec;
1073 
1074  /* flags */
1076 }
1077 
1080 /* -------------------------------------------------------------------- */
1085  {LINE_BEGIN, "LINE_BEGIN", 0, "Line Begin", ""},
1086  {LINE_END, "LINE_END", 0, "Line End", ""},
1087  {PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
1088  {NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
1089  {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
1090  {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
1091  {PREV_LINE, "PREVIOUS_LINE", 0, "Previous Line", ""},
1092  {NEXT_LINE, "NEXT_LINE", 0, "Next Line", ""},
1093  {PREV_PAGE, "PREVIOUS_PAGE", 0, "Previous Page", ""},
1094  {NEXT_PAGE, "NEXT_PAGE", 0, "Next Page", ""},
1095  {0, NULL, 0, NULL, NULL},
1096 };
1097 
1098 static int move_cursor(bContext *C, int type, const bool select)
1099 {
1101  Object *obedit = CTX_data_edit_object(C);
1102  Curve *cu = obedit->data;
1103  EditFont *ef = cu->editfont;
1104  int cursmove = -1;
1105 
1106  if ((select) && (ef->selstart == 0)) {
1107  ef->selstart = ef->selend = ef->pos + 1;
1108  }
1109 
1110  switch (type) {
1111  case LINE_BEGIN:
1112  while (ef->pos > 0) {
1113  if (ef->textbuf[ef->pos - 1] == '\n') {
1114  break;
1115  }
1116  if (ef->textbufinfo[ef->pos - 1].flag & CU_CHINFO_WRAP) {
1117  break;
1118  }
1119  ef->pos--;
1120  }
1121  cursmove = FO_CURS;
1122  break;
1123 
1124  case LINE_END:
1125  while (ef->pos < ef->len) {
1126  if (ef->textbuf[ef->pos] == 0) {
1127  break;
1128  }
1129  if (ef->textbuf[ef->pos] == '\n') {
1130  break;
1131  }
1132  if (ef->textbufinfo[ef->pos].flag & CU_CHINFO_WRAP) {
1133  break;
1134  }
1135  ef->pos++;
1136  }
1137  cursmove = FO_CURS;
1138  break;
1139 
1140  case PREV_WORD: {
1141  int pos = ef->pos;
1143  ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
1144  ef->pos = pos;
1145  cursmove = FO_CURS;
1146  break;
1147  }
1148 
1149  case NEXT_WORD: {
1150  int pos = ef->pos;
1152  ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
1153  ef->pos = pos;
1154  cursmove = FO_CURS;
1155  break;
1156  }
1157 
1158  case PREV_CHAR:
1159  ef->pos--;
1160  cursmove = FO_CURS;
1161  break;
1162 
1163  case NEXT_CHAR:
1164  ef->pos++;
1165  cursmove = FO_CURS;
1166 
1167  break;
1168 
1169  case PREV_LINE:
1170  cursmove = FO_CURSUP;
1171  break;
1172 
1173  case NEXT_LINE:
1174  cursmove = FO_CURSDOWN;
1175  break;
1176 
1177  case PREV_PAGE:
1178  cursmove = FO_PAGEUP;
1179  break;
1180 
1181  case NEXT_PAGE:
1182  cursmove = FO_PAGEDOWN;
1183  break;
1184  }
1185 
1186  if (cursmove == -1) {
1187  return OPERATOR_CANCELLED;
1188  }
1189 
1190  if (ef->pos > ef->len) {
1191  ef->pos = ef->len;
1192  }
1193  else if (ef->pos >= MAXTEXT) {
1194  ef->pos = MAXTEXT;
1195  }
1196  else if (ef->pos < 0) {
1197  ef->pos = 0;
1198  }
1199 
1200  /* apply vertical cursor motion to position immediately
1201  * otherwise the selection will lag behind */
1202  if (FO_CURS_IS_MOTION(cursmove)) {
1204  cursmove = FO_CURS;
1205  }
1206 
1207  if (select == 0) {
1208  if (ef->selstart) {
1209  ef->selstart = ef->selend = 0;
1211  }
1212  }
1213 
1214  if (select) {
1215  ef->selend = ef->pos;
1216  }
1217 
1218  text_update_edited(C, obedit, cursmove);
1219 
1220  return OPERATOR_FINISHED;
1221 }
1222 
1223 static int move_exec(bContext *C, wmOperator *op)
1224 {
1225  int type = RNA_enum_get(op->ptr, "type");
1226 
1227  return move_cursor(C, type, false);
1228 }
1229 
1231 {
1232  /* identifiers */
1233  ot->name = "Move Cursor";
1234  ot->description = "Move cursor to position type";
1235  ot->idname = "FONT_OT_move";
1236 
1237  /* api callbacks */
1238  ot->exec = move_exec;
1240 
1241  /* flags */
1243 
1244  /* properties */
1245  RNA_def_enum(ot->srna, "type", move_type_items, LINE_BEGIN, "Type", "Where to move cursor to");
1246 }
1247 
1250 /* -------------------------------------------------------------------- */
1255 {
1256  int type = RNA_enum_get(op->ptr, "type");
1257 
1258  return move_cursor(C, type, true);
1259 }
1260 
1262 {
1263  /* identifiers */
1264  ot->name = "Move Select";
1265  ot->description = "Move the cursor while selecting";
1266  ot->idname = "FONT_OT_move_select";
1267 
1268  /* api callbacks */
1271 
1272  /* flags */
1274 
1275  /* properties */
1276  RNA_def_enum(ot->srna,
1277  "type",
1279  LINE_BEGIN,
1280  "Type",
1281  "Where to move cursor to, to make a selection");
1282 }
1283 
1286 /* -------------------------------------------------------------------- */
1291 {
1292  Object *obedit = CTX_data_edit_object(C);
1293  Curve *cu = obedit->data;
1294  EditFont *ef = cu->editfont;
1295  int kern, delta = RNA_int_get(op->ptr, "delta");
1296  int selstart, selend;
1297  bool changed = false;
1298 
1299  const bool has_select = BKE_vfont_select_get(obedit, &selstart, &selend);
1300  if (has_select) {
1301  selstart -= 1;
1302  }
1303  else {
1304  selstart = selend = ef->pos - 1;
1305  }
1306  selstart = max_ii(0, selstart);
1307 
1308  for (int i = selstart; i <= selend; i++) {
1309  kern = ef->textbufinfo[i].kern + delta;
1310  CLAMP(kern, -20, 20);
1311 
1312  if (ef->textbufinfo[i].kern != kern) {
1313  ef->textbufinfo[i].kern = kern;
1314  changed = true;
1315  }
1316  }
1317 
1318  if (changed) {
1319  text_update_edited(C, obedit, FO_EDIT);
1320 
1321  return OPERATOR_FINISHED;
1322  }
1323  return OPERATOR_CANCELLED;
1324 }
1325 
1327 {
1328  /* identifiers */
1329  ot->name = "Change Spacing";
1330  ot->description = "Change font spacing";
1331  ot->idname = "FONT_OT_change_spacing";
1332 
1333  /* api callbacks */
1336 
1337  /* flags */
1339 
1340  /* properties */
1341  RNA_def_int(ot->srna,
1342  "delta",
1343  1,
1344  -20,
1345  20,
1346  "Delta",
1347  "Amount to decrease or increase character spacing with",
1348  -20,
1349  20);
1350 }
1351 
1354 /* -------------------------------------------------------------------- */
1359 {
1360  Object *obedit = CTX_data_edit_object(C);
1361  Curve *cu = obedit->data;
1362  EditFont *ef = cu->editfont;
1363  int character, delta = RNA_int_get(op->ptr, "delta");
1364 
1365  if (ef->pos <= 0) {
1366  return OPERATOR_CANCELLED;
1367  }
1368 
1369  character = ef->textbuf[ef->pos - 1];
1370  character += delta;
1371  CLAMP(character, 0, 255);
1372 
1373  if (character == ef->textbuf[ef->pos - 1]) {
1374  return OPERATOR_CANCELLED;
1375  }
1376 
1377  ef->textbuf[ef->pos - 1] = character;
1378 
1379  text_update_edited(C, obedit, FO_EDIT);
1380 
1381  return OPERATOR_FINISHED;
1382 }
1383 
1385 {
1386  /* identifiers */
1387  ot->name = "Change Character";
1388  ot->description = "Change font character code";
1389  ot->idname = "FONT_OT_change_character";
1390 
1391  /* api callbacks */
1394 
1395  /* flags */
1397 
1398  /* properties */
1399  RNA_def_int(ot->srna,
1400  "delta",
1401  1,
1402  -255,
1403  255,
1404  "Delta",
1405  "Number to increase or decrease character code with",
1406  -255,
1407  255);
1408 }
1409 
1412 /* -------------------------------------------------------------------- */
1417 {
1418  Object *obedit = CTX_data_edit_object(C);
1419  Curve *cu = obedit->data;
1420  EditFont *ef = cu->editfont;
1421 
1422  insert_into_textbuf(obedit, '\n');
1423 
1424  ef->selstart = ef->selend = 0;
1425 
1426  text_update_edited(C, obedit, FO_EDIT);
1427 
1428  return OPERATOR_FINISHED;
1429 }
1430 
1432 {
1433  /* identifiers */
1434  ot->name = "Line Break";
1435  ot->description = "Insert line break at cursor position";
1436  ot->idname = "FONT_OT_line_break";
1437 
1438  /* api callbacks */
1439  ot->exec = line_break_exec;
1441 
1442  /* flags */
1444 }
1445 
1448 /* -------------------------------------------------------------------- */
1453  {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
1454  {DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
1455  {DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
1456  {DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
1457  {DEL_SELECTION, "SELECTION", 0, "Selection", ""},
1458  {DEL_NEXT_SEL, "NEXT_OR_SELECTION", 0, "Next or Selection", ""},
1459  {DEL_PREV_SEL, "PREVIOUS_OR_SELECTION", 0, "Previous or Selection", ""},
1460  {0, NULL, 0, NULL, NULL},
1461 };
1462 
1464 {
1465  Object *obedit = CTX_data_edit_object(C);
1466  Curve *cu = obedit->data;
1467  EditFont *ef = cu->editfont;
1468  int selstart, selend, type = RNA_enum_get(op->ptr, "type");
1469  int range[2] = {0, 0};
1470  bool has_select = false;
1471 
1472  if (ef->len == 0) {
1473  return OPERATOR_CANCELLED;
1474  }
1475 
1476  if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
1477  if (type == DEL_NEXT_SEL) {
1478  type = DEL_SELECTION;
1479  }
1480  else if (type == DEL_PREV_SEL) {
1481  type = DEL_SELECTION;
1482  }
1483  has_select = true;
1484  }
1485  else {
1486  if (type == DEL_NEXT_SEL) {
1487  type = DEL_NEXT_CHAR;
1488  }
1489  else if (type == DEL_PREV_SEL) {
1490  type = DEL_PREV_CHAR;
1491  }
1492  }
1493 
1494  switch (type) {
1495  case DEL_SELECTION:
1496  if (!kill_selection(obedit, 0)) {
1497  return OPERATOR_CANCELLED;
1498  }
1499  break;
1500  case DEL_PREV_CHAR:
1501  if (ef->pos <= 0) {
1502  return OPERATOR_CANCELLED;
1503  }
1504 
1505  range[0] = ef->pos - 1;
1506  range[1] = ef->pos;
1507 
1508  ef->pos--;
1509  break;
1510  case DEL_NEXT_CHAR:
1511  if (ef->pos >= ef->len) {
1512  return OPERATOR_CANCELLED;
1513  }
1514 
1515  range[0] = ef->pos;
1516  range[1] = ef->pos + 1;
1517  break;
1518  case DEL_NEXT_WORD: {
1519  int pos = ef->pos;
1521  ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
1522  range[0] = ef->pos;
1523  range[1] = pos;
1524  break;
1525  }
1526 
1527  case DEL_PREV_WORD: {
1528  int pos = ef->pos;
1530  ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
1531  range[0] = pos;
1532  range[1] = ef->pos;
1533  ef->pos = pos;
1534  break;
1535  }
1536  default:
1537  return OPERATOR_CANCELLED;
1538  }
1539 
1540  if (range[0] != range[1]) {
1541  BLI_assert(range[0] < range[1]);
1542  int len_remove = range[1] - range[0];
1543  int len_tail = ef->len - range[1];
1544  if (has_select) {
1545  for (int i = 0; i < 2; i++) {
1546  int *sel = i ? &ef->selend : &ef->selstart;
1547  if (*sel <= range[0]) {
1548  /* pass */
1549  }
1550  else if (*sel >= range[1]) {
1551  *sel -= len_remove;
1552  }
1553  else {
1554  BLI_assert(*sel < range[1]);
1555  /* pass */
1556  *sel = range[0];
1557  }
1558  }
1559  }
1560 
1561  memmove(&ef->textbuf[range[0]], &ef->textbuf[range[1]], sizeof(*ef->textbuf) * len_tail);
1562  memmove(&ef->textbufinfo[range[0]],
1563  &ef->textbufinfo[range[1]],
1564  sizeof(*ef->textbufinfo) * len_tail);
1565 
1566  ef->len -= len_remove;
1567  ef->textbuf[ef->len] = '\0';
1568 
1569  BKE_vfont_select_clamp(obedit);
1570  }
1571 
1572  text_update_edited(C, obedit, FO_EDIT);
1573 
1574  return OPERATOR_FINISHED;
1575 }
1576 
1578 {
1579  /* identifiers */
1580  ot->name = "Delete";
1581  ot->description = "Delete text by cursor position";
1582  ot->idname = "FONT_OT_delete";
1583 
1584  /* api callbacks */
1585  ot->exec = delete_exec;
1587 
1588  /* flags */
1590 
1591  /* properties */
1592  RNA_def_enum(ot->srna,
1593  "type",
1595  DEL_PREV_CHAR,
1596  "Type",
1597  "Which part of the text to delete");
1598 }
1599 
1602 /* -------------------------------------------------------------------- */
1607 {
1608  Object *obedit = CTX_data_edit_object(C);
1609  char *inserted_utf8;
1610  char32_t *inserted_text;
1611  int a, len;
1612 
1613  if (!RNA_struct_property_is_set(op->ptr, "text")) {
1614  return OPERATOR_CANCELLED;
1615  }
1616 
1617  inserted_utf8 = RNA_string_get_alloc(op->ptr, "text", NULL, 0, NULL);
1618  len = BLI_strlen_utf8(inserted_utf8);
1619 
1620  inserted_text = MEM_callocN(sizeof(char32_t) * (len + 1), "FONT_insert_text");
1621  len = BLI_str_utf8_as_utf32(inserted_text, inserted_utf8, MAXTEXT);
1622 
1623  for (a = 0; a < len; a++) {
1624  insert_into_textbuf(obedit, inserted_text[a]);
1625  }
1626 
1627  MEM_freeN(inserted_text);
1628  MEM_freeN(inserted_utf8);
1629 
1630  kill_selection(obedit, len);
1631  text_update_edited(C, obedit, FO_EDIT);
1632 
1633  return OPERATOR_FINISHED;
1634 }
1635 
1636 static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1637 {
1638  Object *obedit = CTX_data_edit_object(C);
1639  Curve *cu = obedit->data;
1640  EditFont *ef = cu->editfont;
1641  static bool accentcode = false;
1642  const bool alt = event->modifier & KM_ALT;
1643  const bool shift = event->modifier & KM_SHIFT;
1644  const bool ctrl = event->modifier & KM_CTRL;
1645  char32_t insert_char_override = 0;
1646  char32_t inserted_text[2] = {0};
1647 
1648  if (RNA_struct_property_is_set(op->ptr, "text")) {
1649  return insert_text_exec(C, op);
1650  }
1651 
1652  if (RNA_struct_property_is_set(op->ptr, "accent")) {
1653  if (ef->len != 0 && ef->pos > 0) {
1654  accentcode = true;
1655  }
1656  return OPERATOR_FINISHED;
1657  }
1658 
1659  if (event->type == EVT_BACKSPACEKEY) {
1660  if (alt && ef->len != 0 && ef->pos > 0) {
1661  accentcode = true;
1662  }
1663  return OPERATOR_PASS_THROUGH;
1664  }
1665 
1666  /* Tab typically exit edit-mode, but we allow it to be typed using modifier keys. */
1667  if (event->type == EVT_TABKEY) {
1668  if ((alt || ctrl || shift) == 0) {
1669  return OPERATOR_PASS_THROUGH;
1670  }
1671  insert_char_override = '\t';
1672  }
1673 
1674  if (insert_char_override || event->utf8_buf[0]) {
1675  if (insert_char_override) {
1676  /* Handle case like TAB ('\t'). */
1677  inserted_text[0] = insert_char_override;
1678  insert_into_textbuf(obedit, insert_char_override);
1679  text_update_edited(C, obedit, FO_EDIT);
1680  }
1681  else {
1682  BLI_assert(event->utf8_buf[0]);
1683  if (accentcode) {
1684  if (ef->pos > 0) {
1685  inserted_text[0] = findaccent(ef->textbuf[ef->pos - 1],
1687  ef->textbuf[ef->pos - 1] = inserted_text[0];
1688  }
1689  accentcode = false;
1690  }
1691  else if (event->utf8_buf[0]) {
1692  inserted_text[0] = BLI_str_utf8_as_unicode(event->utf8_buf);
1693  insert_into_textbuf(obedit, inserted_text[0]);
1694  accentcode = false;
1695  }
1696  else {
1697  BLI_assert(0);
1698  }
1699 
1700  kill_selection(obedit, 1);
1701  text_update_edited(C, obedit, FO_EDIT);
1702  }
1703  }
1704  else {
1705  return OPERATOR_PASS_THROUGH;
1706  }
1707 
1708  if (inserted_text[0]) {
1709  /* store as utf8 in RNA string */
1710  char inserted_utf8[8] = {0};
1711 
1712  BLI_str_utf32_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
1713  RNA_string_set(op->ptr, "text", inserted_utf8);
1714  }
1715 
1716  return OPERATOR_FINISHED;
1717 }
1718 
1720 {
1721  /* identifiers */
1722  ot->name = "Insert Text";
1723  ot->description = "Insert text at cursor position";
1724  ot->idname = "FONT_OT_text_insert";
1725 
1726  /* api callbacks */
1730 
1731  /* flags */
1732  ot->flag = OPTYPE_UNDO;
1733 
1734  /* properties */
1735  RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
1737  ot->srna,
1738  "accent",
1739  0,
1740  "Accent Mode",
1741  "Next typed character will strike through previous, for special character input");
1742 }
1743 
1746 /* -------------------------------------------------------------------- */
1751 {
1752  Object *obedit = CTX_data_active_object(C);
1753  Curve *cu = obedit->data;
1754  int i;
1755 
1756  if (cu->totbox < 256) {
1757  for (i = cu->totbox; i > cu->actbox; i--) {
1758  cu->tb[i] = cu->tb[i - 1];
1759  }
1760  cu->tb[cu->actbox] = cu->tb[cu->actbox - 1];
1761  cu->actbox++;
1762  cu->totbox++;
1763  }
1764 
1765  DEG_id_tag_update(obedit->data, 0);
1767  return OPERATOR_FINISHED;
1768 }
1769 
1771 {
1772  /* identifiers */
1773  ot->name = "Add Text Box";
1774  ot->description = "Add a new text box";
1775  ot->idname = "FONT_OT_textbox_add";
1776 
1777  /* api callbacks */
1780 
1781  /* flags */
1783 }
1784 
1787 /* -------------------------------------------------------------------- */
1792 {
1793  Object *obedit = CTX_data_active_object(C);
1794  Curve *cu = obedit->data;
1795  int i;
1796  int index = RNA_int_get(op->ptr, "index");
1797 
1798  if (cu->totbox > 1) {
1799  for (i = index; i < cu->totbox; i++) {
1800  cu->tb[i] = cu->tb[i + 1];
1801  }
1802  cu->totbox--;
1803  if (cu->actbox >= index) {
1804  cu->actbox--;
1805  }
1806  }
1807 
1808  DEG_id_tag_update(obedit->data, 0);
1810 
1811  return OPERATOR_FINISHED;
1812 }
1813 
1815 {
1816  /* identifiers */
1817  ot->name = "Remove Text Box";
1818  ot->description = "Remove the text box";
1819  ot->idname = "FONT_OT_textbox_remove";
1820 
1821  /* api callbacks */
1824 
1825  /* flags */
1827 
1828  RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The current text box", 0, INT_MAX);
1829 }
1830 
1833 /* -------------------------------------------------------------------- */
1838 {
1839  Curve *cu = obedit->data;
1840  EditFont *ef = cu->editfont;
1841  int len_char32;
1842 
1843  if (ef == NULL) {
1844  ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
1845 
1846  ef->textbuf = MEM_callocN((MAXTEXT + 4) * sizeof(*ef->textbuf), "texteditbuf");
1847  ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
1848  }
1849 
1850  /* Convert the original text to chat32_t. */
1851  len_char32 = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4);
1852  BLI_assert(len_char32 == cu->len_char32);
1853  ef->len = len_char32;
1854  BLI_assert(ef->len >= 0);
1855 
1856  memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo));
1857 
1858  ef->pos = cu->pos;
1859  if (ef->pos > ef->len) {
1860  ef->pos = ef->len;
1861  }
1862 
1863  cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
1864 
1865  /* Other vars */
1866  ef->selstart = cu->selstart;
1867  ef->selend = cu->selend;
1868 
1869  /* text may have been modified by Python */
1870  BKE_vfont_select_clamp(obedit);
1871 }
1872 
1874 {
1875  Curve *cu = obedit->data;
1876  EditFont *ef = cu->editfont;
1877 
1878  /* Free the old curve string */
1879  MEM_freeN(cu->str);
1880 
1881  /* Calculate the actual string length in UTF-8 variable characters */
1882  cu->len_char32 = ef->len;
1884 
1885  /* Alloc memory for UTF-8 variable char length string */
1886  cu->str = MEM_mallocN(cu->len + sizeof(char32_t), "str");
1887 
1888  /* Copy the wchar to UTF-8 */
1889  BLI_str_utf32_as_utf8(cu->str, ef->textbuf, cu->len + 1);
1890 
1891  if (cu->strinfo) {
1892  MEM_freeN(cu->strinfo);
1893  }
1894  cu->strinfo = MEM_callocN((cu->len_char32 + 4) * sizeof(CharInfo), "texteditinfo");
1895  memcpy(cu->strinfo, ef->textbufinfo, cu->len_char32 * sizeof(CharInfo));
1896 
1897  /* Other vars */
1898  cu->pos = ef->pos;
1899  cu->selstart = ef->selstart;
1900  cu->selend = ef->selend;
1901 }
1902 
1904 {
1905  BKE_curve_editfont_free((Curve *)obedit->data);
1906 }
1907 
1910 /* -------------------------------------------------------------------- */
1914 static const EnumPropertyItem case_items[] = {
1915  {CASE_LOWER, "LOWER", 0, "Lower", ""},
1916  {CASE_UPPER, "UPPER", 0, "Upper", ""},
1917  {0, NULL, 0, NULL, NULL},
1918 };
1919 
1920 static int set_case(bContext *C, int ccase)
1921 {
1922  Object *obedit = CTX_data_edit_object(C);
1923  Curve *cu = obedit->data;
1924  EditFont *ef = cu->editfont;
1925  char32_t *str;
1926  int len;
1927  int selstart, selend;
1928 
1929  if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
1930  len = (selend - selstart) + 1;
1931  str = &ef->textbuf[selstart];
1932  while (len) {
1933  if (*str >= 'a' && *str <= 'z') {
1934  *str -= 32;
1935  }
1936  len--;
1937  str++;
1938  }
1939 
1940  if (ccase == CASE_LOWER) {
1941  len = (selend - selstart) + 1;
1942  str = &ef->textbuf[selstart];
1943  while (len) {
1944  if (*str >= 'A' && *str <= 'Z') {
1945  *str += 32;
1946  }
1947  len--;
1948  str++;
1949  }
1950  }
1951 
1952  text_update_edited(C, obedit, FO_EDIT);
1953  }
1954 
1955  return OPERATOR_FINISHED;
1956 }
1957 
1959 {
1960  return set_case(C, RNA_enum_get(op->ptr, "case"));
1961 }
1962 
1964 {
1965  /* identifiers */
1966  ot->name = "Set Case";
1967  ot->description = "Set font case";
1968  ot->idname = "FONT_OT_case_set";
1969 
1970  /* api callbacks */
1971  ot->exec = set_case_exec;
1973 
1974  /* flags */
1976 
1977  /* properties */
1978  RNA_def_enum(ot->srna, "case", case_items, CASE_LOWER, "Case", "Lower or upper case");
1979 }
1980 
1983 /* -------------------------------------------------------------------- */
1988 {
1989  Object *obedit = CTX_data_edit_object(C);
1990  Curve *cu = obedit->data;
1991  EditFont *ef = cu->editfont;
1992  char32_t *str;
1993  int ccase = CASE_UPPER;
1994 
1995  str = ef->textbuf;
1996  while (*str) {
1997  if (*str >= 'a' && *str <= 'z') {
1998  ccase = CASE_LOWER;
1999  break;
2000  }
2001 
2002  str++;
2003  }
2004 
2005  return set_case(C, ccase);
2006 }
2007 
2009 {
2010  /* identifiers */
2011  ot->name = "Toggle Case";
2012  ot->description = "Toggle font case";
2013  ot->idname = "FONT_OT_case_toggle";
2014 
2015  /* api callbacks */
2018 
2019  /* flags */
2021 }
2022 
2023 /* **************** Open Font ************** */
2024 
2026 {
2027  PropertyPointerRNA *pprop;
2028 
2029  op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
2031 }
2032 
2034 {
2035  MEM_freeN(op->customdata);
2036  op->customdata = NULL;
2037 }
2038 
2040 {
2041  struct Main *bmain = CTX_data_main(C);
2042  VFont *font;
2043  PropertyPointerRNA *pprop;
2044  PointerRNA idptr;
2045  char filepath[FILE_MAX];
2046  RNA_string_get(op->ptr, "filepath", filepath);
2047 
2048  font = BKE_vfont_load(bmain, filepath);
2049 
2050  if (!font) {
2051  if (op->customdata) {
2052  MEM_freeN(op->customdata);
2053  }
2054  return OPERATOR_CANCELLED;
2055  }
2056 
2057  if (!op->customdata) {
2058  font_ui_template_init(C, op);
2059  }
2060 
2061  /* hook into UI */
2062  pprop = op->customdata;
2063 
2064  if (pprop->prop) {
2065  /* when creating new ID blocks, use is already 1, but RNA
2066  * pointer use also increases user, so this compensates it */
2067  id_us_min(&font->id);
2068 
2069  RNA_id_pointer_create(&font->id, &idptr);
2070  RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
2071  RNA_property_update(C, &pprop->ptr, pprop->prop);
2072  }
2073 
2074  MEM_freeN(op->customdata);
2075 
2076  return OPERATOR_FINISHED;
2077 }
2078 
2079 static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2080 {
2081  VFont *vfont = NULL;
2082  const char *filepath;
2083 
2084  PointerRNA idptr;
2085  PropertyPointerRNA *pprop;
2086 
2087  font_ui_template_init(C, op);
2088 
2089  /* hook into UI */
2090  pprop = op->customdata;
2091 
2092  if (pprop->prop) {
2093  idptr = RNA_property_pointer_get((PointerRNA *)pprop, pprop->prop);
2094  vfont = (VFont *)idptr.owner_id;
2095  }
2096 
2097  filepath = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->filepath : U.fontdir;
2098 
2099  if (RNA_struct_property_is_set(op->ptr, "filepath")) {
2100  return font_open_exec(C, op);
2101  }
2102 
2103  RNA_string_set(op->ptr, "filepath", filepath);
2105 
2106  return OPERATOR_RUNNING_MODAL;
2107 }
2108 
2110 {
2111  /* identifiers */
2112  ot->name = "Open Font";
2113  ot->idname = "FONT_OT_open";
2114  ot->description = "Load a new font from a file";
2115 
2116  /* api callbacks */
2117  ot->exec = font_open_exec;
2118  ot->invoke = open_invoke;
2120 
2121  /* flags */
2123 
2124  /* properties */
2127  FILE_SPECIAL,
2128  FILE_OPENFILE,
2131  FILE_SORT_ALPHA);
2132 }
2133 
2136 /* -------------------------------------------------------------------- */
2141 {
2142  VFont *builtin_font;
2143 
2144  PointerRNA idptr;
2145  PropertyPointerRNA pprop;
2146 
2148 
2149  if (pprop.prop == NULL) {
2150  BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink");
2151  return OPERATOR_CANCELLED;
2152  }
2153 
2154  builtin_font = BKE_vfont_builtin_get();
2155 
2156  RNA_id_pointer_create(&builtin_font->id, &idptr);
2157  RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, NULL);
2158  RNA_property_update(C, &pprop.ptr, pprop.prop);
2159 
2160  return OPERATOR_FINISHED;
2161 }
2162 
2164 {
2165  /* identifiers */
2166  ot->name = "Unlink";
2167  ot->idname = "FONT_OT_unlink";
2168  ot->description = "Unlink active font data-block";
2169 
2170  /* api callbacks */
2172 }
2173 
2175  bContext *C,
2176  const int mval[2],
2177  /* NOTE: `params->deselect_all` is ignored as only one text-box is active at once. */
2178  const struct SelectPick_Params *params)
2179 {
2181  Object *obedit = CTX_data_edit_object(C);
2182  Curve *cu = obedit->data;
2183  ViewContext vc;
2184  /* bias against the active, in pixels, allows cycling */
2185  const float active_bias_px = 4.0f;
2186  const float mval_fl[2] = {UNPACK2(mval)};
2187  const int i_actbox = max_ii(0, cu->actbox - 1);
2188  int i_iter, actbox_select = -1;
2189  const float dist = ED_view3d_select_dist_px();
2190  float dist_sq_best = dist * dist;
2191 
2193 
2195 
2196  /* currently only select active */
2197  (void)params;
2198 
2199  for (i_iter = 0; i_iter < cu->totbox; i_iter++) {
2200  int i = (i_iter + i_actbox) % cu->totbox;
2201  float dist_sq_min;
2202  int j, j_prev;
2203 
2204  float obedit_co[4][3];
2205  float screen_co[4][2];
2206  rctf rect;
2207  int project_ok = 0;
2208 
2209  BKE_curve_rect_from_textbox(cu, &cu->tb[i], &rect);
2210 
2211  copy_v3_fl3(obedit_co[0], rect.xmin, rect.ymin, 0.0f);
2212  copy_v3_fl3(obedit_co[1], rect.xmin, rect.ymax, 0.0f);
2213  copy_v3_fl3(obedit_co[2], rect.xmax, rect.ymax, 0.0f);
2214  copy_v3_fl3(obedit_co[3], rect.xmax, rect.ymin, 0.0f);
2215 
2216  for (j = 0; j < 4; j++) {
2218  vc.region, obedit_co[j], screen_co[j], V3D_PROJ_TEST_CLIP_BB) == V3D_PROJ_RET_OK) {
2219  project_ok |= (1 << j);
2220  }
2221  }
2222 
2223  dist_sq_min = dist_sq_best;
2224  for (j = 0, j_prev = 3; j < 4; j_prev = j++) {
2225  if ((project_ok & (1 << j)) && (project_ok & (1 << j_prev))) {
2226  const float dist_test_sq = dist_squared_to_line_segment_v2(
2227  mval_fl, screen_co[j_prev], screen_co[j]);
2228  if (dist_sq_min > dist_test_sq) {
2229  dist_sq_min = dist_test_sq;
2230  }
2231  }
2232  }
2233 
2234  /* Bias in pixels to cycle selection. */
2235  if (i_iter == 0) {
2236  dist_sq_min += active_bias_px;
2237  }
2238 
2239  if (dist_sq_min < dist_sq_best) {
2240  dist_sq_best = dist_sq_min;
2241  actbox_select = i + 1;
2242  }
2243  }
2244 
2245  if (actbox_select != -1) {
2246  if (cu->actbox != actbox_select) {
2247  cu->actbox = actbox_select;
2249  /* TODO: support #ID_RECALC_SELECT. */
2251  }
2252  return true;
2253  }
2254  return false;
2255 }
2256 
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1370
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *tb, struct rctf *r_rect)
Definition: curve.cc:5454
void BKE_curve_editfont_free(struct Curve *cu)
Definition: curve.cc:336
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
General operations, lookup, etc. for blender objects.
void BKE_object_where_is_calc(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
Definition: object.cc:3495
struct Object * BKE_object_add(struct Main *bmain, struct ViewLayer *view_layer, int type, const char *name) ATTR_NONNULL(1
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void BKE_vfont_select_clamp(struct Object *ob)
Definition: vfont.c:658
bool BKE_vfont_to_curve(struct Object *ob, int mode)
Definition: vfont.c:1744
void BKE_vfont_clipboard_set(const char32_t *text_buf, const struct CharInfo *info_buf, size_t len)
int BKE_vfont_select_get(struct Object *ob, int *r_start, int *r_end)
Definition: vfont.c:618
struct VFont * BKE_vfont_load(struct Main *bmain, const char *filepath)
Definition: vfont.c:316
struct VFont * BKE_vfont_builtin_get(void)
Definition: vfont.c:413
bool BKE_vfont_is_builtin(const struct VFont *vfont)
Definition: vfont.c:223
void BKE_vfont_clipboard_free(void)
Definition: vfont.c:1762
void BKE_vfont_clipboard_get(char32_t **r_text_buf, struct CharInfo **r_info_buf, size_t *r_len_utf8, size_t *r_len_utf32)
Definition: vfont.c:1800
#define BLI_assert(a)
Definition: BLI_assert.h:46
void * BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
Definition: storage.c:466
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
Definition: math_geom.c:283
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void add_v3_v3(float r[3], const float a[3])
#define FILE_MAX
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:134
void BLI_str_cursor_step_utf32(const char32_t *str, size_t maxlen, int *pos, eStrCursorJumpDirection direction, eStrCursorJumpType jump, bool use_init_step)
@ STRCUR_DIR_NEXT
@ STRCUR_DIR_PREV
@ STRCUR_JUMP_DELIM
size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w, const char *__restrict src_c, size_t maxncpy) ATTR_NONNULL(1
size_t size_t BLI_str_utf32_as_utf8(char *__restrict dst, const char32_t *__restrict src, size_t maxncpy) ATTR_NONNULL(1
unsigned int BLI_str_utf8_as_unicode(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: string_utf8.c:478
size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
Definition: string_utf8.c:317
size_t size_t size_t BLI_str_utf32_as_utf8_len(const char32_t *src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: string_utf8.c:654
size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONNULL(1
#define UNPACK2(a)
#define UNUSED(x)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_SELECT
Definition: DNA_ID.h:818
@ CU_CHINFO_WRAP
@ CU_CHINFO_UNDERLINE
@ CU_CHINFO_BOLD
@ CU_CHINFO_ITALIC
@ CU_CHINFO_SMALLCAPS
Object is a sort of wrapper for general info.
@ OB_FONT
@ FILE_SORT_DEFAULT
@ FILE_SORT_ALPHA
@ FILE_SPECIAL
@ FILE_TYPE_TEXT
@ FILE_TYPE_FOLDER
@ FILE_TYPE_FTFONT
@ FILE_IMGDISPLAY
@ FILE_DEFAULTDISPLAY
#define FO_CURS
#define FO_CURS_IS_MOTION(mode)
#define FO_CURSDOWN
#define FO_CURSUP
#define FO_PAGEUP
#define FO_EDIT
#define FO_PAGEDOWN
#define FO_SELCHANGE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_object_base_init_transform_on_add(struct Object *object, const float loc[3], const float rot[3])
Definition: object_add.cc:315
void ED_outliner_select_sync_from_object_tag(struct bContext *C)
bool ED_operator_editfont(struct bContext *C)
Definition: screen_ops.c:635
bool ED_operator_object_active_editable_font(struct bContext *C)
Definition: screen_ops.c:420
@ V3D_PROJ_TEST_CLIP_BB
Definition: ED_view3d.h:235
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:217
eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
void ED_view3d_init_mats_rv3d(const struct Object *ob, struct RegionView3D *rv3d)
Definition: space_view3d.c:166
float ED_view3d_select_dist_px(void)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define C
Definition: RandGen.cpp:25
void UI_context_active_but_prop_get_templateID(struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop)
@ WM_FILESEL_RELPATH
Definition: WM_api.h:752
@ WM_FILESEL_FILEPATH
Definition: WM_api.h:755
@ FILE_OPENFILE
Definition: WM_api.h:764
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define NC_GEOM
Definition: WM_types.h:343
#define ND_DATA
Definition: WM_types.h:456
#define NA_ADDED
Definition: WM_types.h:525
@ KM_CTRL
Definition: WM_types.h:239
@ KM_ALT
Definition: WM_types.h:240
@ KM_SHIFT
Definition: WM_types.h:238
#define NC_OBJECT
Definition: WM_types.h:329
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: avxb.h:154
#define NEXT_CHAR(fmt)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
@ NEXT_LINE
Definition: curve_intern.h:38
@ LINE_BEGIN
Definition: curve_intern.h:31
@ PREV_WORD
Definition: curve_intern.h:35
@ PREV_LINE
Definition: curve_intern.h:37
@ PREV_CHAR
Definition: curve_intern.h:33
@ LINE_END
Definition: curve_intern.h:32
@ PREV_PAGE
Definition: curve_intern.h:39
@ NEXT_PAGE
Definition: curve_intern.h:40
@ NEXT_WORD
Definition: curve_intern.h:36
@ CASE_LOWER
Definition: curve_intern.h:29
@ CASE_UPPER
Definition: curve_intern.h:29
@ DEL_SELECTION
Definition: curve_intern.h:25
@ DEL_PREV_WORD
Definition: curve_intern.h:24
@ DEL_PREV_SEL
Definition: curve_intern.h:27
@ DEL_PREV_CHAR
Definition: curve_intern.h:22
@ DEL_NEXT_WORD
Definition: curve_intern.h:23
@ DEL_NEXT_CHAR
Definition: curve_intern.h:21
@ DEL_NEXT_SEL
Definition: curve_intern.h:26
Scene scene
const Depsgraph * depsgraph
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
static int set_case(bContext *C, int ccase)
Definition: editfont.c:1920
void FONT_OT_textbox_add(wmOperatorType *ot)
Definition: editfont.c:1770
void FONT_OT_style_toggle(wmOperatorType *ot)
Definition: editfont.c:826
void ED_text_to_object(bContext *C, const Text *text, const bool split_lines)
Definition: editfont.c:688
static void text_update_edited(bContext *C, Object *obedit, int mode)
Definition: editfont.c:390
void FONT_OT_text_copy(wmOperatorType *ot)
Definition: editfont.c:925
static bool font_paste_wchar(Object *obedit, const char32_t *str, const size_t str_len, struct CharInfo *str_info)
Definition: editfont.c:460
void FONT_OT_line_break(wmOperatorType *ot)
Definition: editfont.c:1431
static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: editfont.c:2079
static void font_open_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: editfont.c:2033
static void copy_selection(Object *obedit)
Definition: editfont.c:890
void FONT_OT_unlink(wmOperatorType *ot)
Definition: editfont.c:2163
static int paste_from_file_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: editfont.c:569
static int kill_selection(Object *obedit, int ins)
Definition: editfont.c:425
void ED_curve_editfont_make(Object *obedit)
Definition: editfont.c:1837
void FONT_OT_select_all(wmOperatorType *ot)
Definition: editfont.c:869
static int font_select_all_exec(bContext *C, wmOperator *UNUSED(op))
Definition: editfont.c:851
static int change_spacing_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1290
void FONT_OT_move(wmOperatorType *ot)
Definition: editfont.c:1230
static int change_character_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1358
static int toggle_style_exec(bContext *C, wmOperator *op)
Definition: editfont.c:808
static int paste_from_file_exec(bContext *C, wmOperator *op)
Definition: editfont.c:557
static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: editfont.c:1636
#define MAXTEXT
Definition: editfont.c:54
static int paste_text_exec(bContext *C, wmOperator *op)
Definition: editfont.c:997
void FONT_OT_text_cut(wmOperatorType *ot)
Definition: editfont.c:960
static int set_style_exec(bContext *C, wmOperator *op)
Definition: editfont.c:774
static int move_select_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1254
void FONT_OT_change_spacing(wmOperatorType *ot)
Definition: editfont.c:1326
static int toggle_case_exec(bContext *C, wmOperator *UNUSED(op))
Definition: editfont.c:1987
static void txt_add_object(bContext *C, const TextLine *firstline, int totline, const float offset[3])
Definition: editfont.c:611
void ED_curve_editfont_load(Object *obedit)
Definition: editfont.c:1873
void FONT_OT_change_character(wmOperatorType *ot)
Definition: editfont.c:1384
static const EnumPropertyItem style_items[]
Definition: editfont.c:740
static int paste_from_file(bContext *C, ReportList *reports, const char *filepath)
Definition: editfont.c:529
void FONT_OT_delete(wmOperatorType *ot)
Definition: editfont.c:1577
void FONT_OT_textbox_remove(wmOperatorType *ot)
Definition: editfont.c:1814
static int copy_text_exec(bContext *C, wmOperator *UNUSED(op))
Definition: editfont.c:916
static bool paste_selection(Object *obedit, ReportList *reports)
Definition: editfont.c:981
static const EnumPropertyItem delete_type_items[]
Definition: editfont.c:1452
void FONT_OT_open(wmOperatorType *ot)
Definition: editfont.c:2109
void FONT_OT_text_paste_from_file(wmOperatorType *ot)
Definition: editfont.c:580
static char32_t findaccent(char32_t char1, const char code)
Definition: editfont.c:62
void FONT_OT_move_select(wmOperatorType *ot)
Definition: editfont.c:1261
static const EnumPropertyItem case_items[]
Definition: editfont.c:1914
static int insert_text_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1606
static int font_open_exec(bContext *C, wmOperator *op)
Definition: editfont.c:2039
static int font_unlink_exec(bContext *C, wmOperator *op)
Definition: editfont.c:2140
static int textbox_remove_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1791
static int move_cursor(bContext *C, int type, const bool select)
Definition: editfont.c:1098
static int delete_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1463
static int set_style(bContext *C, const int style, const bool clear)
Definition: editfont.c:748
void FONT_OT_case_set(wmOperatorType *ot)
Definition: editfont.c:1963
void FONT_OT_case_toggle(wmOperatorType *ot)
Definition: editfont.c:2008
static int set_case_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1958
void ED_curve_editfont_free(Object *obedit)
Definition: editfont.c:1903
bool ED_curve_editfont_select_pick(bContext *C, const int mval[2], const struct SelectPick_Params *params)
Definition: editfont.c:2174
static void font_ui_template_init(bContext *C, wmOperator *op)
Definition: editfont.c:2025
void FONT_OT_text_paste(wmOperatorType *ot)
Definition: editfont.c:1063
static int insert_into_textbuf(Object *obedit, uintptr_t c)
Definition: editfont.c:362
static int line_break_exec(bContext *C, wmOperator *UNUSED(op))
Definition: editfont.c:1416
void FONT_OT_text_insert(wmOperatorType *ot)
Definition: editfont.c:1719
static int textbox_add_exec(bContext *C, wmOperator *UNUSED(op))
Definition: editfont.c:1750
static int move_exec(bContext *C, wmOperator *op)
Definition: editfont.c:1223
void FONT_OT_style_set(wmOperatorType *ot)
Definition: editfont.c:782
static int cut_text_exec(bContext *C, wmOperator *UNUSED(op))
Definition: editfont.c:943
static const EnumPropertyItem move_type_items[]
Definition: editfont.c:1084
static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
Definition: editfont.c:505
#define rot(x, k)
#define str(s)
uint pos
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static void clear(Message *msg)
Definition: msgfmt.c:278
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3532
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3493
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2138
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:5129
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:5301
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3687
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
_W64 unsigned int uintptr_t
Definition: stdint.h:119
struct Object * object
struct VFont * vfont
int len_char32
struct CharInfo curinfo
struct TextBox * tb
int selstart
struct EditFont * editfont
struct CharInfo * strinfo
char * str
int selend
Definition: BKE_vfont.h:43
int pos
Definition: BKE_vfont.h:42
int len
Definition: BKE_vfont.h:42
char32_t * textbuf
Definition: BKE_vfont.h:32
int selstart
Definition: BKE_vfont.h:43
struct CharInfo * textbufinfo
Definition: BKE_vfont.h:33
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
char filepath[1024]
Definition: BKE_main.h:124
float loc[3]
void * data
struct ID * owner_id
Definition: RNA_types.h:36
struct PropertyRNA * prop
Definition: RNA_types.h:43
PointerRNA ptr
Definition: RNA_types.h:42
float viewinv[4][4]
char * line
struct TextLine * next
ListBase lines
char filepath[1024]
struct ARegion * region
Definition: ED_view3d.h:69
struct Object * obedit
Definition: ED_view3d.h:68
struct RegionView3D * rv3d
Definition: ED_view3d.h:72
struct Base * basact
char utf8_buf[6]
Definition: WM_types.h:690
short type
Definition: WM_types.h:678
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
struct PointerRNA * ptr
size_t len_utf8
Definition: vfont.c:1759
void WM_event_add_fileselect(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ EVT_TABKEY
@ EVT_BACKSPACEKEY
wmOperatorType * ot
Definition: wm_files.c:3479
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
void WM_clipboard_text_set(const char *buf, bool selection)
Definition: wm_window.c:1780
char * WM_clipboard_text_get(bool selection, int *r_len)
Definition: wm_window.c:1770