fix default color btn in set title bar color, fix bar color fast path, tweaks to...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / resourcepixmap.C
index e70c5fcd5b0676c6848e25f87709ee2ded5dbc9c..b0bc49b7ffbf5020ce8764ac5024ff1ddccbe763 100644 (file)
@@ -194,16 +194,13 @@ void ResourcePixmap::draw_data(TrackCanvas *canvas,
        refresh_w = pixmap_w;
 
 // Draw background image
-       if( refresh_w > 0 )
-               mwindow->theme->draw_resource_bg(canvas,
-                       this,
-                       edit_x,
-                       edit_w,
-                       pixmap_x,
-                       refresh_x,
-                       y,
-                       refresh_x + refresh_w,
-                       mwindow->edl->local_session->zoom_track + y);
+       if( refresh_w > 0 ) {
+               int x1 = refresh_x, x2 = x1 + refresh_w;
+               int y1 = y, y2 = y1 + mwindow->edl->local_session->zoom_track;
+               int color = mwindow->get_title_color(edit);
+               mwindow->theme->draw_resource_bg(canvas, this, color,
+                       edit_x, edit_w, pixmap_x, x1,y1, x2,y2);
+       }
 //printf("ResourcePixmap::draw_data 70\n");
 
 
@@ -214,28 +211,18 @@ void ResourcePixmap::draw_data(TrackCanvas *canvas,
                {
                        case TRACK_AUDIO:
                                draw_audio_resource(canvas,
-                                       edit,
-                                       refresh_x,
-                                       refresh_w);
+                                       edit, refresh_x, refresh_w);
                                break;
 
                        case TRACK_VIDEO:
-                               draw_video_resource(canvas,
-                                       edit,
-                                       edit_x,
-                                       edit_w,
-                                       pixmap_x,
-                                       pixmap_w,
-                                       refresh_x,
-                                       refresh_w,
+                               draw_video_resource(canvas, edit, edit_x, edit_w,
+                                       pixmap_x, pixmap_w, refresh_x, refresh_w,
                                        mode);
                                break;
 
                        case TRACK_SUBTITLE:
-                               draw_subttl_resource(canvas,
-                                       edit,
-                                       refresh_x,
-                                       refresh_w);
+                               draw_subttl_resource(canvas, edit,
+                                       refresh_x, refresh_w);
                                break;
                }
        }
@@ -243,31 +230,91 @@ SET_TRACE
 }
 
 
