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=bdde6b47cd32a651dac4c75eac90ac48d7436358;hb=3badd817d6f012b5e882940db0c5d7e61cec15d7;hpb=77815ec03df6a03ed75433e8cf8ae1e83fb76d6e diff --git a/cinelerra-5.1/plugins/titler/titler.C b/cinelerra-5.1/plugins/titler/titler.C index bdde6b47..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,10 +61,10 @@ #include #include #include -#include #include #include +#define FIXED_FONT "bitstream vera sans mono (bitstream)" #define SMALL (1.0 / 64.0) #define MAX_FLT 3.40282347e+38 @@ -80,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 = 720; + 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; } @@ -123,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) @@ -286,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) ) { @@ -523,10 +541,7 @@ TitleUnit::TitleUnit(TitleMain *plugin, TitleEngine *server) static void get_mask_colors(int rgb, int color_model, int &rr, int &gg, int &bb) { int r = 0xff & (rgb>>16), g = 0xff & (rgb>>8), b = 0xff & (rgb>>0); - if( BC_CModels::is_yuv(color_model) ) { - bc_rgb2yuv(r,g,b, r,g,b); - bclamp(r,0,255); bclamp(g,0,255); bclamp(b,0,255); - } + if( BC_CModels::is_yuv(color_model) ) bc_rgb2yuv(r,g,b, r,g,b); rr = r; gg = g; bb = b; } @@ -1001,51 +1016,51 @@ LoadPackage* TitleTranslate::new_package() } TitleCurNudge::TitleCurNudge(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, 0) + : TitleStack(parser, 0) { } TitleCurColor::TitleCurColor(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, plugin->config.color) + : TitleStack(parser, plugin->config.color) { } TitleCurAlpha::TitleCurAlpha(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, plugin->config.alpha) + : TitleStack(parser, plugin->config.alpha) { } TitleCurSize::TitleCurSize(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, plugin->config.size) + : TitleStack(parser, plugin->config.size) { } TitleCurBold::TitleCurBold(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, (plugin->config.style & BC_FONT_BOLD) ? 1 : 0) + : TitleStack(parser, (plugin->config.style & BC_FONT_BOLD) ? 1 : 0) { } TitleCurItalic::TitleCurItalic(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, (plugin->config.style & BC_FONT_ITALIC) ? 1 : 0) + : TitleStack(parser, (plugin->config.style & BC_FONT_ITALIC) ? 1 : 0) { } TitleCurFont::TitleCurFont(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, plugin->config_font()) + : TitleStack(parser, plugin->config_font()) { } TitleCurCaps::TitleCurCaps(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, 0) + : TitleStack(parser, 0) { } TitleCurUnder::TitleCurUnder(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, 0) + : TitleStack(parser, 0) { } TitleCurBlink::TitleCurBlink(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, 0) + : TitleStack(parser, 0) { } TitleCurFixed::TitleCurFixed(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, 0) + : TitleStack(parser, 0) { } TitleCurSuper::TitleCurSuper(TitleParser *parser, TitleMain *plugin) - : TitleStack(parser, 0) + : TitleStack(parser, 0) { } @@ -1150,6 +1165,7 @@ void TitleMain::build_previews(TitleWindow *gui) const char *test_string = "Aa"; char new_path[BCTEXTLEN]; int text_height = gui->get_text_height(LARGEFONT); + int max_height = 3*text_height/2, max_width = 2 * max_height; int text_color = BC_WindowBase::get_resources()->default_text_color; int r = (text_color >> 16) & 0xff; int g = (text_color >> 8) & 0xff; @@ -1180,9 +1196,7 @@ void TitleMain::build_previews(TitleWindow *gui) } if( skip ) continue; - - int current_x = 0, current_w = 0, current_h = 0, current_ascent = 0; - if( pass == 1 ) { + if( pass > 0 ) { font->image = new VFrame; font->image->set_use_shm(0); font->image->reallocate(0, -1, 0, 0, 0, @@ -1190,7 +1204,10 @@ void TitleMain::build_previews(TitleWindow *gui) font->image->clear_frame(); } + int current_w = 1, current_h = 1; + int current_x = 0, current_ascent = 0; int len = strlen(test_string); + for( int j=0; jglyph->bitmap.width; + int glyph_h = freetype_face->glyph->bitmap.rows; + if( glyph_h > max_height ) glyph_h = max_height; + int glyph_a = freetype_face->glyph->advance.x >> 6; + int glyph_t = freetype_face->glyph->bitmap_top; if( pass == 0 ) { - current_w = current_x + freetype_face->glyph->bitmap.width; - if( (int)freetype_face->glyph->bitmap_top > current_ascent ) - current_ascent = freetype_face->glyph->bitmap_top; - if( (int)freetype_face->glyph->bitmap.rows > total_h ) - total_h = freetype_face->glyph->bitmap.rows; - if( (int)freetype_face->glyph->bitmap.rows > current_h ) - current_h = freetype_face->glyph->bitmap.rows; + current_w = current_x + glyph_w; + if( current_w > max_width ) current_w = max_width; + if( total_w < current_w ) total_w = current_w; + if( current_ascent < glyph_t ) current_ascent = glyph_t; + if( current_h < glyph_h ) current_h = glyph_h; + if( total_h < glyph_h ) total_h = glyph_h; } else { // copy 1 row at a time, center vertically - int out_y = (total_h - height[font_number]) / 2 + - ascent[font_number] - freetype_face->glyph->bitmap_top; - for( int in_y = 0; - in_y < (int)freetype_face->glyph->bitmap.rows && out_y < total_h; - ++in_y, ++out_y ) { - unsigned char *out_row = font->image->get_rows()[out_y] + - current_x * 4; + int out_y = (total_h-height[font_number])/2 + ascent[font_number]-glyph_t; + if( out_y < 0 ) out_y = 0; + for( int in_y = 0; in_y < glyph_h && out_y < total_h; ++in_y, ++out_y ) { unsigned char *in_row = freetype_face->glyph->bitmap.buffer + freetype_face->glyph->bitmap.pitch * in_y; + int out_x = current_x; + unsigned char *out_row = font->image->get_rows()[out_y] + + out_x * 4; - for( int out_x = 0; - out_x < (int)freetype_face->glyph->bitmap.width && out_x < total_w; - ++out_x ) { + for( int in_x = 0; in_x < glyph_w && out_x < total_w; ++in_x, ++out_x ) { *out_row = (*in_row * r + (0xff - *in_row) * *out_row) / 0xff; ++out_row; *out_row = (*in_row * g + @@ -1236,13 +1254,11 @@ void TitleMain::build_previews(TitleWindow *gui) in_row++; } } - current_x += freetype_face->glyph->advance.x >> 6; } + current_x += glyph_a; } - height[font_number] = current_h; ascent[font_number] = current_ascent; - if( pass == 0 && current_w > total_w ) total_w = current_w; } } @@ -1460,36 +1476,43 @@ void TitleMain::draw_background() BC_FontEntry* TitleMain::get_font(const char *font_name, int style) { - int flavor = + if( !strcmp("fixed", font_name) ) + font_name = FIXED_FONT; + 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 = 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; @@ -1505,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) { @@ -1540,10 +1578,11 @@ int TitleMain::get_width(TitleGlyph *cur, TitleGlyph *nxt) int result = cur->advance_x; if( !nxt ) return result; FT_Vector kerning; - FT_Get_Kerning(freetype_face, - cur->freetype_index, nxt->freetype_index, - ft_kerning_default, &kerning); - return result + (kerning.x >> 6); + if( !FT_Get_Kerning(freetype_face, + cur->freetype_index, nxt->freetype_index, + ft_kerning_default, &kerning) ) + result += (kerning.x >> 6); + return result; } @@ -1633,7 +1672,7 @@ int TitleCurSize::set(const char *txt) } if( *txt || size <= 0 || size > 2048 ) return 1; int style = parser->cur_font.style(); - if( parser->cur_font.set(0,style) ) return 1; + if( !parser->cur_font.set(0,style) ) return 1; push(size); return 0; } @@ -1654,7 +1693,7 @@ int TitleCurBold::set(const char *txt) int style = parser->cur_font.style(); if( bold ) style |= BC_FONT_BOLD; else style &= ~BC_FONT_BOLD; - if( parser->cur_font.set(0,style) ) return 1; + if( !parser->cur_font.set(0,style) ) return 1; push(bold); return 0; } @@ -1674,7 +1713,7 @@ int TitleCurItalic::set(const char *txt) int style = parser->cur_font.style(); if( italic ) style |= BC_FONT_ITALIC; else style &= ~BC_FONT_ITALIC; - if( parser->cur_font.set(0,style) ) return 1; + if( !parser->cur_font.set(0,style) ) return 1; push(italic); return 0; } @@ -1700,16 +1739,16 @@ BC_FontEntry* TitleCurFont::get(const char *txt, int style) else if( !*txt ) txt = parser->plugin->config.font; return parser->plugin->get_font(txt, style); } -int TitleCurFont::set(const char *txt, int style) +BC_FontEntry *TitleCurFont::set(const char *txt, int style) { BC_FontEntry *font = get(txt, style); - if( !font || parser->plugin->load_font(font) ) return 1; + if( !font || parser->plugin->load_font(font) ) return 0; if( !txt ) (BC_FontEntry*&)*this = font; - return 0; + return font; } int TitleCurFont::set(const char *txt) { - BC_FontEntry *font = get(txt, style()); + BC_FontEntry *font = set(txt, style()); if( !font ) return 1; push(font); return 0; @@ -1773,21 +1812,22 @@ 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; } + void TitleMain::load_glyphs() { // Build table of all glyphs needed @@ -1797,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 ) { - 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 ) @@ -1902,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; @@ -1937,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); @@ -2051,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; @@ -2266,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; @@ -2302,11 +2342,11 @@ void TitleMain::draw_overlay() const char* TitleMain::motion_to_text(int motion) { switch( motion ) { - case NO_MOTION: return _("No motion"); break; - case BOTTOM_TO_TOP: return _("Bottom to top"); break; - case TOP_TO_BOTTOM: return _("Top to bottom"); break; - case RIGHT_TO_LEFT: return _("Right to left"); break; - case LEFT_TO_RIGHT: return _("Left to right"); break; + case NO_MOTION: return _("No motion"); + case BOTTOM_TO_TOP: return _("Bottom to top"); + case TOP_TO_BOTTOM: return _("Top to bottom"); + case RIGHT_TO_LEFT: return _("Right to left"); + case LEFT_TO_RIGHT: return _("Left to right"); } return _("Unknown"); } @@ -2634,3 +2674,26 @@ void TitleMain::read_data(KeyFrame *keyframe) } } +void TitleMain::insert_text(const wchar_t *wtxt, int pos) +{ + 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+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] = wtxt[j]; + } + + if( (wlen+=len) > wsize ) wlen = wsize; + wtext[wlen] = 0; + config.wlen = wlen; +} +