Andrew add of titler reset button and english save + tips and po updates
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / titler / titler.C
index d0f4f681ca08fddd629e7cffa36f392c6aa8317f..95218e4c83dc0545be551aa2b73b73c64c553f40 100644 (file)
@@ -76,7 +76,7 @@ REGISTER_PLUGIN(TitleMain)
 #else
 #define DEFAULT_ENCODING "ISO8859-1"
 #endif
-#define DEFAULT_TIMECODEFORMAT TIME_HMS
+#define DEFAULT_TIMECODEFORMAT TIME_HMSF
 
 static inline int kw_strcmp(const char *ap, const char *bp) {
        return !strcmp(ap, bp) ? 0 : strcmp(ap,_(bp));
@@ -87,11 +87,11 @@ TitleConfig::TitleConfig()
        strcpy(font, "fixed");
        strcpy(encoding, DEFAULT_ENCODING);
        style = FONT_ALIAS;
-       size = 24;
-       color = BLACK;
+       size = 48;
+       color = WHITE;
        alpha = 0xff;
        outline_size = 0.;
-       outline_color = WHITE;
+       outline_color = RED;
        outline_alpha = 0xff;
        color_stroke = 0xff0000;
        stroke_width = 0.0;
@@ -105,16 +105,15 @@ TitleConfig::TitleConfig()
        wtext = 0;  wsize = 0;  wlen = 0;
        title_x = title_y = 0.0;
        title_w = title_h = 0;
-       window_w = 860;
-       window_h = 460;
+       window_w = xS(860);
+       window_h = yS(460);
        next_keyframe_position = 0;
        prev_keyframe_position = 0;
        timecode = 0;
-       dropshadow = 2;
+       dropshadow = 0;
        background = 0;
        strcpy(background_path, "");
        timecode_format = DEFAULT_TIMECODEFORMAT;
-       drag = 0;
        loop_playback = 0;
 }
 
@@ -145,8 +144,8 @@ int TitleConfig::equivalent(TitleConfig &that)
 //             fade_in == that.fade_in && fade_out == that.fade_out &&
 //             EQUIV(pixels_per_second, that.pixels_per_second) &&
                wlen == that.wlen &&
-               !memcmp(wtext, that.wtext, wlen * sizeof(wchar_t)) &&
-//             title_x == that.title_x && title_y == that.title_y &&
+               !memcmp(wtext, that.wtext, wlen * sizeof(wchr_t)) &&
+               EQUIV(title_x, that.title_x) && EQUIV(title_y, that.title_y) &&
                title_w == that.title_w && title_h == that.title_h &&
 //             window_w == that.window_w && window_h == that.window_h &&
                timecode == that.timecode &&
@@ -154,7 +153,6 @@ int TitleConfig::equivalent(TitleConfig &that)
                background == that.background &&
                !strcmp(background_path, that.background_path) &&
                timecode_format == that.timecode_format &&
-//             drag == that.drag &&
                loop_playback == that.loop_playback;
 }
 
@@ -180,7 +178,7 @@ void TitleConfig::copy_from(TitleConfig &that)
        fade_out = that.fade_out;
        pixels_per_second = that.pixels_per_second;
        demand(wlen = that.wlen);
-       memcpy(wtext, that.wtext, that.wlen * sizeof(wchar_t));
+       memcpy(wtext, that.wtext, that.wlen * sizeof(wchr_t));
        title_x = that.title_x;  title_y = that.title_y;
        title_w = that.title_w;  title_h = that.title_h;
        window_w = that.window_w;  window_h = that.window_h;
@@ -189,7 +187,6 @@ void TitleConfig::copy_from(TitleConfig &that)
        background = that.background;
        strcpy(background_path, that.background_path);
        timecode_format = that.timecode_format;
-       drag = that.drag;
        loop_playback = that.loop_playback;
 }
 
