X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Ftitler%2Ftitler.C;h=dde50aa37bc9a0b7c98f572d31891a831d69059d;hp=a90731dd963d03654005b1bbd415f064258c83c4;hb=3badd817d6f012b5e882940db0c5d7e61cec15d7;hpb=331564c0ebb30688da917fc1c89058e12771e348 diff --git a/cinelerra-5.1/plugins/titler/titler.C b/cinelerra-5.1/plugins/titler/titler.C index a90731dd..dde50aa3 100644 --- a/cinelerra-5.1/plugins/titler/titler.C +++ b/cinelerra-5.1/plugins/titler/titler.C @@ -46,6 +46,7 @@ #include "language.h" #include "mwindow.inc" #include "overlayframe.h" +#include "plugin.h" #include "renderengine.h" #include "titler.h" #include "titlerwindow.h" @@ -60,11 +61,10 @@ #include #include #include -#include #include #include -#define FIXED_FONT "Bitstream Vera Sans Mono (Bits)" +#define FIXED_FONT "bitstream vera sans mono (bitstream)" #define SMALL (1.0 / 64.0) #define MAX_FLT 3.40282347e+38 @@ -81,38 +81,36 @@ REGISTER_PLUGIN(TitleMain) TitleConfig::TitleConfig() { + strcpy(font, "fixed"); + strcpy(encoding, DEFAULT_ENCODING); style = 0; + size = 24; color = BLACK; alpha = 0xff; + outline_size = 0.; + outline_color = WHITE; outline_alpha = 0xff; - size = 24; + color_stroke = 0xff0000; + stroke_width = 1.0; motion_strategy = NO_MOTION; - loop = 0; line_pitch = 0; + loop = 0; hjustification = JUSTIFY_CENTER; vjustification = JUSTIFY_MID; - fade_in = 0.0; - fade_out = 0.0; + fade_in = 0.0; fade_out = 0.0; + pixels_per_second = 100.0; + wtext[0] = 0; wlen = 0; title_x = title_y = 0.0; title_w = title_h = 0; - dropshadow = 2; - strcpy(font, "fixed"); - strcpy(encoding, DEFAULT_ENCODING); - timecode_format = DEFAULT_TIMECODEFORMAT; - pixels_per_second = 1.0; - timecode = 0; - stroke_width = 1.0; - wtext[0] = 0; wlen = 0; - color_stroke = 0xff0000; - outline_color = WHITE; - background = 0; - strcpy(background_path, ""); - - outline_size = 0; - window_w = 800; + window_w = 860; window_h = 460; next_keyframe_position = 0; prev_keyframe_position = 0; + timecode = 0; + dropshadow = 2; + background = 0; + strcpy(background_path, ""); + timecode_format = DEFAULT_TIMECODEFORMAT; drag = 0; loop_playback = 0; } @@ -124,102 +122,118 @@ TitleConfig::~TitleConfig() int TitleConfig::equivalent(TitleConfig &that) { return !strcasecmp(font, that.font) && + !strcasecmp(encoding, that.encoding) && style == that.style && size == that.size && color == that.color && - color_stroke == that.color_stroke && - stroke_width == that.stroke_width && - outline_color == that.outline_color && alpha == that.alpha && + outline_size == that.outline_size && + outline_color == that.outline_color && outline_alpha == that.outline_alpha && - EQUIV(pixels_per_second, that.pixels_per_second) && - motion_strategy == that.motion_strategy && - loop == that.loop && + color_stroke == that.color_stroke && + stroke_width == that.stroke_width && +// dont require redraw for these +// motion_strategy == that.motion_strategy && line_pitch == that.line_pitch && +// loop == that.loop && hjustification == that.hjustification && vjustification == that.vjustification && - fade_in == that.fade_in && fade_out == that.fade_out && - title_x == that.title_x && title_y == that.title_y && +// 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 && title_w == that.title_w && title_h == that.title_h && - dropshadow == that.dropshadow && +// window_w == that.window_w && window_h == that.window_h && timecode == that.timecode && + dropshadow == that.dropshadow && + background == that.background && + !strcmp(background_path, that.background_path) && timecode_format == that.timecode_format && - outline_size == that.outline_size && - !strcasecmp(encoding, that.encoding) && - wlen == that.wlen && - !memcmp(wtext, that.wtext, wlen * sizeof(wchar_t)); +// drag == that.drag && + loop_playback == that.loop_playback; } void TitleConfig::copy_from(TitleConfig &that) { strcpy(font, that.font); + strcpy(encoding, that.encoding); style = that.style; size = that.size; color = that.color; - color_stroke = that.color_stroke; - stroke_width = that.stroke_width; - outline_color = that.outline_color; alpha = that.alpha; + outline_size = that.outline_size; + outline_color = that.outline_color; outline_alpha = that.outline_alpha; - pixels_per_second = that.pixels_per_second; + color_stroke = that.color_stroke; + stroke_width = that.stroke_width; motion_strategy = that.motion_strategy; - loop = that.loop; line_pitch = that.line_pitch; + loop = that.loop; hjustification = that.hjustification; vjustification = that.vjustification; fade_in = that.fade_in; fade_out = that.fade_out; - title_x = that.title_x; - title_y = that.title_y; - title_w = that.title_w; - title_h = that.title_h; - dropshadow = that.dropshadow; + pixels_per_second = that.pixels_per_second; + wlen = that.wlen; + memcpy(wtext, that.wtext, that.wlen * sizeof(wchar_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; timecode = that.timecode; + dropshadow = that.dropshadow; + background = that.background; + strcpy(background_path, that.background_path); timecode_format = that.timecode_format; - outline_size = that.outline_size; - strcpy(encoding, that.encoding); - memcpy(wtext, that.wtext, that.wlen * sizeof(wchar_t)); - wlen = that.wlen; - window_w = that.window_w; - window_h = that.window_h; + drag = that.drag; + loop_playback = that.loop_playback; } void TitleConfig::interpolate(TitleConfig &prev, TitleConfig &next, int64_t prev_frame, int64_t next_frame, int64_t current_frame) { + double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); + double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); strcpy(font, prev.font); strcpy(encoding, prev.encoding); style = prev.style; size = prev.size; color = prev.color; - color_stroke = prev.color_stroke; - stroke_width = prev.stroke_width; - outline_color = prev.outline_color; alpha = prev.alpha; + outline_size = prev.outline_size; + outline_color = prev.outline_color; outline_alpha = prev.outline_alpha; + color_stroke = prev.color_stroke; + stroke_width = prev.stroke_width; motion_strategy = prev.motion_strategy; - loop = prev.loop; line_pitch = prev.line_pitch; + loop = prev.loop; hjustification = prev.hjustification; vjustification = prev.vjustification; fade_in = prev.fade_in; fade_out = prev.fade_out; - outline_size = prev.outline_size; pixels_per_second = prev.pixels_per_second; - memcpy(wtext, prev.wtext, prev.wlen * sizeof(wchar_t)); wlen = prev.wlen; + memcpy(wtext, prev.wtext, prev.wlen * sizeof(wchar_t)); wtext[wlen] = 0; - - double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); - double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); - this->title_x = prev.title_x * prev_scale + next.title_x * next_scale; - this->title_y = prev.title_y * prev_scale + next.title_y * next_scale; -// this->title_x = prev.title_x; -// this->title_y = prev.title_y; + this->title_x = prev.title_x == next.title_x ? prev.title_x : + prev.title_x * prev_scale + next.title_x * next_scale; + this->title_y = prev.title_y == next.title_y ? prev.title_y : + prev.title_y * prev_scale + next.title_y * next_scale; + this->title_w = prev.title_w == next.title_w ? prev.title_w : + prev.title_w * prev_scale + next.title_w * next_scale; + this->title_h = prev.title_h == next.title_h ? prev.title_h : + prev.title_h * prev_scale + next.title_h * next_scale; + window_w = prev.window_w; + window_h = prev.window_h; timecode = prev.timecode; + this->dropshadow = prev.dropshadow == next.dropshadow ? prev.dropshadow : + prev.dropshadow * prev_scale + next.dropshadow * next_scale; + background = prev.background; + strcpy(background_path, prev.background_path); timecode_format = prev.timecode_format; - this->dropshadow = prev.dropshadow * prev_scale + next.dropshadow * next_scale; -// this->dropshadow = prev.dropshadow; + drag = prev.drag; + loop_playback = prev.loop_playback; } void TitleConfig::to_wtext(const char *from_enc, const char *text, int tlen) @@ -287,13 +301,16 @@ void GlyphUnit::process_package(LoadPackage *package) glyph->font->path); result = 1; } - if( !result ) { int gindex = FT_Get_Char_Index(freetype_face, glyph->char_code); - -//printf("GlyphUnit::process_package 1 %c\n", glyph->char_code); -// Char not found + if( !gindex && !freetype_face->charmap && // if no default charmap + freetype_face->charmaps && freetype_face->charmaps[0] && + !FT_Select_Charmap(freetype_face, freetype_face->charmaps[0]->encoding) ) { + gindex = FT_Get_Char_Index(freetype_face, glyph->char_code); + } if( gindex == 0 ) { +printf("GlyphUnit::process_package 1 glyph not found (%s) %04x, '%c'\n", + glyph->font->displayname, (unsigned)glyph->char_code, (unsigned)glyph->char_code); BC_Resources *resources = BC_WindowBase::get_resources(); // Search replacement font if( resources->find_font_by_char(glyph->char_code, new_path, freetype_face) ) { @@ -1461,37 +1478,41 @@ BC_FontEntry* TitleMain::get_font(const char *font_name, int style) { if( !strcmp("fixed", font_name) ) font_name = FIXED_FONT; - int flavor = + int flavor = FL_WIDTH_MASK | ((style & BC_FONT_ITALIC) != 0 ? FL_SLANT_ITALIC | FL_SLANT_OBLIQUE : FL_SLANT_ROMAN) | ((style & BC_FONT_BOLD) != 0 ? FL_WEIGHT_BOLD | FL_WEIGHT_DEMIBOLD | FL_WEIGHT_EXTRABOLD| FL_WEIGHT_BLACK | FL_WEIGHT_EXTRABLACK : FL_WEIGHT_BOOK | FL_WEIGHT_NORMAL | FL_WEIGHT_MEDIUM | FL_WEIGHT_LIGHT | FL_WEIGHT_EXTRALIGHT | FL_WEIGHT_THIN); - int mask = FL_WEIGHT_MASK | FL_SLANT_MASK; + int mask = FL_WEIGHT_MASK | FL_SLANT_MASK | FL_WIDTH_MASK; BC_Resources *resources = BC_WindowBase::get_resources(); - return resources->find_fontentry(font_name, flavor, mask, style); + BC_FontEntry *font = resources->find_fontentry(font_name, flavor, mask, style); + if( font && strcmp(font_name, font->displayname) ) font = 0; + return font; } BC_FontEntry* TitleMain::config_font() { BC_FontEntry *font = get_font(config.font, config.style); - if( font && load_font(font) ) - font = get_font(FIXED_FONT,0); + if( !font || load_font(font) ) + load_font(font = get_font(FIXED_FONT,0)); return font; } -static inline bool is_ltr(wchar_t wch) { return (wch>='a' && wch<='z') || (wch>='A' && wch<='Z'); } -static inline bool is_nbr(wchar_t wch) { return (wch>='0' && wch<='9'); } +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=='_'; } // return eof=-1, chr=0, opener=1, closer=2 int TitleParser::wget(wchar_t &wch) { - char *ip = id, *tp = text; *ip = 0; *tp = 0; - int ilen = sizeof(id), tlen = sizeof(text), ich; + wchar_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; @@ -1507,23 +1528,38 @@ int TitleParser::wget(wchar_t &wch) int ret = 1; long pos = tell(); if( (ich=wnext()) == '/' ) { ret = 2; ich = wnext(); } if( is_ltr(ich) ) { - *ip++ = ich; + *wip++ = ich; while( is_idch(ich=wnext()) ) - if( --ilen > 0 ) *ip++ = ich; + if( --ilen > 0 ) *wip++ = ich; } - *ip = 0; + *wip = 0; while( is_ws(ich) ) ich = wnext(); while( ich >= 0 && ich != '>' ) { if( ich == '\n' || ich == '<' ) { ich = -1; break; } if( ich == '\\' && (ich=wnext()) < 0 ) break; - if( --tlen > 0 ) *tp++ = ich; + if( --tlen > 0 ) *wtp++ = ich; ich = wnext(); } - *tp = 0; + *wtp = 0; if( ich < 0 ) { ich = '<'; seek(pos); ret = 0; } wch = ich; return ret; } +int TitleParser::tget(wchar_t &wch) +{ + int ret = wget(wch); + if( ret > 0 ) { + int wid_len = wcslen(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; + BC_Resources::encode( + BC_Resources::wide_encoding, plugin->config.encoding, + (char*)wtxt,wtxt_len*sizeof(wtxt[0]), (char *)text,sizeof(text)); + } + return ret; +} TitleGlyph *TitleMain::get_glyph(FT_ULong char_code, BC_FontEntry *font, int size, int style) { @@ -1776,18 +1812,18 @@ int TitleCurNudge::set(const char *txt) int TitleParser::set_attributes(int ret) { - if( !strcmp(id,_("nudge")) ) return ret>1 ? cur_nudge.unset(text) : cur_nudge.set(text); - if( !strcmp(id,_("color")) ) return ret>1 ? cur_color.unset(text) : cur_color.set(text); - if( !strcmp(id,_("alpha")) ) return ret>1 ? cur_alpha.unset(text) : cur_alpha.set(text); - if( !strcmp(id,_("font")) ) return ret>1 ? cur_font.unset(text) : cur_font.set(text); - if( !strcmp(id,_("size")) ) return ret>1 ? cur_size.unset(text) : cur_size.set(text); - if( !strcmp(id,_("bold")) ) return ret>1 ? cur_bold.unset(text) : cur_bold.set(text); - if( !strcmp(id,_("italic")) ) return ret>1 ? cur_italic.unset(text) : cur_italic.set(text); - if( !strcmp(id,_("caps")) ) return ret>1 ? cur_caps.unset(text) : cur_caps.set(text); - if( !strcmp(id,_("ul")) ) return ret>1 ? cur_under.unset(text) : cur_under.set(text); - if( !strcmp(id,_("blink")) ) return ret>1 ? cur_blink.unset(text) : cur_blink.set(text); - if( !strcmp(id,_("fixed")) ) return ret>1 ? cur_fixed.unset(text) : cur_fixed.set(text); - if( !strcmp(id,_("sup")) ) return ret>1 ? cur_super.unset(text) : cur_super.set(text); + if( !strcmp(id,KW_NUDGE) ) return ret>1 ? cur_nudge.unset(text) : cur_nudge.set(text); + if( !strcmp(id,KW_COLOR) ) return ret>1 ? cur_color.unset(text) : cur_color.set(text); + if( !strcmp(id,KW_ALPHA) ) return ret>1 ? cur_alpha.unset(text) : cur_alpha.set(text); + if( !strcmp(id,KW_FONT) ) return ret>1 ? cur_font.unset(text) : cur_font.set(text); + if( !strcmp(id,KW_SIZE) ) return ret>1 ? cur_size.unset(text) : cur_size.set(text); + if( !strcmp(id,KW_BOLD) ) return ret>1 ? cur_bold.unset(text) : cur_bold.set(text); + if( !strcmp(id,KW_ITALIC) ) return ret>1 ? cur_italic.unset(text) : cur_italic.set(text); + if( !strcmp(id,KW_CAPS) ) return ret>1 ? cur_caps.unset(text) : cur_caps.set(text); + if( !strcmp(id,KW_UL) ) return ret>1 ? cur_under.unset(text) : cur_under.set(text); + if( !strcmp(id,KW_BLINK) ) return ret>1 ? cur_blink.unset(text) : cur_blink.set(text); + if( !strcmp(id,KW_FIXED) ) return ret>1 ? cur_fixed.unset(text) : cur_fixed.set(text); + if( !strcmp(id,KW_SUP) ) return ret>1 ? cur_super.unset(text) : cur_super.set(text); return 1; } @@ -1801,45 +1837,45 @@ void TitleMain::load_glyphs() while( !wchrs.eof() ) { wchar_t wch1 = wchrs.wcur(), wch; long ipos = wchrs.tell(); - int ret = wchrs.wget(wch); + int ret = wchrs.tget(wch); if( ret > 0 ) { if( !wchrs.set_attributes(ret) ) continue; - if( !strcmp(wchrs.id,"png") && add_image(wchrs.text) ) continue; + if( !strcmp(wchrs.id,KW_PNG) && add_image(wchrs.text) ) continue; wch = wch1; wchrs.seek(ipos+1); ret = 0; } - if( !ret ) { - int cur_caps = wchrs.cur_caps; - if( cur_caps > 0 ) wch = towupper(wch); - else if( cur_caps < 0 ) wch = towlower(wch); - BC_FontEntry *cur_font = wchrs.cur_font; - int cur_size = wchrs.cur_size; - int cur_style = 0; - int cur_bold = wchrs.cur_bold; - if( cur_bold ) cur_style |= BC_FONT_BOLD; - int cur_italic = wchrs.cur_italic; - if( cur_italic ) cur_style |= BC_FONT_ITALIC; - int cur_super = wchrs.cur_super; - if( cur_super ) cur_size /= 2; - int exists = 0; - for( int j=0; jchar_code == (FT_ULong)wch && glyph->font == cur_font && - glyph->size == cur_size && glyph->style == cur_style ) { - exists = 1; break; - } - } + if( ret || wch == '\n' ) continue; - if( !exists && cur_font ) { - total_packages++; - TitleGlyph *glyph = new TitleGlyph; - glyph->char_code = (FT_ULong)wch; - glyph->font = cur_font; - glyph->size = cur_size; - glyph->style = cur_style; - title_glyphs.append(glyph); + int cur_caps = wchrs.cur_caps; + if( cur_caps > 0 ) wch = towupper(wch); + else if( cur_caps < 0 ) wch = towlower(wch); + BC_FontEntry *cur_font = wchrs.cur_font; + int cur_size = wchrs.cur_size; + int cur_style = 0; + int cur_bold = wchrs.cur_bold; + if( cur_bold ) cur_style |= BC_FONT_BOLD; + int cur_italic = wchrs.cur_italic; + if( cur_italic ) cur_style |= BC_FONT_ITALIC; + int cur_super = wchrs.cur_super; + if( cur_super ) cur_size /= 2; + int exists = 0; + for( int j=0; jchar_code == (FT_ULong)wch && glyph->font == cur_font && + glyph->size == cur_size && glyph->style == cur_style ) { + exists = 1; break; } } + + if( !exists && cur_font ) { + total_packages++; + TitleGlyph *glyph = new TitleGlyph; + glyph->char_code = (FT_ULong)wch; + glyph->font = cur_font; + glyph->size = cur_size; + glyph->style = cur_style; + title_glyphs.append(glyph); + } } if( !glyph_engine ) @@ -1906,7 +1942,7 @@ int TitleMain::get_text() TitleChar *chr = 0; long ipos = wchrs.tell(); wchar_t wch1 = wchrs.wcur(), wch; - int ret = wchrs.wget(wch); + int ret = wchrs.tget(wch); if( ret < 0 || wch == '\n' ) { if( row->x1 > row->x2 ) row->x1 = row->x2 = 0; if( row->y2 > row->y1 ) row->y1 = row->y2 = 0; @@ -1941,7 +1977,7 @@ int TitleMain::get_text() if( ret > 0 ) { if( !wchrs.set_attributes(ret) ) continue; ret = -1; - if( !strcmp(wchrs.id,"png") ) { + if( !strcmp(wchrs.id,KW_PNG) ) { VFrame *png_image = get_image(wchrs.text); if( png_image ) { chr = title_chars.add(CHAR_IMAGE, png_image); @@ -2055,7 +2091,7 @@ int TitleMain::get_visible_text() case RIGHT_TO_LEFT: case LEFT_TO_RIGHT: { float magnitude = config.pixels_per_second * - (get_source_position() - config.prev_keyframe_position) / + (get_source_position() - get_source_start()) / PluginVClient::project_frame_rate; if( config.loop ) { int loop_size = text_w + title_w; @@ -2270,21 +2306,21 @@ int TitleMain::draw_underline(VFrame *mask, int alpha) void TitleMain::draw_overlay() { - //printf("TitleMain::draw_overlay 1\n"); fade = 1; if( !EQUIV(config.fade_in, 0) ) { - int fade_len = lroundf(config.fade_in * PluginVClient::project_frame_rate); - int fade_position = get_source_position() - config.prev_keyframe_position; + int64_t plugin_start = server->plugin->startproject; + int64_t fade_len = lroundf(config.fade_in * PluginVClient::project_frame_rate); + int64_t fade_position = get_source_position() - plugin_start; if( fade_position >= 0 && fade_position < fade_len ) { fade = (float)fade_position / fade_len; } } if( !EQUIV(config.fade_out, 0) ) { - int fade_len = lroundf(config.fade_out * PluginVClient::project_frame_rate); - int fade_position = config.next_keyframe_position - get_source_position(); - + int64_t plugin_end = server->plugin->startproject + server->plugin->length; + int64_t fade_len = lroundf(config.fade_out * PluginVClient::project_frame_rate); + int64_t fade_position = plugin_end - get_source_position(); if( fade_position >= 0 && fade_position < fade_len ) { fade = (float)fade_position / fade_len; @@ -2638,25 +2674,25 @@ void TitleMain::read_data(KeyFrame *keyframe) } } -void TitleMain::insert_text(const char *txt, int pos) +void TitleMain::insert_text(const wchar_t *wtxt, int pos) { - int ilen = strlen(txt); + int len = wcslen(wtxt); wchar_t *wtext = config.wtext; int wsize = sizeof(config.wtext)-1; int wlen = config.wlen; if( pos < 0 ) pos = 0; if( pos > wlen ) pos = wlen; - for( int i=wlen-1, j=wlen+ilen-1; i>=pos; --i,--j ) { + for( int i=wlen-1, j=wlen+len-1; i>=pos; --i,--j ) { if( j >= wsize ) continue; wtext[j] = wtext[i]; } - for( int i=pos, j=0; j= wsize ) break; - wtext[i] = txt[j]; + wtext[i] = wtxt[j]; } - if( (wlen+=ilen) > wsize ) wlen = wsize; + if( (wlen+=len) > wsize ) wlen = wsize; wtext[wlen] = 0; config.wlen = wlen; }