void load_framedraw_image(LiVESPixbuf *pixbuf) { // this is for the single frame framedraw widget // it should be called whenever mainw->framedraw_bitmap changes weed_timecode_t tc; if (mainw->framedraw_frame>cfile->frames) mainw->framedraw_frame=cfile->frames; if (pixbuf==NULL) { const char *img_ext=get_image_ext_for_type(cfile->img_type); // can happen if we preview for rendered generators if ((mainw->multitrack==NULL||mainw->current_file!=mainw->multitrack->render_file)&&mainw->framedraw_frame==0) return; tc=((mainw->framedraw_frame-1.))/cfile->fps*U_SECL; pixbuf=pull_lives_pixbuf_at_size(mainw->current_file,mainw->framedraw_frame,img_ext,tc, (double)cfile->hsize,(double)cfile->vsize, LIVES_INTERP_BEST); } if (pixbuf!=NULL) { if (mainw->fd_layer_orig!=NULL) { weed_layer_free(mainw->fd_layer_orig); } mainw->fd_layer_orig=weed_layer_new(0,0,NULL,WEED_PALETTE_END); if (!pixbuf_to_layer(mainw->fd_layer_orig,pixbuf)) lives_object_unref(pixbuf); } if (mainw->fd_layer!=NULL) weed_layer_free(mainw->fd_layer); mainw->fd_layer=NULL; }
void load_framedraw_image(LiVESPixbuf *pixbuf) { // this is for the single frame framedraw widget // it should be called whenever mainw->framedraw_bitmap changes weed_timecode_t tc; boolean needs_unlock=FALSE; if (mainw->framedraw_frame>cfile->frames) mainw->framedraw_frame=cfile->frames; if (pixbuf==NULL) { const char *img_ext=get_image_ext_for_type(cfile->img_type); // can happen if we preview for rendered generators if ((mainw->multitrack==NULL||mainw->current_file!=mainw->multitrack->render_file)&&mainw->framedraw_frame==0) return; tc=((mainw->framedraw_frame-1.))/cfile->fps*U_SECL; pixbuf=pull_lives_pixbuf_at_size(mainw->current_file,mainw->framedraw_frame,img_ext,tc, (double)cfile->hsize,(double)cfile->vsize, LIVES_INTERP_BEST); } if (pixbuf!=NULL) { if (mainw->fd_layer_orig!=NULL) { weed_layer_free(mainw->fd_layer_orig); } mainw->fd_layer_orig=weed_layer_new(0,0,NULL,WEED_PALETTE_END); if (pixbuf_to_layer(mainw->fd_layer_orig,pixbuf)) { mainw->do_not_free=(livespointer)lives_pixbuf_get_pixels_readonly(pixbuf); // might be threaded here so we need a mutex to stop other thread resetting free_fn pthread_mutex_lock(&mainw->free_fn_mutex); needs_unlock=TRUE; mainw->free_fn=_lives_free_with_check; } lives_object_unref(pixbuf); mainw->do_not_free=NULL; mainw->free_fn=_lives_free_normal; if (needs_unlock) pthread_mutex_unlock(&mainw->free_fn_mutex); } if (mainw->fd_layer!=NULL) weed_layer_free(mainw->fd_layer); mainw->fd_layer=NULL; }
void framedraw_redraw(lives_special_framedraw_rect_t *framedraw, boolean reload, LiVESPixbuf *pixbuf) { // this will draw the mask (framedraw_bitmap) and optionally reload the image // and then combine them int fd_height; int fd_width; int width,height; double xstartf,ystartf,xendf,yendf; lives_painter_t *cr; if (mainw->current_file<1||cfile==NULL) return; if (framedraw->rfx->source_type==LIVES_RFX_SOURCE_RFX) if (noupdate) return; fd_width=lives_widget_get_allocation_width(mainw->framedraw); fd_height=lives_widget_get_allocation_height(mainw->framedraw); width=cfile->hsize; height=cfile->vsize; calc_maxspect(fd_width,fd_height,&width,&height); // copy from orig, resize // copy orig layer to layer if (mainw->fd_layer!=NULL) { weed_layer_free(mainw->fd_layer); mainw->fd_layer=NULL; } if (reload||mainw->fd_layer_orig==NULL) load_framedraw_image(pixbuf); mainw->fd_layer=weed_layer_copy(NULL,mainw->fd_layer_orig); // resize to correct size resize_layer(mainw->fd_layer, width, height, LIVES_INTERP_BEST, WEED_PALETTE_END, 0); cr=layer_to_lives_painter(mainw->fd_layer); // draw on the lives_painter // her we dont offset because we are drawing in the pixbuf, not the widget switch (framedraw->type) { case LIVES_PARAM_SPECIAL_TYPE_RECT_MULTRECT: // deprecated // scale values if (framedraw->xstart_param->dp==0) { xstartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf/(double)cfile->hsize*(double)width; } else { xstartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf*(double)width; } if (framedraw->xend_param->dp==0) { xendf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf/(double)cfile->hsize*(double)width; } else { xendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf*(double)width; } if (framedraw->ystart_param->dp==0) { ystartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf/(double)cfile->vsize*(double)height; } else { ystartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf*(double)height; } if (framedraw->yend_param->dp==0) { yendf=lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf/(double)cfile->vsize*(double)height; } else { yendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf*(double)height; } lives_painter_set_source_rgb(cr, 1., 0., 0.); lives_painter_rectangle(cr,xstartf-1.,ystartf-1.,xendf+2.,yendf+2.); lives_painter_stroke(cr); break; case LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT: case LIVES_PARAM_SPECIAL_TYPE_RECT_DEMASK: if (framedraw->xstart_param->dp==0) { xstartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf/(double)cfile->hsize*(double)width; } else { xstartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf*(double)width; } if (framedraw->xend_param->dp==0) { xendf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf/(double)cfile->hsize*(double)width; } else { xendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xend_param->widgets[0])); xendf=xendf*(double)width; } if (framedraw->ystart_param->dp==0) { ystartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf/(double)cfile->vsize*(double)height; } else { ystartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf*(double)height; } if (framedraw->yend_param->dp==0) { yendf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf/(double)cfile->vsize*(double)height; } else { yendf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->yend_param->widgets[0])); yendf=yendf*(double)height; } if (b1_held||framedraw->type==LIVES_PARAM_SPECIAL_TYPE_RECT_MULTIRECT) { lives_painter_set_source_rgb(cr, 1., 0., 0.); lives_painter_rectangle(cr,xstartf-1.,ystartf-1.,xendf-xstartf+2.,yendf-ystartf+2.); lives_painter_stroke(cr); } else { if (!b1_held) { // create a mask which is only opaque within the clipping area lives_painter_rectangle(cr,0,0,width,height); lives_painter_rectangle(cr,xstartf,ystartf,xendf-xstartf+1.,yendf-ystartf+1.); lives_painter_set_operator(cr, LIVES_PAINTER_OPERATOR_DEST_OUT); lives_painter_set_source_rgba(cr, .0, .0, .0, .5); lives_painter_set_fill_rule(cr, LIVES_PAINTER_FILL_RULE_EVEN_ODD); lives_painter_fill(cr); } } break; case LIVES_PARAM_SPECIAL_TYPE_SINGLEPOINT: if (framedraw->xstart_param->dp==0) { xstartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf/(double)cfile->hsize*(double)width; } else { xstartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->xstart_param->widgets[0])); xstartf=xstartf*(double)width; } if (framedraw->ystart_param->dp==0) { ystartf=(double)lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf/(double)cfile->vsize*(double)height; } else { ystartf=lives_spin_button_get_value(LIVES_SPIN_BUTTON(framedraw->ystart_param->widgets[0])); ystartf=ystartf*(double)height; } lives_painter_set_source_rgb(cr, 1., 0., 0.); lives_painter_move_to(cr,xstartf,ystartf-3); lives_painter_line_to(cr,xstartf,ystartf+3); lives_painter_stroke(cr); lives_painter_move_to(cr,xstartf-3,ystartf); lives_painter_line_to(cr,xstartf+3,ystartf); lives_painter_stroke(cr); break; default: break; } lives_painter_to_layer(cr, mainw->fd_layer); lives_painter_destroy(cr); redraw_framedraw_image(); }