ClangFormat: apply to source, most of intern
[blender.git] / source / blender / blenfont / intern / blf_glyph.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  * The Original Code is Copyright (C) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup blf
22  *
23  * Glyph rendering, texturing and caching. Wraps Freetype and OpenGL functions.
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h>
30
31 #include <ft2build.h>
32
33 #include FT_FREETYPE_H
34 #include FT_GLYPH_H
35 #include FT_OUTLINE_H
36 #include FT_BITMAP_H
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_vec_types.h"
41 #include "DNA_userdef_types.h"
42
43 #include "BLI_listbase.h"
44 #include "BLI_rect.h"
45 #include "BLI_threads.h"
46
47 #include "BLF_api.h"
48
49 #ifndef BLF_STANDALONE
50 #  include "GPU_immediate.h"
51 #  include "GPU_extensions.h"
52 #endif
53
54 #include "blf_internal_types.h"
55 #include "blf_internal.h"
56
57 #include "BLI_strict_flags.h"
58 #include "BLI_math_vector.h"
59
60 KerningCacheBLF *blf_kerning_cache_find(FontBLF *font)
61 {
62   KerningCacheBLF *p;
63
64   p = (KerningCacheBLF *)font->kerning_caches.first;
65   while (p) {
66     if (p->mode == font->kerning_mode)
67       return p;
68     p = p->next;
69   }
70   return NULL;
71 }
72
73 /* Create a new glyph cache for the current kerning mode. */
74 KerningCacheBLF *blf_kerning_cache_new(FontBLF *font)
75 {
76   KerningCacheBLF *kc;
77
78   kc = (KerningCacheBLF *)MEM_callocN(sizeof(KerningCacheBLF), "blf_kerning_cache_new");
79   kc->next = NULL;
80   kc->prev = NULL;
81   kc->mode = font->kerning_mode;
82
83   unsigned int i, j;
84   for (i = 0; i < 0x80; i++) {
85     for (j = 0; j < 0x80; j++) {
86       GlyphBLF *g = blf_glyph_search(font->glyph_cache, i);
87       if (!g) {
88         FT_UInt glyph_index = FT_Get_Char_Index(font->face, i);
89         g = blf_glyph_add(font, glyph_index, i);
90       }
91       /* Can fail on certain fonts */
92       GlyphBLF *g_prev = blf_glyph_search(font->glyph_cache, j);
93
94       FT_Vector delta = {
95           .x = 0,
96           .y = 0,
97       };
98       if (g_prev && FT_Get_Kerning(font->face, g_prev->idx, g->idx, kc->mode, &delta) == 0) {
99         kc->table[i][j] = (int)delta.x >> 6;
100       }
101       else {
102         kc->table[i][j] = 0;
103       }
104     }
105   }
106
107   BLI_addhead(&font->kerning_caches, kc);
108   return kc;
109 }
110
111 void blf_kerning_cache_clear(FontBLF *font)
112 {
113   font->kerning_cache = NULL;
114   BLI_freelistN(&font->kerning_caches);
115 }
116
117 GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned int dpi)
118 {
119   GlyphCacheBLF *p;
120
121   p = (GlyphCacheBLF *)font->cache.first;
122   while (p) {
123     if (p->size == size && p->dpi == dpi)
124       return p;
125     p = p->next;
126   }
127   return NULL;
128 }
129
130 /* Create a new glyph cache for the current size and dpi. */
131 GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
132 {
133   GlyphCacheBLF *gc;
134
135   gc = (GlyphCacheBLF *)MEM_callocN(sizeof(GlyphCacheBLF), "blf_glyph_cache_new");
136   gc->next = NULL;
137   gc->prev = NULL;
138   gc->size = font->size;
139   gc->dpi = font->dpi;
140
141   memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
142   memset(gc->bucket, 0, sizeof(gc->bucket));
143
144   gc->textures = (GPUTexture **)MEM_callocN(sizeof(GPUTexture *) * 256, __func__);
145   gc->textures_len = 256;
146   gc->texture_current = BLF_TEXTURE_UNSET;
147   gc->offset_x = 3; /* enough padding for blur */
148   gc->offset_y = 3; /* enough padding for blur */
149   gc->pad = 6;
150
151   gc->glyphs_len_max = (int)font->face->num_glyphs;
152   gc->glyphs_len_free = (int)font->face->num_glyphs;
153   gc->ascender = ((float)font->face->size->metrics.ascender) / 64.0f;
154   gc->descender = ((float)font->face->size->metrics.descender) / 64.0f;
155
156   if (FT_IS_SCALABLE(font->face)) {
157     gc->glyph_width_max = (int)((float)(font->face->bbox.xMax - font->face->bbox.xMin) *
158                                 (((float)font->face->size->metrics.x_ppem) /
159                                  ((float)font->face->units_per_EM)));
160
161     gc->glyph_height_max = (int)((float)(font->face->bbox.yMax - font->face->bbox.yMin) *
162                                  (((float)font->face->size->metrics.y_ppem) /
163                                   ((float)font->face->units_per_EM)));
164   }
165   else {
166     gc->glyph_width_max = (int)(((float)font->face->size->metrics.max_advance) / 64.0f);
167     gc->glyph_height_max = (int)(((float)font->face->size->metrics.height) / 64.0f);
168   }
169
170   /* can happen with size 1 fonts */
171   CLAMP_MIN(gc->glyph_width_max, 1);
172   CLAMP_MIN(gc->glyph_height_max, 1);
173
174   gc->p2_width = 0;
175   gc->p2_height = 0;
176
177   BLI_addhead(&font->cache, gc);
178   return gc;
179 }
180
181 void blf_glyph_cache_clear(FontBLF *font)
182 {
183   GlyphCacheBLF *gc;
184
185   while ((gc = BLI_pophead(&font->cache))) {
186     blf_glyph_cache_free(gc);
187   }
188   font->glyph_cache = NULL;
189 }
190
191 void blf_glyph_cache_free(GlyphCacheBLF *gc)
192 {
193   GlyphBLF *g;
194   unsigned int i;
195
196   for (i = 0; i < 257; i++) {
197     while ((g = BLI_pophead(&gc->bucket[i]))) {
198       blf_glyph_free(g);
199     }
200   }
201   for (i = 0; i < gc->textures_len; i++) {
202     if (gc->textures[i]) {
203       GPU_texture_free(gc->textures[i]);
204     }
205   }
206   MEM_freeN(gc->textures);
207   MEM_freeN(gc);
208 }
209
210 static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
211 {
212   int i;
213   char error[256];
214
215   /* move the index. */
216   gc->texture_current++;
217
218   if (UNLIKELY(gc->texture_current >= gc->textures_len)) {
219     gc->textures_len *= 2;
220     gc->textures = MEM_recallocN((void *)gc->textures, sizeof(GPUTexture *) * gc->textures_len);
221   }
222
223   gc->p2_width = (int)blf_next_p2(
224       (unsigned int)((gc->glyphs_len_free * gc->glyph_width_max) + (gc->pad * 2)));
225   if (gc->p2_width > font->tex_size_max) {
226     gc->p2_width = font->tex_size_max;
227   }
228
229   i = (int)((gc->p2_width - (gc->pad * 2)) / gc->glyph_width_max);
230   gc->p2_height = (int)blf_next_p2(
231       (unsigned int)(((gc->glyphs_len_max / i) + 1) * gc->glyph_height_max + (gc->pad * 2)));
232
233   if (gc->p2_height > font->tex_size_max) {
234     gc->p2_height = font->tex_size_max;
235   }
236
237   unsigned char *pixels = MEM_callocN((size_t)gc->p2_width * (size_t)gc->p2_height,
238                                       "BLF texture init");
239   GPUTexture *tex = GPU_texture_create_nD(
240       gc->p2_width, gc->p2_height, 0, 2, pixels, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, error);
241   MEM_freeN(pixels);
242   gc->textures[gc->texture_current] = tex;
243   GPU_texture_bind(tex, 0);
244   GPU_texture_wrap_mode(tex, false);
245   GPU_texture_filters(tex, GPU_NEAREST, GPU_LINEAR);
246   GPU_texture_unbind(tex);
247 }
248
249 GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
250 {
251   GlyphBLF *p;
252   unsigned int key;
253
254   key = blf_hash(c);
255   p = gc->bucket[key].first;
256   while (p) {
257     if (p->c == c)
258       return p;
259     p = p->next;
260   }
261   return NULL;
262 }
263
264 GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
265 {
266   FT_GlyphSlot slot;
267   GlyphBLF *g;
268   FT_Error err;
269   FT_Bitmap bitmap, tempbitmap;
270   FT_BBox bbox;
271   unsigned int key;
272
273   g = blf_glyph_search(font->glyph_cache, c);
274   if (g)
275     return g;
276
277   /* glyphs are dynamically created as needed by font rendering. this means that
278    * to make font rendering thread safe we have to do locking here. note that this
279    * must be a lock for the whole library and not just per font, because the font
280    * renderer uses a shared buffer internally */
281   BLI_spin_lock(font->ft_lib_mutex);
282
283   /* search again after locking */
284   g = blf_glyph_search(font->glyph_cache, c);
285   if (g) {
286     BLI_spin_unlock(font->ft_lib_mutex);
287     return g;
288   }
289
290   if (font->flags & BLF_MONOCHROME) {
291     err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
292   }
293   else {
294     int flags = FT_LOAD_NO_BITMAP;
295
296     if (font->flags & BLF_HINTING_NONE) {
297       flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
298     }
299     else if (font->flags & BLF_HINTING_SLIGHT) {
300       flags |= FT_LOAD_TARGET_LIGHT;
301     }
302     else if (font->flags & BLF_HINTING_FULL) {
303       flags |= FT_LOAD_TARGET_NORMAL;
304     }
305     else {
306       /* Default, hinting disabled until FreeType has been upgraded
307        * to give good results on all platforms. */
308       flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING;
309     }
310
311     err = FT_Load_Glyph(font->face, (FT_UInt)index, flags);
312   }
313
314   if (err) {
315     BLI_spin_unlock(font->ft_lib_mutex);
316     return NULL;
317   }
318
319   /* get the glyph. */
320   slot = font->face->glyph;
321
322   if (font->flags & BLF_MONOCHROME) {
323     err = FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
324
325     /* Convert result from 1 bit per pixel to 8 bit per pixel */
326     /* Accum errors for later, fine if not interested beyond "ok vs any error" */
327     FT_Bitmap_New(&tempbitmap);
328     err += FT_Bitmap_Convert(font->ft_lib,
329                              &slot->bitmap,
330                              &tempbitmap,
331                              1); /* Does Blender use Pitch 1 always? It works so far */
332     err += FT_Bitmap_Copy(font->ft_lib, &tempbitmap, &slot->bitmap);
333     err += FT_Bitmap_Done(font->ft_lib, &tempbitmap);
334   }
335   else {
336     err = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
337   }
338
339   if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) {
340     BLI_spin_unlock(font->ft_lib_mutex);
341     return NULL;
342   }
343
344   g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add");
345   g->c = c;
346   g->idx = (FT_UInt)index;
347   g->offset_x = -1;
348   g->offset_y = -1;
349   bitmap = slot->bitmap;
350   g->width = (int)bitmap.width;
351   g->height = (int)bitmap.rows;
352
353   if (g->width && g->height) {
354     if (font->flags & BLF_MONOCHROME) {
355       /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
356       int i;
357       for (i = 0; i < (g->width * g->height); i++) {
358         bitmap.buffer[i] = bitmap.buffer[i] ? 255 : 0;
359       }
360     }
361
362     g->bitmap = (unsigned char *)MEM_mallocN((size_t)g->width * (size_t)g->height, "glyph bitmap");
363     memcpy((void *)g->bitmap, (void *)bitmap.buffer, (size_t)g->width * (size_t)g->height);
364   }
365
366   g->advance = ((float)slot->advance.x) / 64.0f;
367   g->advance_i = (int)g->advance;
368   g->pos_x = (float)slot->bitmap_left;
369   g->pos_y = (float)slot->bitmap_top;
370   g->pitch = slot->bitmap.pitch;
371
372   FT_Outline_Get_CBox(&(slot->outline), &bbox);
373   g->box.xmin = ((float)bbox.xMin) / 64.0f;
374   g->box.xmax = ((float)bbox.xMax) / 64.0f;
375   g->box.ymin = ((float)bbox.yMin) / 64.0f;
376   g->box.ymax = ((float)bbox.yMax) / 64.0f;
377
378   key = blf_hash(g->c);
379   BLI_addhead(&(font->glyph_cache->bucket[key]), g);
380
381   BLI_spin_unlock(font->ft_lib_mutex);
382
383   return g;
384 }
385
386 void blf_glyph_free(GlyphBLF *g)
387 {
388   /* don't need free the texture, the GlyphCache already
389    * have a list of all the texture and free it.
390    */
391   if (g->bitmap)
392     MEM_freeN(g->bitmap);
393   MEM_freeN(g);
394 }
395
396 static void blf_texture_draw(
397     const unsigned char color[4], const float uv[2][2], float x1, float y1, float x2, float y2)
398 {
399   /* Only one vertex per glyph, geometry shader expand it into a quad. */
400   /* TODO Get rid of Geom Shader because it's not optimal AT ALL for the GPU */
401   copy_v4_fl4(GPU_vertbuf_raw_step(&g_batch.pos_step),
402               x1 + g_batch.ofs[0],
403               y1 + g_batch.ofs[1],
404               x2 + g_batch.ofs[0],
405               y2 + g_batch.ofs[1]);
406   copy_v4_v4(GPU_vertbuf_raw_step(&g_batch.tex_step), (float *)uv);
407   copy_v4_v4_uchar(GPU_vertbuf_raw_step(&g_batch.col_step), color);
408   g_batch.glyph_len++;
409   /* Flush cache if it's full. */
410   if (g_batch.glyph_len == BLF_BATCH_DRAW_LEN_MAX) {
411     blf_batch_draw();
412   }
413 }
414
415 static void blf_texture5_draw(const unsigned char color_in[4],
416                               int tex_w,
417                               int tex_h,
418                               const float uv[2][2],
419                               float x1,
420                               float y1,
421                               float x2,
422                               float y2)
423 {
424   float ofs[2] = {2 / (float)tex_w, 2 / (float)tex_h};
425   float uv_flag[2][2];
426   copy_v4_v4((float *)uv_flag, (float *)uv);
427   /* flag the x and y component signs for 5x5 blurring */
428   uv_flag[0][0] = -(uv_flag[0][0] - ofs[0]);
429   uv_flag[0][1] = -(uv_flag[0][1] - ofs[1]);
430   uv_flag[1][0] = -(uv_flag[1][0] + ofs[0]);
431   uv_flag[1][1] = -(uv_flag[1][1] + ofs[1]);
432
433   blf_texture_draw(color_in, uv_flag, x1 - 2, y1 + 2, x2 + 2, y2 - 2);
434 }
435
436 static void blf_texture3_draw(const unsigned char color_in[4],
437                               int tex_w,
438                               int tex_h,
439                               const float uv[2][2],
440                               float x1,
441                               float y1,
442                               float x2,
443                               float y2)
444 {
445   float ofs[2] = {1 / (float)tex_w, 1 / (float)tex_h};
446   float uv_flag[2][2];
447   copy_v4_v4((float *)uv_flag, (float *)uv);
448   /* flag the x component sign for 3x3 blurring */
449   uv_flag[0][0] = -(uv_flag[0][0] - ofs[0]);
450   uv_flag[0][1] = (uv_flag[0][1] - ofs[1]);
451   uv_flag[1][0] = -(uv_flag[1][0] + ofs[0]);
452   uv_flag[1][1] = (uv_flag[1][1] + ofs[1]);
453
454   blf_texture_draw(color_in, uv_flag, x1 - 1, y1 + 1, x2 + 1, y2 - 1);
455 }
456
457 static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y)
458 {
459   rect->xmin = floorf(x + g->pos_x);
460   rect->xmax = rect->xmin + (float)g->width;
461   rect->ymin = floorf(y + g->pos_y);
462   rect->ymax = rect->ymin - (float)g->height;
463 }
464
465 static void blf_glyph_calc_rect_test(rctf *rect, GlyphBLF *g, float x, float y)
466 {
467   /* Intentionally check with g->advance, because this is the
468    * width used by BLF_width. This allows that the text slightly
469    * overlaps the clipping border to achieve better alignment. */
470   rect->xmin = floorf(x);
471   rect->xmax = rect->xmin + MIN2(g->advance, (float)g->width);
472   rect->ymin = floorf(y);
473   rect->ymax = rect->ymin - (float)g->height;
474 }
475
476 static void blf_glyph_calc_rect_shadow(rctf *rect, GlyphBLF *g, float x, float y, FontBLF *font)
477 {
478   blf_glyph_calc_rect(rect, g, x + (float)font->shadow_x, y + (float)font->shadow_y);
479 }
480
481 void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
482 {
483   if ((!g->width) || (!g->height))
484     return;
485
486   if (g->build_tex == 0) {
487     GlyphCacheBLF *gc = font->glyph_cache;
488
489     if (font->tex_size_max == -1)
490       font->tex_size_max = GPU_max_texture_size();
491
492     if (gc->texture_current == BLF_TEXTURE_UNSET) {
493       blf_glyph_cache_texture(font, gc);
494       gc->offset_x = gc->pad;
495       gc->offset_y = 3; /* enough padding for blur */
496     }
497
498     if (gc->offset_x > (gc->p2_width - gc->glyph_width_max)) {
499       gc->offset_x = gc->pad;
500       gc->offset_y += gc->glyph_height_max;
501
502       if (gc->offset_y > (gc->p2_height - gc->glyph_height_max)) {
503         gc->offset_y = 3; /* enough padding for blur */
504         blf_glyph_cache_texture(font, gc);
505       }
506     }
507
508     g->tex = gc->textures[gc->texture_current];
509     g->offset_x = gc->offset_x;
510     g->offset_y = gc->offset_y;
511
512     /* prevent glTexSubImage2D from failing if the character
513      * asks for pixels out of bounds, this tends only to happen
514      * with very small sizes (5px high or less) */
515     if (UNLIKELY((g->offset_x + g->width) > gc->p2_width)) {
516       g->width -= (g->offset_x + g->width) - gc->p2_width;
517       BLI_assert(g->width > 0);
518     }
519     if (UNLIKELY((g->offset_y + g->height) > gc->p2_height)) {
520       g->height -= (g->offset_y + g->height) - gc->p2_height;
521       BLI_assert(g->height > 0);
522     }
523
524     GPU_texture_update_sub(g->tex,
525                            GPU_DATA_UNSIGNED_BYTE,
526                            g->bitmap,
527                            g->offset_x,
528                            g->offset_y,
529                            0,
530                            g->width,
531                            g->height,
532                            0);
533
534     g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width);
535     g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height);
536     g->uv[1][0] = ((float)(g->offset_x + g->width)) / ((float)gc->p2_width);
537     g->uv[1][1] = ((float)(g->offset_y + g->height)) / ((float)gc->p2_height);
538
539     /* update the x offset for the next glyph. */
540     gc->offset_x += (int)BLI_rctf_size_x(&g->box) + gc->pad;
541
542     gc->glyphs_len_free--;
543     g->build_tex = 1;
544   }
545
546   if (font->flags & BLF_CLIPPING) {
547     rctf rect_test;
548     blf_glyph_calc_rect_test(&rect_test, g, x, y);
549     BLI_rctf_translate(&rect_test, font->pos[0], font->pos[1]);
550
551     if (!BLI_rctf_inside_rctf(&font->clip_rec, &rect_test)) {
552       return;
553     }
554   }
555
556   if (font->tex_bind_state != g->tex) {
557     blf_batch_draw();
558     font->tex_bind_state = g->tex;
559     GPU_texture_bind(font->tex_bind_state, 0);
560   }
561
562   g_batch.tex_bind_state = g->tex;
563
564   if (font->flags & BLF_SHADOW) {
565     rctf rect_ofs;
566     blf_glyph_calc_rect_shadow(&rect_ofs, g, x, y, font);
567
568     if (font->shadow == 0) {
569       blf_texture_draw(
570           font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
571     }
572     else if (font->shadow <= 4) {
573       blf_texture3_draw(font->shadow_color,
574                         font->glyph_cache->p2_width,
575                         font->glyph_cache->p2_height,
576                         g->uv,
577                         rect_ofs.xmin,
578                         rect_ofs.ymin,
579                         rect_ofs.xmax,
580                         rect_ofs.ymax);
581     }
582     else {
583       blf_texture5_draw(font->shadow_color,
584                         font->glyph_cache->p2_width,
585                         font->glyph_cache->p2_height,
586                         g->uv,
587                         rect_ofs.xmin,
588                         rect_ofs.ymin,
589                         rect_ofs.xmax,
590                         rect_ofs.ymax);
591     }
592   }
593
594   rctf rect;
595   blf_glyph_calc_rect(&rect, g, x, y);
596
597 #if BLF_BLUR_ENABLE
598   switch (font->blur) {
599     case 3:
600       blf_texture3_draw(font->color,
601                         font->glyph_cache->p2_width,
602                         font->glyph_cache->p2_height,
603                         g->uv,
604                         rect.xmin,
605                         rect.ymin,
606                         rect.xmax,
607                         rect.ymax);
608       break;
609     case 5:
610       blf_texture5_draw(font->color,
611                         font->glyph_cache->p2_width,
612                         font->glyph_cache->p2_height,
613                         g->uv,
614                         rect.xmin,
615                         rect.ymin,
616                         rect.xmax,
617                         rect.ymax);
618       break;
619     default:
620       blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
621   }
622 #else
623   blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
624 #endif
625 }