Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / draw / intern / draw_manager_text.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file \ingroup draw
20  */
21
22 #include "MEM_guardedalloc.h"
23
24 #include "BLI_listbase.h"
25 #include "BLI_math.h"
26
27
28 #include "GPU_matrix.h"
29
30 #include "ED_screen.h"
31 #include "ED_view3d.h"
32
33 #include "UI_interface.h"
34
35 #include "WM_api.h"
36 #include "BLF_api.h"
37
38 #include "draw_manager_text.h"
39
40 typedef struct ViewCachedString {
41         struct ViewCachedString *next, *prev;
42         float vec[3];
43         union {
44                 uchar ub[4];
45                 int pack;
46         } col;
47         short sco[2];
48         short xoffs, yoffs;
49         short flag;
50         int str_len;
51
52         /* str is allocated past the end */
53         char str[0];
54 } ViewCachedString;
55
56 typedef struct DRWTextStore {
57         ListBase list;
58 } DRWTextStore;
59
60 DRWTextStore *DRW_text_cache_create(void)
61 {
62         DRWTextStore *dt = MEM_callocN(sizeof(*dt), __func__);
63         return dt;
64 }
65
66 void DRW_text_cache_destroy(struct DRWTextStore *dt)
67 {
68         BLI_freelistN(&dt->list);
69         MEM_freeN(dt);
70 }
71
72 void DRW_text_cache_add(
73         DRWTextStore *dt,
74         const float co[3],
75         const char *str, const int str_len,
76         short xoffs, short yoffs, short flag,
77         const uchar col[4])
78 {
79         int alloc_len;
80         ViewCachedString *vos;
81
82         if (flag & DRW_TEXT_CACHE_STRING_PTR) {
83                 BLI_assert(str_len == strlen(str));
84                 alloc_len = sizeof(void *);
85         }
86         else {
87                 alloc_len = str_len + 1;
88         }
89
90         vos = MEM_mallocN(sizeof(ViewCachedString) + alloc_len, __func__);
91
92         BLI_addtail(&dt->list, vos);
93
94         copy_v3_v3(vos->vec, co);
95         copy_v4_v4_uchar(vos->col.ub, col);
96         vos->xoffs = xoffs;
97         vos->yoffs = yoffs;
98         vos->flag = flag;
99         vos->str_len = str_len;
100
101         /* allocate past the end */
102         if (flag & DRW_TEXT_CACHE_STRING_PTR) {
103                 memcpy(vos->str, &str, alloc_len);
104         }
105         else {
106                 memcpy(vos->str, str, alloc_len);
107         }
108 }
109
110 void DRW_text_cache_draw(DRWTextStore *dt, ARegion *ar)
111 {
112         RegionView3D *rv3d = ar->regiondata;
113         ViewCachedString *vos;
114         int tot = 0;
115
116         /* project first and test */
117         for (vos = dt->list.first; vos; vos = vos->next) {
118                 if (ED_view3d_project_short_ex(
119                         ar,
120                         (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
121                         (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0,
122                         vos->vec, vos->sco,
123                         V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
124                 {
125                         tot++;
126                 }
127                 else {
128                         vos->sco[0] = IS_CLIPPED;
129                 }
130         }
131
132         if (tot) {
133                 int col_pack_prev = 0;
134
135                 if (rv3d->rflag & RV3D_CLIPPING) {
136                         ED_view3d_clipping_disable();
137                 }
138
139                 float original_proj[4][4];
140                 GPU_matrix_projection_get(original_proj);
141                 wmOrtho2_region_pixelspace(ar);
142
143                 GPU_matrix_push();
144                 GPU_matrix_identity_set();
145
146                 const int font_id = BLF_default();
147
148                 const uiStyle *style = UI_style_get();
149
150                 BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
151
152                 for (vos = dt->list.first; vos; vos = vos->next) {
153                         if (vos->sco[0] != IS_CLIPPED) {
154                                 if (col_pack_prev != vos->col.pack) {
155                                         BLF_color4ubv(font_id, vos->col.ub);
156                                         col_pack_prev = vos->col.pack;
157                                 }
158
159                                 BLF_position(
160                                         font_id,
161                                         (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f);
162
163                                 ((vos->flag & DRW_TEXT_CACHE_ASCII) ?
164                                  BLF_draw_ascii :
165                                  BLF_draw
166                                  )(font_id,
167                                    (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str,
168                                    vos->str_len);
169                         }
170                 }
171
172                 GPU_matrix_pop();
173                 GPU_matrix_projection_set(original_proj);
174
175                 if (rv3d->rflag & RV3D_CLIPPING) {
176                         ED_view3d_clipping_enable();
177                 }
178         }
179 }