1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2017 - Daniel De Matteis
4  *  Copyright (C) 2016-2019 - Brad Parker
5  *
6  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
7  *  of the GNU General Public License as published by the Free Software Found-
8  *  ation, either version 3 of the License, or (at your option) any later version.
9  *
10  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  *  PURPOSE.  See the GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along with RetroArch.
15  *  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <stdlib.h>
19 #include <string/stdstring.h>
20 #include <caca.h>
21 
22 #ifdef HAVE_CONFIG_H
23 #include "../../config.h"
24 #endif
25 
26 #include "../common/caca_common.h"
27 
28 #include "../font_driver.h"
29 #include "../../configuration.h"
30 #include "../../verbosity.h"
31 
32 typedef struct
33 {
34    const font_renderer_driver_t *caca_font_driver;
35    void *caca_font_data;
36    caca_t *caca;
37 } caca_raster_t;
38 
caca_init_font(void * data,const char * font_path,float font_size,bool is_threaded)39 static void *caca_init_font(void *data,
40       const char *font_path, float font_size,
41       bool is_threaded)
42 {
43    caca_raster_t *font  = (caca_raster_t*)calloc(1, sizeof(*font));
44 
45    if (!font)
46       return NULL;
47 
48    font->caca = (caca_t*)data;
49 
50    if (!font_renderer_create_default(
51             &font->caca_font_driver,
52             &font->caca_font_data, font_path, font_size))
53    {
54       RARCH_WARN("Couldn't initialize font renderer.\n");
55       return NULL;
56    }
57 
58    return font;
59 }
60 
caca_render_free_font(void * data,bool is_threaded)61 static void caca_render_free_font(void *data, bool is_threaded)
62 {
63    (void)data;
64    (void)is_threaded;
65 }
66 
caca_get_message_width(void * data,const char * msg,unsigned msg_len,float scale)67 static int caca_get_message_width(void *data, const char *msg,
68       unsigned msg_len, float scale)
69 {
70    return 0;
71 }
72 
caca_font_get_glyph(void * data,uint32_t code)73 static const struct font_glyph *caca_font_get_glyph(
74       void *data, uint32_t code)
75 {
76    return NULL;
77 }
78 
caca_render_msg(void * userdata,void * data,const char * msg,const struct font_params * params)79 static void caca_render_msg(
80       void *userdata,
81       void *data, const char *msg,
82       const struct font_params *params)
83 {
84    float x, y, scale;
85    unsigned width, height;
86    unsigned newX, newY;
87    unsigned align;
88    caca_raster_t              *font = (caca_raster_t*)data;
89    settings_t *settings             = config_get_ptr();
90    float video_msg_pos_x            = settings->floats.video_msg_pos_x;
91    float video_msg_pos_y            = settings->floats.video_msg_pos_y;
92 
93    if (!font || string_is_empty(msg))
94       return;
95 
96    if (params)
97    {
98       x     = params->x;
99       y     = params->y;
100       scale = params->scale;
101       align = params->text_align;
102    }
103    else
104    {
105       x     = video_msg_pos_x;
106       y     = video_msg_pos_y;
107       scale = 1.0f;
108       align = TEXT_ALIGN_LEFT;
109    }
110 
111    if (!font->caca || !font->caca->cv || !font->caca->display ||
112        !font->caca->cv || !font->caca->display)
113       return;
114 
115    width    = caca_get_canvas_width(font->caca->cv);
116    height   = caca_get_canvas_height(font->caca->cv);
117    newY     = height - (y * height * scale);
118 
119    switch (align)
120    {
121       case TEXT_ALIGN_RIGHT:
122          newX = (x * width * scale) - strlen(msg);
123          break;
124       case TEXT_ALIGN_CENTER:
125          newX = (x * width * scale) - (strlen(msg) / 2);
126          break;
127       case TEXT_ALIGN_LEFT:
128       default:
129          newX = x * width * scale;
130          break;
131    }
132 
133    caca_put_str(font->caca->cv, newX, newY, msg);
134 
135    caca_refresh_display(font->caca->display);
136 }
137 
138 font_renderer_t caca_font = {
139    caca_init_font,
140    caca_render_free_font,
141    caca_render_msg,
142    "caca font",
143    caca_font_get_glyph,       /* get_glyph */
144    NULL,                      /* bind_block */
145    NULL,                      /* flush */
146    caca_get_message_width,    /* get_message_width */
147    NULL                       /* get_line_metrics */
148 };
149