f631e4fee2d065538524687e80ae196b88408818
[goodguy/history.git] / cinelerra-5.1 / plugins / titler / title.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #ifndef TITLE_H
23 #define TITLE_H
24
25
26
27 // Theory:
28
29 // Stage 1:
30 // Only performed when text mask changes.
31 // Update glyph cache with every glyph used in the title.
32 // A parallel text renderer draws one character per CPU.
33 // The titler direct copies all the text currently visible onto the text mask.
34 // in integer coordinates.
35 // The text mask is in the same color space as the output but always has
36 // an alpha channel.
37
38 // Stage 2:
39 // Performed every frame.
40 // The text mask is overlayed with fractional translation and fading on the output.
41
42
43
44
45
46
47 class TitleMain;
48 class TitleEngine;
49 class TitleOutlineEngine;
50 class GlyphEngine;
51 class TitleTranslate;
52
53 #include "bchash.h"
54 #include "bcfontentry.h"
55 #include "loadbalance.h"
56 #include "mutex.h"
57 #include "pluginvclient.h"
58 #include "titlewindow.h"
59
60 #include <ft2build.h>
61 #include FT_FREETYPE_H
62 #include <sys/types.h>
63
64 // Motion strategy
65 #define TOTAL_PATHS 5
66 #define NO_MOTION     0x0
67 #define BOTTOM_TO_TOP 0x1
68 #define TOP_TO_BOTTOM 0x2
69 #define RIGHT_TO_LEFT 0x3
70 #define LEFT_TO_RIGHT 0x4
71
72 // Horizontal justification
73 #define JUSTIFY_LEFT   0x0
74 #define JUSTIFY_CENTER 0x1
75 #define JUSTIFY_RIGHT  0x2
76
77 // Vertical justification
78 #define JUSTIFY_TOP     0x0
79 #define JUSTIFY_MID     0x1
80 #define JUSTIFY_BOTTOM  0x2
81
82 class TitleConfig
83 {
84 public:
85         TitleConfig();
86         ~TitleConfig();
87
88         void to_wtext(const char *from_enc, const char *text, int tlen);
89 // Only used to clear glyphs
90         int equivalent(TitleConfig &that);
91         void copy_from(TitleConfig &that);
92         void interpolate(TitleConfig &prev,
93                 TitleConfig &next,
94                 int64_t prev_frame,
95                 int64_t next_frame,
96                 int64_t current_frame);
97         void limits();
98
99 // Font information
100         char font[BCTEXTLEN];
101         int64_t style;
102         int size;
103         int color;
104         int color_stroke;
105         int outline_color;
106         int alpha;
107         int outline_alpha;
108         int motion_strategy;     // Motion of title across frame
109         int line_pitch;
110         int loop;                // Loop motion path
111         float pixels_per_second; // Speed of motion
112         int hjustification;
113         int vjustification;
114 // Number of seconds the fade in and fade out of the title take
115         double fade_in, fade_out;
116 // Position in frame relative to top left
117         float x, y;
118 // Pixels down and right of dropshadow
119         int dropshadow;
120         int outline_size;
121 // Calculated during every frame for motion strategy
122         int64_t prev_keyframe_position;
123         int64_t next_keyframe_position;
124 // Stamp timecode
125         int timecode;
126
127 // Text to display
128         wchar_t wtext[BCTEXTLEN];
129         int wlen;
130         void convert_text();
131
132 // Encoding to convert from
133         char encoding[BCTEXTLEN];
134 // Time Code Format
135         int timecode_format;
136 // Width of the stroke
137         double stroke_width;
138 // Size of window
139         int window_w, window_h;
140 };
141
142 class TitleGlyph
143 {
144 public:
145         TitleGlyph();
146         ~TitleGlyph();
147
148         FT_ULong char_code;
149         int width, height, pitch;
150         int advance_x;
151         int left, top, right, bottom;
152         int freetype_index;
153         VFrame *data;
154         VFrame *data_stroke;
155 };
156
157
158
159
160
161
162
163
164
165 // Draw a single character into the glyph cache
166 //
167 class GlyphPackage : public LoadPackage
168 {
169 public:
170         GlyphPackage();
171         TitleGlyph *glyph;
172 };
173
174
175 class GlyphUnit : public LoadClient
176 {
177 public:
178         GlyphUnit(TitleMain *plugin, GlyphEngine *server);
179         ~GlyphUnit();
180         void process_package(LoadPackage *package);
181
182         TitleMain *plugin;
183         BC_FontEntry *current_font;       // Current font configured by freetype
184         FT_Library freetype_library;            // Freetype library
185         FT_Face freetype_face;
186 };
187
188 class GlyphEngine : public LoadServer
189 {
190 public:
191         GlyphEngine(TitleMain *plugin, int cpus);
192         void init_packages();
193         LoadClient* new_client();
194         LoadPackage* new_package();
195         TitleMain *plugin;
196 };
197
198
199
200
201
202
203
204 // Copy a single character to the text mask
205 class TitlePackage : public LoadPackage
206 {
207 public:
208         TitlePackage();
209         int x, y;
210         wchar_t char_code;
211 };
212
213
214 class TitleUnit : public LoadClient
215 {
216 public:
217         TitleUnit(TitleMain *plugin, TitleEngine *server);
218         void process_package(LoadPackage *package);
219         void draw_glyph(VFrame *output, VFrame *data, TitleGlyph *glyph, int x, int y);
220         TitleMain *plugin;
221         TitleEngine *engine;
222 };
223
224 class TitleEngine : public LoadServer
225 {
226 public:
227         TitleEngine(TitleMain *plugin, int cpus);
228         void init_packages();
229         LoadClient* new_client();
230         LoadPackage* new_package();
231         TitleMain *plugin;
232         int do_dropshadow;
233 };
234
235
236
237
238
239 // Create outline
240 class TitleOutlinePackage : public LoadPackage
241 {
242 public:
243         TitleOutlinePackage();
244         int y1, y2;
245 };
246
247
248 class TitleOutlineUnit : public LoadClient
249 {
250 public:
251         TitleOutlineUnit(TitleMain *plugin, TitleOutlineEngine *server);
252         void process_package(LoadPackage *package);
253         TitleMain *plugin;
254         TitleOutlineEngine *engine;
255 };
256
257 class TitleOutlineEngine : public LoadServer
258 {
259 public:
260         TitleOutlineEngine(TitleMain *plugin, int cpus);
261         void init_packages();
262         void do_outline();
263         LoadClient* new_client();
264         LoadPackage* new_package();
265         TitleMain *plugin;
266         int pass;
267 };
268
269
270
271
272
273
274
275
276
277 // Overlay text mask with fractional translation
278 // We don't use OverlayFrame to enable alpha blending on non alpha
279 // output.
280 class TitleTranslatePackage : public LoadPackage
281 {
282 public:
283         TitleTranslatePackage();
284         int y1, y2;
285 };
286
287 typedef struct
288 {
289         int in_x1;
290         float in_fraction1;
291         int in_x2;       // Might be same as in_x1 for boundary
292         float in_fraction2;
293         float output_fraction;
294 } transfer_table_f;
295
296 class TitleTranslateUnit : public LoadClient
297 {
298 public:
299         TitleTranslateUnit(TitleMain *plugin, TitleTranslate *server);
300
301         static void translation_array_f(transfer_table_f* &table,
302                 float out_x1, float out_x2, float in_x1, float in_x2,
303                 int in_total, int out_total, int &out_x1_int, int &out_x2_int);
304         void process_package(LoadPackage *package);
305         TitleMain *plugin;
306 };
307
308 class TitleTranslate : public LoadServer
309 {
310 public:
311         TitleTranslate(TitleMain *plugin, int cpus);
312         ~TitleTranslate();
313         void init_packages();
314         void run_packages();
315         LoadClient* new_client();
316         LoadPackage* new_package();
317         TitleMain *plugin;
318         transfer_table_f *y_table;
319         transfer_table_f *x_table;
320         int output_w;
321         int output_h;
322 // Result of translation_array_f
323         int out_x1_int;
324         int out_x2_int;
325         int out_y1_int;
326         int out_y2_int;
327 // Values to process
328         int out_x1;
329         int out_x2;
330         int out_y1;
331         int out_y2;
332 };
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 // Position of each character relative to total text extents
348 typedef struct
349 {
350         int x, y, w, row;
351 } char_pos_t;
352
353
354
355 class TitleMain : public PluginVClient
356 {
357 public:
358         TitleMain(PluginServer *server);
359         ~TitleMain();
360
361 // required for all realtime plugins
362         PLUGIN_CLASS_MEMBERS(TitleConfig)
363         int process_realtime(VFrame *input_ptr, VFrame *output_ptr);
364         int is_realtime();
365         int is_synthesis();
366         void update_gui();
367         void save_data(KeyFrame *keyframe);
368         void read_data(KeyFrame *keyframe);
369
370         void build_previews(TitleWindow *gui);
371         void reset_render();
372         int init_freetype();
373         void load_glyphs();
374         int draw_mask();
375         void overlay_mask();
376         TitleGlyph *get_glyph(FT_ULong char_code);
377         BC_FontEntry* get_font();
378         int get_char_advance(FT_ULong current, FT_ULong next);
379         int get_char_height();
380         int get_char_width(FT_ULong c);
381         void get_total_extents();
382         void clear_glyphs();
383         int check_char_code_path(FT_Library &freetype_library,
384                 char *path_old,
385                 FT_ULong &char_code,
386                 char *path_new);
387         int load_freetype_face(FT_Library &freetype_library,
388                 FT_Face &freetype_face,
389                 const char *path);
390         void get_color_components(int *r, int *g, int *b, int *a, int is_outline);
391
392
393
394
395 // backward compatibility
396         void convert_encoding();
397         static const char* motion_to_text(int motion);
398         static int text_to_motion(const char *text);
399
400         ArrayList<TitleGlyph*> glyphs;
401         Mutex glyph_lock;
402
403 // Stage 1 parameters must be compared to redraw the text mask
404         VFrame *text_mask;
405         VFrame *text_mask_stroke;
406         VFrame *outline_mask;
407         GlyphEngine *glyph_engine;
408         TitleEngine *title_engine;
409         TitleTranslate *translate;
410         TitleOutlineEngine *outline_engine;
411
412 // Necessary to get character width
413         FT_Library freetype_library;            // Freetype library
414         FT_Face freetype_face;
415
416 // Visible area of all text present in the mask.
417 // Horizontal characters aren't clipped because column positions are
418 // proportional.
419         int visible_row1, visible_char1;
420         int visible_row2, visible_char2;
421 // Positions of the top pixels of the rows
422         class Geom {
423         public: // x1,y1 x2,y2 are abs
424                 int x0, y0, x1, y1, x2, y2;
425         } extent;
426         class RowGeom : public Geom {
427         public: // x1,x2 y1,y2 are rel x0,y0
428                 int left()   { return x0+x1; }
429                 int top()    { return y0+y1; }
430                 int right()  { return x0+x2; }
431                 int bottom() { return y0+y2; }
432         } *row_geom;
433         int row_geom_size;
434
435         int text_rows;
436 // relative position of all text to output
437         int text_w, text_h;
438         float text_x1, text_y1, text_x2, text_y2;
439 // Position of each character relative to total text extents
440         char_pos_t *char_pos;
441 // relative position of visible part of text to output
442         int mask_w, mask_h;
443
444 // Fade value
445         int alpha;
446
447 // Max dimensions for all characters.  Not equal to config.size
448 // Must be calculated from rendering characters
449         int ascent;
450         int height;
451 // Relative position of mask to output is text_x1, mask_y1
452 // We can either round it to nearest ints to speed up replication while the text
453 // itself is offset fractionally
454 // or replicate with fractional offsetting.  Since fraction offsetting usually
455 // happens during motion and motion would require floating point offsetting
456 // for every frame we replicate with fractional offsetting.
457
458
459
460         VFrame *input, *output;
461
462         int need_reconfigure;
463         int cpus;
464 };
465
466
467 #endif