titler font fixups, debian i386 build
[goodguy/history.git] / cinelerra-5.1 / plugins / titler / titler.C
index bdde6b47cd32a651dac4c75eac90ac48d7436358..a90731dd963d03654005b1bbd415f064258c83c4 100644 (file)
@@ -64,6 +64,7 @@
 #include <sys/stat.h>
 #include <fontconfig/fontconfig.h>
 
+#define FIXED_FONT "Bitstream Vera Sans Mono (Bits)"
 #define SMALL (1.0 / 64.0)
 
 #define MAX_FLT  3.40282347e+38
@@ -108,7 +109,7 @@ TitleConfig::TitleConfig()
        strcpy(background_path, "");
 
        outline_size = 0;
-       window_w = 720;
+       window_w = 800;
        window_h = 460;
        next_keyframe_position = 0;
        prev_keyframe_position = 0;
@@ -523,10 +524,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 +999,51 @@ LoadPackage* TitleTranslate::new_package()
 }
 
 TitleCurNudge::TitleCurNudge(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, 0)
+ : TitleStack<int>(parser, 0)
 {
 }
 TitleCurColor::TitleCurColor(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, plugin->config.color)
+ : TitleStack<int>(parser, plugin->config.color)
 {
 }
 TitleCurAlpha::TitleCurAlpha(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, plugin->config.alpha)
+ : TitleStack<int>(parser, plugin->config.alpha)
 {
 }
 TitleCurSize::TitleCurSize(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, plugin->config.size)
+ : TitleStack<float>(parser, plugin->config.size)
 {
 }
 TitleCurBold::TitleCurBold(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, (plugin->config.style & BC_FONT_BOLD) ? 1 : 0)
+ : TitleStack<int>(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<int>(parser, (plugin->config.style & BC_FONT_ITALIC) ? 1 : 0)
 {
 }
 TitleCurFont::TitleCurFont(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, plugin->config_font())
+ : TitleStack<BC_FontEntry*>(parser, plugin->config_font())
 {
 }
 TitleCurCaps::TitleCurCaps(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, 0)
+ : TitleStack<int>(parser, 0)
 {
 }
 TitleCurUnder::TitleCurUnder(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, 0)
+ : TitleStack<int>(parser, 0)
 {
 }
 TitleCurBlink::TitleCurBlink(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, 0)
+ : TitleStack<float>(parser, 0)
 {
 }
 TitleCurFixed::TitleCurFixed(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, 0)
+ : TitleStack<int>(parser, 0)
 {
 }
 TitleCurSuper::TitleCurSuper(TitleParser *parser, TitleMain *plugin)
- : TitleStack(parser, 0)
+ : TitleStack<int>(parser, 0)
 {
 }
 
@@ -1150,6 +1148,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 +1179,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 +1187,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; j<len; ++j ) {
                                FT_ULong c = test_string[j];
 // memory leaks here are fatal
@@ -1202,30 +1202,31 @@ void TitleMain::build_previews(TitleWindow *gui)
                                if( load_freetype_face(freetype_library, freetype_face, new_path)) continue;
                                FT_Set_Pixel_Sizes(freetype_face, text_height, 0);
                                if( FT_Load_Char(freetype_face, c, FT_LOAD_RENDER) ) continue;
+                               int glyph_w = freetype_face->glyph->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 +1237,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,6 +1459,8 @@ void TitleMain::draw_background()
 
 BC_FontEntry* TitleMain::get_font(const char *font_name, int style)
 {
+       if( !strcmp("fixed", font_name) )
+               font_name = FIXED_FONT;
        int flavor =
            ((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 |
@@ -1475,7 +1476,8 @@ BC_FontEntry* TitleMain::get_font(const char *font_name, int style)
 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) )
+               font = get_font(FIXED_FONT,0);
        return font;
 }
 
@@ -1540,10 +1542,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 +1636,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 +1657,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 +1677,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 +1703,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;
@@ -1788,6 +1791,7 @@ int TitleParser::set_attributes(int ret)
        return 1;
 }
 
+
 void TitleMain::load_glyphs()
 {
 // Build table of all glyphs needed
@@ -1826,7 +1830,7 @@ void TitleMain::load_glyphs()
                                }
                        }
 
-                       if( !exists ) {
+                       if( !exists && cur_font ) {
                                total_packages++;
                                TitleGlyph *glyph = new TitleGlyph;
                                glyph->char_code = (FT_ULong)wch;
@@ -2302,11 +2306,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 +2638,26 @@ void TitleMain::read_data(KeyFrame *keyframe)
        }
 }
 
+void TitleMain::insert_text(const char *txt, int pos)
+{
+       int ilen = strlen(txt);
+       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 ) {
+               if( j >= wsize ) continue;
+               wtext[j] = wtext[i];
+       }
+       for( int i=pos, j=0; j<ilen; ++i,++j ) {
+               if( i >= wsize ) break;
+               wtext[i] = txt[j];
+       }
+
+       if( (wlen+=ilen) > wsize ) wlen = wsize;
+       wtext[wlen] = 0;
+       config.wlen = wlen;
+}
+