-VFrame *ResourcePixmap::change_title_color(VFrame *title_bg, int color, int bg_color)
+VFrame *ResourcePixmap::change_title_color(VFrame *title_bg, int color)
 {
-       if( color < 0 || color == bg_color ) return title_bg;
        int colormodel = title_bg->get_color_model();
        int bpp = BC_CModels::calculate_pixelsize(colormodel);
-       int tw = title_bg->get_w(), th = title_bg->get_h();
+       int tw = title_bg->get_w(), tw1 = tw-1, th = title_bg->get_h();
        VFrame *title_bar = new VFrame(tw, th, colormodel);
-       uint8_t br = (bg_color>>16), cr = (color>>16);
-       uint8_t bg = (bg_color>>8),  cg = (color>>8);
-       uint8_t bb = (bg_color>>0),  cb = (color>>0);
-       int dr = cr-br, dg = cg-bg, db = cb-bb;
        uint8_t **bar_rows = title_bar->get_rows();
-       uint8_t **rows = title_bg->get_rows();
-       for( int y=0; y<th; ++y ) {
-               uint8_t *bp = rows[y], *cp = bar_rows[y];
-               for( int x=0; x<tw; ++x ) {
-                       *cp++ = *bp++ + dr;
-                       *cp++ = *bp++ + dg;
-                       *cp++ = *bp++ + db;
-                       if( bpp > 3 ) *cp++ = *bp++;
+       const uint8_t gap_grey = 0x4a;
+       union { unsigned rgba; struct { uint8_t r,g,b,a; }; } c;
+       c.r = color>>16;  c.g = color>>8;  c.b = color>>0;  c.a = 0xff;
+       if( BC_CModels::has_alpha(colormodel) && // fast path
+           BC_CModels::calculate_pixelsize(colormodel) == sizeof(unsigned) ) {
+               const unsigned gap_rgba = (0xff<<24) |
+                       (gap_grey<<16) | (gap_grey<<8) | (gap_grey<<0);
+               if( th > 0 ) {
+                       unsigned *bp = (unsigned *)bar_rows[0];
+                       for( int i=tw; --i>=0; ) *bp++ = gap_rgba;
+               }
+               for( int y=1; y<th; ++y ) {
+                       unsigned *bp = (unsigned *)bar_rows[y];
+                       if( tw > 0 ) *bp++ = gap_rgba;
+                       for( int i=tw1; --i>0; ++bp ) *bp = c.rgba;
+                       if( tw > 1 ) *bp = gap_rgba;
+               }
+       }
+       else {
+               if( th > 0 ) {
+                       uint8_t *cp = bar_rows[0];
+                       for( int x=0; x<tw; ++x ) {
+                               cp[0] = cp[1] = cp[2] = gap_grey;
+                               if( bpp > 3 ) cp[3] = 0xff;
+                               cp += bpp;
+                       }
+               }
+               for( int y=1; y<th; ++y ) {
+                       uint8_t *cp = bar_rows[y];
+                       if( tw > 0 ) {
+                               cp[0] = cp[1] = cp[2] = gap_grey;
+                               if( bpp > 3 ) cp[3] = 0xff;
+                               cp += bpp;
+                       }
+                       for( int x=1; x<tw1; ++x ) {
+                               cp[0] = c.r; cp[1] = c.g; cp[2] = c.b;
+                               if( bpp > 3 ) cp[3] = 0xff;
+                               cp += bpp;
+                       }
+                       if( tw > 1 ) {
+                               cp[0] = cp[1] = cp[2] = gap_grey;
+                               if( bpp > 3 ) cp[3] = 0xff;
+                       }
                }
        }
        return title_bar;
 }
 
+VFrame *ResourcePixmap::change_picon_alpha(VFrame *picon_frame, int alpha)
+{
+       uint8_t **picon_rows = picon_frame->get_rows();
+       int pw = picon_frame->get_w(), ph = picon_frame->get_h();
+       int color_model = picon_frame->get_color_model();
+       int bpp = BC_CModels::calculate_pixelsize(color_model);
+       VFrame *frame = new VFrame(pw, ph, BC_RGBA8888);
+       uint8_t **rows = frame->get_rows();
+       if( BC_CModels::has_alpha(color_model) && // fast path
+           BC_CModels::calculate_pixelsize(color_model) == sizeof(unsigned) ) {
+               unsigned a = alpha << 24;
+               for( int y=0; y<ph; ++y ) {
+                       unsigned *bp = (unsigned *)picon_rows[y];
+                       unsigned *rp = (unsigned *)rows[y];
+                       for( int i=pw; --i>=0; ++bp,++rp ) *rp = (*bp & 0xffffff) | a;
+               }
+       }
+       else {
+               for( int y=0; y<ph; ++y ) {
+                       uint8_t *bp = picon_rows[y], *rp = rows[y];
+                       for( int x=0; x<pw; ++x ) {
+                               rp[0] = bp[0];  rp[1] = bp[1];
+                               rp[2] = bp[2];  bp += bpp;
+                               rp[3] = alpha;  rp += 4;
+                       }
+               }
+       }
+       return frame;
+}
+
 void ResourcePixmap::draw_title(TrackCanvas *canvas,
        Edit *edit, int64_t edit_x, int64_t edit_w,
        int64_t pixmap_x, int64_t pixmap_w)
@@ -275,38 +322,31 @@ void ResourcePixmap::draw_title(TrackCanvas *canvas,
 // coords relative to pixmap
        int64_t total_x = edit_x - pixmap_x, total_w = edit_w;
        int64_t x = total_x, w = total_w;
-       int left_margin = 10;
+       int left_margin = xS(10);
 
        if( x < 0 ) { w -= -x; x = 0; }
        if( w > pixmap_w ) w -= w - pixmap_w;
 
        VFrame *title_bg = mwindow->theme->get_image("title_bg_data");
-       VFrame *title_bar = title_bg;
-       int color = mwindow->get_title_color(edit), bg_color = -1;
-       if( color >= 0 ) {
-               bg_color = mwindow->theme->get_color_title_bg();
-               if( bg_color == color ) color = -1;
-       }
-       if( color >= 0 && color != bg_color )
-               title_bar = change_title_color(title_bg, color, bg_color);
+       int color = mwindow->get_title_color(edit);
+       VFrame *title_bar = !color ? title_bg :
+               change_title_color(title_bg, color);
        canvas->draw_3segmenth(x, 0, w, total_x, total_w, title_bar, this);
        if( title_bar != title_bg ) delete title_bar;
 
-//     if( total_x > -BC_INFINITY ) {
-               char title[BCTEXTLEN];
-               edit->get_title(title);
-               canvas->set_color(mwindow->theme->title_color);
-               canvas->set_font(mwindow->theme->title_font);
+       char title[BCTEXTLEN];
+       edit->get_title(title);
+       canvas->set_color(mwindow->theme->title_color);
+       canvas->set_font(mwindow->theme->title_font);
 
 // Justify the text on the left boundary of the edit if it is visible.
 // Otherwise justify it on the left side of the screen.
-               int text_x = total_x + left_margin;
-               text_x = MAX(left_margin, text_x);
+       int text_x = total_x + left_margin;
+       text_x = MAX(left_margin, text_x);
 //printf("ResourcePixmap::draw_title 1 %d\n", text_x);
-               canvas->draw_text(text_x,
-                       canvas->get_text_ascent(mwindow->theme->title_font) + 2,
-                       title, strlen(title), this);
-//     }
+       canvas->draw_text(text_x, // 2,
+               canvas->get_text_ascent(mwindow->theme->title_font) + yS(2),
+               title, strlen(title), this);
 }
 
 
@@ -324,7 +364,6 @@ SET_TRACE
        IndexState *index_state = indexable->index_state;
        double asset_over_session = (double)indexable->get_sample_rate() /
                mwindow->edl->session->sample_rate;
-
 // Develop strategy for drawing
 // printf("ResourcePixmap::draw_audio_resource %d %p %d\n",
 // __LINE__,
@@ -334,50 +373,57 @@ SET_TRACE
        {
                case INDEX_NOTTESTED:
                        return;
-                       break;
 // Disabled.  All files have an index.
 //             case INDEX_TOOSMALL:
 //                     draw_audio_source(canvas, edit, x, w);
 //                     break;
                case INDEX_BUILDING:
-               case INDEX_READY:
-               {
+               case INDEX_READY: {
                        IndexFile indexfile(mwindow, indexable);
                        if( !indexfile.open_index() ) {
                                if( index_state->index_zoom >
-                                               mwindow->edl->local_session->zoom_sample *
+                                       mwindow->edl->local_session->zoom_sample *
                                                asset_over_session ) {
-//printf("ResourcePixmap::draw_audio_resource %d\n", __LINE__);
-
                                        draw_audio_source(canvas, edit, x, w);
                                }
                                else {
-//printf("ResourcePixmap::draw_audio_resource %d\n", __LINE__);
-                                       indexfile.draw_index(canvas,
-                                               this,
-                                               edit,
-                                               x,
-                                               w);
-SET_TRACE
+                                       indexfile.draw_index(canvas, this, edit, x, w);
                                }
-
                                indexfile.close_index();
-SET_TRACE
                        }
                        break;
                }
        }
+       if( !mwindow->preferences->rectify_audio ) {
+               int center_pixel = calculate_center_pixel(edit->track);
+               canvas->set_line_dashes(1);
+               canvas->set_color(mwindow->theme->zero_crossing_color);
+               canvas->draw_line(x, center_pixel, x + w, center_pixel, this);
+               canvas->set_line_dashes(0);
+       }
 }
 
 
+int ResourcePixmap::calculate_center_pixel(Track *track)
+{
+       int rect_audio = mwindow->preferences->rectify_audio;
+       int center_pixel = !rect_audio ?
+               mwindow->edl->local_session->zoom_track / 2 :
+               mwindow->edl->local_session->zoom_track ;
+       if( track->show_titles() )
+               center_pixel += mwindow->theme->get_image("title_bg_data")->get_h();
+       return center_pixel;
+}
+
 void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, int w)
 {
        w++;
        Indexable *indexable = edit->get_source();
-       int center_pixel = mwindow->edl->local_session->zoom_track / 2;
-       if( edit->track->show_titles() )
-               center_pixel += mwindow->theme->get_image("title_bg_data")->get_h();
-       int64_t scale_y = mwindow->edl->local_session->zoom_y;
+       int center_pixel = calculate_center_pixel(edit->track);
+       int rect_audio = mwindow->preferences->rectify_audio;
+       int64_t scale_y = !rect_audio ?
+               mwindow->edl->local_session->zoom_y :
+               mwindow->edl->local_session->zoom_y * 2;
        int y_max = center_pixel + scale_y / 2 - 1;
 
        double project_zoom = mwindow->edl->local_session->zoom_sample;
@@ -458,11 +504,12 @@ void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, i
 
                if( !result ) {
                        double *samples = buffer->get_data();
-                       int y1 = center_pixel - samples[0] * scale_y / 2;
+                       double sample = !rect_audio ? samples[0] : fabs(samples[0]);
+                       int y1 = center_pixel - sample * scale_y / 2;
                        int y2 = CLIP(y1, 0, y_max);
 
-                       for( int x0=0; x0<w; ++x0 ) {
-                               int x1 = x0 + x, x2 = x1 + 1;
+                       for( int x1=x; x1<w; ++x1 ) {
+                               int x2 = x1 + 1;
                                edit_position = (x1 + pixmap_x - edit_x) * project_zoom;
                                int64_t speed_position = edit->startsource;
                                speed_position += !speed_autos ? edit_position :
@@ -471,10 +518,14 @@ void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, i
                                int j = speed_position * asset_over_session - start_position;
                                CLAMP(j, 0, sample_size);
                                int y0 = y2;
-                               y1 = center_pixel - samples[j] * scale_y / 2;
+                               sample = !rect_audio ? samples[j] : fabs(samples[j]);
+                               y1 = center_pixel - sample * scale_y / 2;
                                y2 = CLIP(y1, 0, y_max);
 //printf("ResourcePixmap::draw_audio_source %d %d %d\n", __LINE__, y1, y2);
-                               canvas->draw_line(x0, y0, x2, y2, this);
+                               if( !rect_audio )
+                                       canvas->draw_line(x1, y0, x2, y2, this);
+                               else
+                                       canvas->draw_line(x2, center_pixel, x2, y2, this);
                        }
                }
 
@@ -506,10 +557,12 @@ void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, i
                        WaveCacheItem *item = mwindow->wave_cache->get_wave(indexable->id,
                                        edit->channel, prev_position, next_position);
                        if( item ) {
+                               double item_low = !rect_audio ? item->low : fabs(item->low);
 //printf("ResourcePixmap::draw_audio_source %d\n", __LINE__);
-                               int y_lo = (int)(center_pixel - item->low * scale_y / 2);
+                               int y_lo = (int)(center_pixel - item_low * scale_y / 2);
                                int y1 = CLIP(y_lo, 0, y_max);
-                               int y_hi = (int)(center_pixel - item->high * scale_y / 2);
+                               double item_high = !rect_audio ? item->high : fabs(item->high);
+                               int y_hi = (int)(center_pixel - item_high * scale_y / 2);
                                int y2 = CLIP(y_hi, 0, y_max);
                                if( !first_pixel ) {
                                        y_lo = MIN(y1,prev_y2);
@@ -520,7 +573,7 @@ void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, i
                                        y_lo = y1;  y_hi = y2;
                                }
                                prev_y1 = y1;  prev_y2 = y2;
-                               canvas->draw_line(x, y_lo, x, y_hi, this);
+                               canvas->draw_line(x, !rect_audio ? y_lo : center_pixel, x, y_hi, this);
 //printf("ResourcePixmap::draw_audio_source %d %d %d %d\n", __LINE__, x, y1, y2);
                                mwindow->wave_cache->unlock();
                        }
@@ -540,19 +593,23 @@ void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, i
 void ResourcePixmap::draw_wave(TrackCanvas *canvas,
        int x, double high, double low)
 {
-       int top_pixel = 0;
-       if( mwindow->edl->session->show_titles )
-               top_pixel += mwindow->theme->get_image("title_bg_data")->get_h();
-       int center_pixel = mwindow->edl->local_session->zoom_track / 2 + top_pixel;
+       int rect_audio = mwindow->preferences->rectify_audio;
+       if( rect_audio ) { low = fabs(low);  high = fabs(high); }
+       int top_pixel =  mwindow->edl->session->show_titles ? 0 :
+               mwindow->theme->get_image("title_bg_data")->get_h();
+       int center_pixel = !rect_audio ?
+               mwindow->edl->local_session->zoom_track / 2 + top_pixel :
+               mwindow->edl->local_session->zoom_track + top_pixel ;
+       int scale_y = !rect_audio ?
+               mwindow->edl->local_session->zoom_y / 2 :
+               mwindow->edl->local_session->zoom_y ;
        int bottom_pixel = top_pixel + mwindow->edl->local_session->zoom_track;
-       int y1 = (int)(center_pixel -
-               low * mwindow->edl->local_session->zoom_y / 2);
-       int y2 = (int)(center_pixel -
-               high * mwindow->edl->local_session->zoom_y / 2);
+       int y1 = (int)(center_pixel - low * scale_y);
+       int y2 = (int)(center_pixel - high * scale_y);
        CLAMP(y1, top_pixel, bottom_pixel);
        CLAMP(y2, top_pixel, bottom_pixel);
        canvas->set_color(mwindow->theme->audio_color);
-       canvas->draw_line(x, y1, x, y2, this);
+       canvas->draw_line(x, !rect_audio ? y1 : bottom_pixel, x, y2, this);
 }
 
 
@@ -602,8 +659,20 @@ void ResourcePixmap::draw_video_resource(TrackCanvas *canvas,
                        mwindow->frame_cache->get_frame_ptr(speed_position, edit->channel,
                                mwindow->edl->session->frame_rate, BC_RGB888,
                                picon_w, picon_h, indexable->id);
+               int bg_color = gui->get_bg_color();
                if( picon_frame ) {
-                       draw_vframe(picon_frame, x, y, picon_w, picon_h, 0, 0);
+                       VFrame *frame = picon_frame;
+                       int color = mwindow->get_title_color(edit);
+                       if( color ) {
+                               int alpha = (~color >> 24) & 0xff;
+                               frame = change_picon_alpha(picon_frame, alpha);
+                               gui->set_bg_color(color & 0xffffff);
+                       }
+                       draw_vframe(frame, x, y, picon_w, picon_h, 0, 0);
+                       if( frame != picon_frame ) {
+                               delete frame;
+                               gui->set_bg_color(bg_color);
+                       }
                        mwindow->frame_cache->unlock();
                }
                else if( mode != IGNORE_THREAD ) {
@@ -625,7 +694,7 @@ void ResourcePixmap::draw_subttl_resource(TrackCanvas *canvas, Edit *edit, int x
 {
        SEdit *sedit = (SEdit *)edit;
        char *text = sedit->get_text();
-       if( !*text || w < 10 ) return;
+       if( !*text || w < xS(10) ) return;
        int center_pixel = canvas->resource_h() / 2;
        if( edit->track->show_titles() )
                center_pixel += mwindow->theme->get_image("title_bg_data")->get_h();
@@ -639,7 +708,7 @@ void ResourcePixmap::draw_subttl_resource(TrackCanvas *canvas, Edit *edit, int x
        canvas->set_color(color);
        int ch = canvas->get_text_height(font);
        int hh = canvas->get_text_height(font,text) + ch/2;
-       int y1 = y_max - hh - 10;
+       int y1 = y_max - hh - yS(10);
        if( y1 < 0 ) y1 = 0;
        canvas->draw_text(x1, y1, text, -1, this);
 }