@@ -218,7 +215,7 @@ void TitleConfig::interpolate(TitleConfig &prev, TitleConfig &next,
        fade_out = prev.fade_out;
        pixels_per_second = prev.pixels_per_second;
        demand(wlen = prev.wlen);
-       memcpy(wtext, prev.wtext, prev.wlen * sizeof(wchar_t));
+       memcpy(wtext, prev.wtext, prev.wlen * sizeof(wchr_t));
        wtext[wlen] = 0;
        this->title_x = prev.title_x == next.title_x ? prev.title_x :
                prev.title_x * prev_scale + next.title_x * next_scale;
@@ -236,7 +233,6 @@ void TitleConfig::interpolate(TitleConfig &prev, TitleConfig &next,
        background = prev.background;
        strcpy(background_path, prev.background_path);
        timecode_format = prev.timecode_format;
-       drag = prev.drag;
        loop_playback = prev.loop_playback;
 }
 
@@ -245,7 +241,7 @@ int TitleConfig::demand(long sz)
        if( wtext && wsize >= sz ) return 0;
        delete [] wtext;
        wsize = sz + wlen/2 + 0x1000;
-       wtext = new wchar_t[wsize+1];
+       wtext = new wchr_t[wsize+1];
        wtext[wsize] = 0;
        return 1;
 }
@@ -254,7 +250,7 @@ void TitleConfig::to_wtext(const char *from_enc, const char *text, int tlen)
 {
        demand(tlen);
        wlen = BC_Resources::encode(from_enc, BC_Resources::wide_encoding,
-               (char*)text,tlen, (char *)wtext,sizeof(*wtext)*wsize) / sizeof(wchar_t);
+               (char*)text,tlen, (char *)wtext,sizeof(*wtext)*wsize) / sizeof(wchr_t);
        while( wlen > 0 && !wtext[wlen-1] ) --wlen;
 }
 
@@ -362,14 +358,14 @@ printf("GlyphUnit::process_package 1 glyph not found (%s) %04x, '%c'\n",
                        glyph->right = 0;  glyph->bottom = 0;
                        glyph->freetype_index = 0;
                        glyph->data = new VFrame(glyph->width, glyph->height, BC_A8, glyph->pitch);
-                       glyph->data->clear_frame();
+                       glyph->data->black_frame();
                        glyph->data_stroke = 0;
 
 // create outline glyph
                        if( plugin->config.stroke_width >= SMALL &&
                                (plugin->config.style & BC_FONT_OUTLINE) ) {
                                glyph->data_stroke = new VFrame(glyph->width, glyph->height, BC_A8, glyph->pitch);
-                               glyph->data_stroke->clear_frame();
+                               glyph->data_stroke->black_frame();
                        }
                }
 // char found and no outline desired
