npv: move to freetype SDF rendering
[nyanmp.git] / npv / video / osd / public / code.frag.c
blob123905d563e9a0efe3b7d1739e2c6c4a87e6ccd9
1 STATIC void init_once(u8 **faces_files)
3 FT_Error ft_r;
4 /* adobe or legacy freetype */
5 FT_UInt cff;
6 FT_UInt type1;
7 FT_UInt t1cid;
8 /* the different versions of freetype truetype hinters */
9 FT_UInt tt_interpreters;
10 u8 id; /* face cache_l id, idx in the arrays */
12 memset(&cache_l, 0, sizeof(cache_l));
13 ft_r = FT_Init_FreeType(&library_l);
14 if (ft_r != FT_Err_Ok)
15 fatal("freetype:unable to get a freetype2 library_l handle:%d\n", ft_r);
16 ft_r = FTC_Manager_New(library_l, 0, 0, 0, face_requester, 0,
17 &cache_l.manager);
18 if (ft_r != 0)
19 fatal("freetype:unable to new a cache_l manager\n");
20 ft_r = FTC_ImageCache_New(cache_l.manager, &cache_l.img_cache);
21 if (ft_r != 0)
22 fatal("freetype:unable to new a image cache_l\n");
23 /* ccf, type1 and t1cid hinting engines */
24 ft_r = FT_Property_Get(library_l, "cff", "hinting-engine", &cff);
25 if (ft_r != FT_Err_Ok)
26 warning("freetype:no cff module or no hinting engine property\n");
27 else
28 pout("freetype:ccf:using the %s hinting engine\n", hinting_engine_str(cff));
29 ft_r = FT_Property_Get(library_l, "type1", "hinting-engine", &type1);
30 if (ft_r != FT_Err_Ok)
31 warning("freetype:no type1 module or no hinting engine property\n");
32 else
33 pout("freetype:type1:using the %s hinting engine\n", hinting_engine_str(type1));
34 ft_r = FT_Property_Get(library_l, "t1cid", "hinting-engine", &t1cid);
35 if (ft_r != FT_Err_Ok)
36 warning("freetype:no t1cid module or no hinting engine property\n");
37 else
38 pout("freetype:t1cid:using the %s hinting engine\n", hinting_engine_str(t1cid));
39 /* truetype various hinting engines */
40 ft_r = FT_Property_Get(library_l, "truetype", "interpreter-version",
41 &tt_interpreters);
42 if (ft_r != FT_Err_Ok)
43 warning("freetype:no truetype module or no truetype hinting interpreter version\n");
44 else {
45 pout("freetype:truetype:hinting interpreters 0x%x\n", tt_interpreters);
46 out_tt_interpreters(tt_interpreters);
48 /* we leave all defaults for the various hinting engines */
49 #if 0 // TODO: REMOVE SINCE WE ARE SWITCHING TO MONOCHROME
51 * the lcd filtering stuff (_rendering_ and _not hinting_) must be
52 * explicitely enabled, if available
54 ft_r = FT_Library_SetLcdFilter(library_l, FT_LCD_FILTER_DEFAULT);
55 if (ft_r != FT_Err_Ok)
56 warning("freetype:no lcd filtering in this freetype library_l:%d\n", ft_r);
57 else
58 pout("freetype:default lcd filtering enabled\n");
59 #endif
60 /*====================================================================*/
61 /* prepare our side of the font cache */
62 cache_l.faces.files = faces_files;
63 id = 0;
64 loop { /* count the font files */
65 if (cache_l.faces.files[id] == 0)
66 break;
67 pout("font file:%s\n", cache_l.faces.files[id]);
68 ++id;
70 pout("%u font files provided\n", id);
71 cache_l.faces.n = id;
72 cache_l.faces.ft = calloc(cache_l.faces.n, sizeof(*cache_l.faces.ft));
73 if (cache_l.faces.ft == 0)
74 fatal("unable to allocate an array of %u freetype sets of faces\n", cache_l.faces.n);
75 /*--------------------------------------------------------------------*/
76 /* freetype cache wants face id pointers to be uniq in memory... */
77 cache_l.faces.ids = calloc(cache_l.faces.n, sizeof(*cache_l.faces.ids));
78 if (cache_l.faces.ids == 0)
79 fatal("unable to allocate an array of %u ids\n", cache_l.faces.n);
80 id = 0;
81 loop {
82 if (id == cache_l.faces.n)
83 break;
84 cache_l.faces.ids[id] = id; /* we did miss something */
85 ++id;
87 /*====================================================================*/
88 gs_init_once();
89 memset(&restore_l, 0, sizeof(restore_l));
90 timer_on = false;
92 STATIC void update_dimensions(void *scaler_pixs, u16 width, u16 height,
93 u32 line_bytes_n)
95 FT_Error ft_r;
96 FT_Face f;
97 FTC_ScalerRec scaler_rec;
98 u8 i;
100 cache_nodes_release();
102 * choices which may end up in the config file:
103 * XXX: ascender in most font files ~ em height
105 if (height / 12 > 80)
106 scaler_rec.height = height / 12;
107 else
108 scaler_rec.height = 80;
109 scaler_rec.width = scaler_rec.height;
110 pout("scaler:em to %ux%u pixels\n", scaler_rec.width, scaler_rec.height);
111 i = 0;
112 loop {
113 FT_Glyph g;
115 if (i == GS_N)
116 break;
117 memset(&scaler_rec, 0, sizeof(scaler_rec));
118 /* XXX: freetype cache wants ids with uniq ptrs */
119 scaler_rec.face_id =
120 &(cache_l.faces.ids[cache_l.gs[i].face_id]);
121 if (height / 12 > 80)
122 scaler_rec.height = height / 12;
123 else
124 scaler_rec.height = 80;
125 scaler_rec.width = scaler_rec.height;
126 scaler_rec.pixel = 1;
128 * using the SDF render mode in order to draw properly the
129 * contour of glyphs
131 ft_r = FTC_ImageCache_LookupScaler(cache_l.img_cache,
132 &scaler_rec, FT_LOAD_RENDER
133 | FT_LOAD_TARGET_(FT_RENDER_MODE_SDF),
134 cache_l.gs[i].idx, &g, &cache_l.gs[i].node);
135 if (ft_r != FT_Err_Ok)
136 fatal("freetype:cache_l:failed to look for glyph %u with our target size:0x%02x\n", i, ft_r);
137 if (g->format != FT_GLYPH_FORMAT_BITMAP)
138 fatal("freetype:the glyph %u was not rendered in bitmap\n", i);
139 cache_l.gs[i].bg = (FT_BitmapGlyph)g;
140 ++i;
142 timer_baseline_compute();
143 volume_pen_start_location_compute(width, height);
144 restore_l.scaler_pixs = scaler_pixs;
145 free(restore_l.pixs);
146 restore_l.pixs = calloc(4, (u32)height * line_bytes_n);
147 restore_l.width = width;
148 restore_l.height = height;
149 restore_l.line_bytes_n = line_bytes_n;
150 restore_l.dirty = false;
152 #define BLEND 0
153 STATIC void rop_blend(s64 now)
155 u8 *timer_gs;
157 if (!timer_on || restore_l.dirty)
158 return;
159 timer_gs = timer_to_gs(now,
160 npv_fmt_ctx_p->streams[npv_video_st_p.idx]->tb);
161 rop_x(BLEND, timer_gs);
162 restore_l.dirty = true;
164 #undef BLEND
165 #define RESTORE 1
166 STATIC void rop_restore(void)
168 if (!restore_l.dirty)
169 return;
170 rop_x(RESTORE, restore_l.timer_gs);
171 restore_l.dirty = false;
173 #undef RESTORE
174 STATIC void clear_dirty(void)
176 restore_l.dirty = false;
178 STATIC void npv_cmd_osd_timer_toggle(void)
180 if (timer_on) {
181 timer_on = false;
182 pout("timer off\n");
183 } else {
184 timer_on = true;
185 pout("timer on\n");