@@ -399,7 +395,7 @@ printf("GlyphUnit::process_package 1 glyph not found (%s) %04x, '%c'\n",
 //glyph->width, glyph->height, glyph->pitch, glyph->left, glyph->top, glyph->advance_x, glyph->freetype_index);
 
                        glyph->data = new VFrame(glyph->width, glyph->height, BC_A8, glyph->pitch);
-                       glyph->data->clear_frame();
+                       glyph->data->black_frame();
                        bm.buffer = glyph->data->get_data();
                        ft_Outline_Translate(&((FT_OutlineGlyph) glyph_image)->outline,
                                - bbox.xMin, - bbox.yMin);
@@ -500,9 +496,9 @@ printf("GlyphUnit::process_package 1 glyph not found (%s) %04x, '%c'\n",
 
 //printf("GlyphUnit::process_package 1\n");
                        glyph->data = new VFrame(glyph->width, glyph->height, BC_A8, glyph->pitch);
-                       glyph->data->clear_frame();
+                       glyph->data->black_frame();
                        glyph->data_stroke = new VFrame(glyph->width, glyph->height, BC_A8, glyph->pitch);
-                       glyph->data_stroke->clear_frame();
+                       glyph->data_stroke->black_frame();
 // for debugging       memset( glyph->data_stroke->get_data(), 60, glyph->pitch * glyph->height);
                        bm.buffer=glyph->data->get_data();
                        ft_Outline_Get_Bitmap( freetype_library,
@@ -935,6 +931,7 @@ TitleMain::TitleMain(PluginServer *server)
        if( cpus > 8 ) cpus = 8;
        last_position = -1;
        need_reconfigure = 1;
+       drag = 0;
 }
 
 TitleMain::~TitleMain()
@@ -944,7 +941,8 @@ TitleMain::~TitleMain()
                background = 0;
        }
        delete render_engine;
-       delete video_cache;
+       if( video_cache )
+               video_cache->remove_user(); 
        delete overlay_frame;
        delete bg_file;
        delete bg_frame;
@@ -967,6 +965,18 @@ int TitleMain::is_synthesis() { return 1; }
 
 NEW_WINDOW_MACRO(TitleMain, TitleWindow);
 
+void TitleMain::render_gui(void *data)
+{
+       TitleMain *tilter = (TitleMain *)data;
+       tilter->drag = drag;
+}
+
+int TitleMain::is_dragging()
+{
+       drag = 0;
+       send_render_gui(this);
+       return drag;
+}
 
 void TitleMain::build_previews(TitleWindow *gui)
 {
@@ -1186,7 +1196,7 @@ int TitleMain::load_font(BC_FontEntry *font)
 Indexable *TitleMain::open_background(const char *filename)
 {
        delete render_engine;  render_engine = 0;
-       delete video_cache;    video_cache = 0;
+       if( video_cache ) { video_cache->remove_user();  video_cache = 0; }
        delete bg_file;        bg_file = new File;
 
        Asset *asset = new Asset(filename);
@@ -1325,21 +1335,22 @@ BC_FontEntry* TitleMain::config_font()
 }
 
 
-static inline bool is_ltr(wchar_t wch) { return iswalpha(wch); }
-static inline bool is_nbr(wchar_t wch) { return iswdigit(wch); }
-static inline bool is_ws(wchar_t wch) { return wch==' ' || wch=='\t'; }
-static inline bool is_idch(wchar_t wch) { return is_ltr(wch) || is_nbr(wch) || wch=='_'; }
+static inline bool is_ltr(wchr_t wch) { return iswalpha(wch); }
+static inline bool is_nbr(wchr_t wch) { return iswdigit(wch); }
+static inline bool is_ws(wchr_t wch) { return wch==' ' || wch=='\t'; }
+static inline bool is_idch(wchr_t wch) { return is_ltr(wch) || is_nbr(wch) || wch=='_'; }
 
 // return eof=-1, chr=0, opener=1, closer=2
-int TitleParser::wget(wchar_t &wch)
+int TitleParser::wget(wchr_t &wch)
 {
-       wchar_t *wip = wid, *wtp = wtxt;  *wip = 0;  *wtp = 0;
+       wchr_t *wip = wid, *wtp = wtxt;  *wip = 0;  *wtp = 0;
        int ilen = sizeof(wid)/sizeof(wid[0]);
        int tlen = sizeof(wtxt)/sizeof(wtxt[0]);
        int ich;
        while( (ich=wnext()) >= 0 ) {
                if( ich == '\\' ) {
-                       if( (ich=wnext()) == '\n' ) continue;
+                       if( (ich=wnext()) < 0 ) break;
+                       if( !ich || ich == '\n' ) continue;
                        wch = ich;
                        return 0;
                }
@@ -1369,15 +1380,15 @@ int TitleParser::wget(wchar_t &wch)
        wch = ich;
        return ret;
 }
-int TitleParser::tget(wchar_t &wch)
+int TitleParser::tget(wchr_t &wch)
 {
        int ret = wget(wch);
        if( ret > 0 ) {
-               int wid_len = wcslen(wid)+1;
+               int wid_len = wstrlen(wid)+1;
                BC_Resources::encode(
                        BC_Resources::wide_encoding, plugin->config.encoding,
                        (char*)wid,wid_len*sizeof(wid[0]), (char *)id,sizeof(id));
-               int wtxt_len = wcslen(wtxt)+1;
+               int wtxt_len = wstrlen(wtxt)+1;
                BC_Resources::encode(
                        BC_Resources::wide_encoding, plugin->config.encoding,
                        (char*)wtxt,wtxt_len*sizeof(wtxt[0]), (char *)text,sizeof(text));
@@ -1669,7 +1680,7 @@ void TitleMain::load_glyphs()
        int total_packages = 0;
 
        while( !wchrs.eof() ) {
-               wchar_t wch1 = wchrs.wcur(), wch;
+               wchr_t wch1 = wchrs.wcur(), wch;
                long ipos = wchrs.tell();
                int ret = wchrs.tget(wch);
                if( ret > 0 ) {
@@ -1777,7 +1788,7 @@ int TitleMain::get_text()
                if( !row ) row = title_rows.add();
                TitleChar *chr = 0;
                long ipos = wchrs.tell();
-               wchar_t wch1 = wchrs.wcur(), wch;
+               wchr_t wch1 = wchrs.wcur(), wch;
                int ret = wchrs.tget(wch);
                if( ret < 0 || wch == '\n' ) {
                        if( row->x1 > row->x2 ) row->x1 = row->x2 = 0;
@@ -2147,7 +2158,7 @@ void TitleMain::draw_overlay()
 //printf("TitleMain::draw_overlay 1\n");
         fade = 1;
         if( !EQUIV(config.fade_in, 0) ) {
-               int64_t plugin_start = server->plugin->startproject;
+               int64_t plugin_start = get_startproject();
                int64_t fade_len = lroundf(config.fade_in * PluginVClient::project_frame_rate);
                int64_t fade_position = get_source_position() - plugin_start;
 
@@ -2156,7 +2167,7 @@ void TitleMain::draw_overlay()
                }
        }
         if( !EQUIV(config.fade_out, 0) ) {
-               int64_t plugin_end = server->plugin->startproject + server->plugin->length;
+               int64_t plugin_end = get_endproject();
                int64_t fade_len = lroundf(config.fade_out * PluginVClient::project_frame_rate);
                int64_t fade_position = plugin_end - get_source_position();
 
@@ -2450,7 +2461,7 @@ int TitleMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
        if( !result )
                draw_overlay();
 
-       if( config.drag )
+       if( is_dragging() )
                draw_boundry();
 
        return 0;
@@ -2458,16 +2469,14 @@ int TitleMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
 
 void TitleMain::update_gui()
 {
-       if( thread ) {
-               int reconfigure = load_configuration();
-               if( reconfigure ) {
-                       TitleWindow *window = (TitleWindow*)thread->window;
-                       window->lock_window("TitleMain::update_gui");
-                       window->update();
-                       window->unlock_window();
-                       window->color_thread->update_gui(config.color, 0);
-               }
+       if( !thread ) return;
+       thread->window->lock_window("TitleMain::update_gui");
+       TitleWindow *window = (TitleWindow*)thread->window;
+       if( load_configuration() ) {
+               window->update_gui();
+               window->flush();
        }
+       window->unlock_window();
 }
 
 int TitleMain::load_configuration()
@@ -2545,7 +2554,6 @@ void TitleMain::save_data(KeyFrame *keyframe)
        output.tag.set_property("TIMECODEFORMAT", config.timecode_format);
        output.tag.set_property("WINDOW_W", config.window_w);
        output.tag.set_property("WINDOW_H", config.window_h);
-       output.tag.set_property("DRAG", config.drag);
        output.tag.set_property("BACKGROUND", config.background);
        output.tag.set_property("BACKGROUND_PATH", config.background_path);
        output.tag.set_property("LOOP_PLAYBACK", config.loop_playback);
@@ -2555,7 +2563,7 @@ void TitleMain::save_data(KeyFrame *keyframe)
        char text[tsz];
        int text_len = BC_Resources::encode(
                BC_Resources::wide_encoding, DEFAULT_ENCODING,
-               (char*)config.wtext, config.wlen*sizeof(wchar_t),
+               (char*)config.wtext, config.wlen*sizeof(wchr_t),
                text, tsz);
        output.append_text(text, text_len);
        output.tag.set_title("/TITLE");
@@ -2609,7 +2617,6 @@ void TitleMain::read_data(KeyFrame *keyframe)
                        config.timecode_format = input.tag.get_property("TIMECODEFORMAT", config.timecode_format);
                        config.window_w = input.tag.get_property("WINDOW_W", config.window_w);
                        config.window_h = input.tag.get_property("WINDOW_H", config.window_h);
-                       config.drag = input.tag.get_property("DRAG", config.drag);
                        config.background = input.tag.get_property("BACKGROUND", config.background);
                        input.tag.get_property("BACKGROUND_PATH", config.background_path);
                        config.loop_playback = input.tag.get_property("LOOP_PLAYBACK", config.loop_playback);
@@ -2622,15 +2629,15 @@ void TitleMain::read_data(KeyFrame *keyframe)
        }
 }
 
-void TitleMain::insert_text(const wchar_t *wtxt, int pos)
+void TitleMain::insert_text(const wchr_t *wtxt, int pos)
 {
-       int len = wcslen(wtxt);
+       int len = wstrlen(wtxt);
        int wlen = config.wlen;
        if( pos < 0 ) pos = 0;
        if( pos > wlen ) pos = wlen;
        config.demand(wlen + len);
        int wsize1 = config.wsize-1;
-       wchar_t *wtext = config.wtext;
+       wchr_t *wtext = config.wtext;
        for( int i=wlen, j=wlen+len; --i>=pos; ) {
                if( --j >= wsize1 ) continue;
                wtext[j] = wtext[i];