View Single Post
Old 06-20-2022, 05:12 AM   #4
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default

Hi again folks!

As my goal is to replace the stock overlay text preset, I couldn't not resist to leave out the time code. So here is version 3.1 that includes time code. I also added a fast shadow/outline mode (but low quality) to ease video editing process. For time code just insert "[tc]" or "[dftc]" (drop frame tc) anywhere in #text.



Code:
// Overlay: text w/adjustable ol/sh/rot/pos
// by papagirafe
// version 3.1, now includes rotation, relative positioning LMR TMB

// Write your own text inside quotes, multiple lines allowed inside quotes
// if empty, text = item/track name
// for time code, just insert "[tc]" anywhere, for dropframe version insert "[dftc]"
#text="";

// default font = "Arial" in Windows
#style.font=""; 
/*
  font styles from following list - upto 4 choices allowed - uppercase mandatory 
  'B' - Bold,   'I' - Italics,  'R' - smooth edges,
  'V' - Invert bg/fg, 'U' - underlined
  ugly "stock" shadow and outline styles still work if you insist on using them... 
*/
style.style='';   

// preset paramaters
//@param style.frs 'text height' 0.07 0.01 1.0 0.5 0.001
//@param hRef "x ref L/M/R" 0 -1 1 0 1
//@param vRef "y ref T/M/B" 0 -1 1 0 1
//@param tofx "x offset" 0 -1 1 0 0.001
//@param tofy "y offset" 0 -1 1 0 0.001
//@param rota rotation 0 -180 180 0 0.1
//@param style.fgr 'text r' 1 0 1 0.5 0.001
//@param style.fgg 'text g' 1 0 1 0.5 0.001
//@param style.fgb 'text b' 1 0 1 0.5 0.001
//@param style.fga 'text a' 1 -0.01 1 0.5 0.01
//@param style.bgw 'bg w' 0 0 1 1 0.001
//@param style.bgh 'bg h' -0.001 -0.001 1 0.5 0.001    negative? follow bg w!
//@param style.bgr 'bg r' 0 0 1 0.5 0.001
//@param style.bgg 'bg g' 0 0 1 0.5 0.001
//@param style.bgb 'bg b' 0 0 1 0.5 0.001
//@param style.bga 'bg a' 0.4 0 1 0.5 0.001
//@param style.olr 'outline r' 0 0 1 0.5 0.01
//@param style.olg 'outline g' 0 0 1 0.5 0.01
//@param style.olb 'outline b' 0 0 1 0.5 0.01
//@param style.ola 'outline a' 0.1 0.01 1 0.5 0.01
//@param style.olt 'outline thickness' 0 0 1 0.5 0.01
//@param style.shmode 'shadow mode' 0 0 1 0.5 1
//@param style.shangl 'shadow angle' 45 0 359 180 1
//@param HQMode "ol/sh Fast/HQ" 1 0 1 0.5 1

function gfx_img_alloc_alpha(w,h) 
(
  gfx_set(0,0,0,1,0,-1,0); // set black, transparent, clobber
  gfx_img_alloc(w,h,1); // allocate and clear image with above settings
);

function xy2polar(x,y,r*,phi*)(r=sqrt(x^2+y^2);phi=2*atan(y/(x+r)));
function polar2xy(r,phi,x*,y*)(x=r*cos(phi);y=r*sin(phi));
function rotate_coord(x*,y*,rota)(xy2polar(x,y,this.r,this.phi);polar2xy(this.r,this.phi-rota,x,y));
//calc size of reactangle that can contain all text + its rotation
function calc_rot_img_size(sw,sh,dw*,dh*,rot)
  local(xmax,ymax)
  instance(x,y)
(
  xmax=sw;ymax=sh;
  //top left corner
  x=-sw/2;y=-sh/2;rotate_coord(x,y,rot);
  xmax<2*abs(x)?xmax=2*abs(x);
  ymax<2*abs(y)?ymax=2*abs(y);
  //top right corner
  x=sw/2;y=-sh/2;rotate_coord(x,y,rot);
  xmax<2*abs(x)?xmax=2*abs(x);ymax<2*abs(y)?ymax=2*abs(y);
  dw=xmax;dh=ymax;
);

function time_code(df)
  local(t,f,period,ds)
(
  t = floor((project_time + project_timeoffs) * framerate + 0.0000001);
  f = ceil(framerate);
  df > 0.5 && f != framerate ? (
    period = floor(framerate * 600);
    ds = floor(framerate * 60);
    ds > 0 ? t += 18 * ((t / period)|0) + ((((t%period)-2)/ds)|0)*2;
  );
  sprintf(#this.tcs,"%02d:%02d:%02d:%02d",(t/(f*3600))|0,(t/(f*60))%60,(t/f)%60,t%f);
  #this.tcs;
);

//set the rest of the environment
colorspace='RGBA';
oldiv=HQMode?128:6;
rota=rota/180*$pi;
style.fga<0?style.fga=param_wet;
style.bga*=style.fga; //bg alpha dependent upon fg alpha
mode=0x10000|0x100; //use alpha & smoothing

//get text from all possible sources
strcmp(#text,"")==0 ? input_get_name(-1,#text):(
  matchi("%0s[tc]%0s",#text,#left,#right)?
    sprintf(#text,"%s%s%s",#left,time_code(0),#right) :(
      matchi("%0s[dftc]%0s",#text,#left,#right)?
        sprintf(#text,"%s%s%s",#left,time_code(1),#right);
    );
);

// get current input stats and force output to that size
input_info(0,sw,sh); project_w=sw;project_h=sh;
//calculate text stats, fsize=pix height of font
gfx_setfont(fsize=style.frs*min(sw,sh),#style.font,style.style);
gfx_str_measure(#text,tw,th);   

// calculate text background dimensions to parameters & outline/shadow extra space
style.bgw*=tw; 
style.bgh=style.bgh<0?style.bgw:style.bgh*=th; 
style.olt*=fsize/4;  // outline pix thickness
tbw=tw+2*style.bgw+2*style.olt;  //text bg pix width
tbh=th+2*style.bgh+2*style.olt;  //text bg pix height

//calc temporary img size compensated for rotation: (iw,ih) new temporary img dim
calc_rot_img_size(tbw,tbh,iw,ih,rota);

//ok, it's time to render to temporary image  
img=gfx_img_alloc_alpha(iw,ih);

//background if applicable
style.bga>0?(
  gfx_set(style.bgr,style.bgg,style.bgb,style.bga,mode,img);
  gfx_fillrect((iw-tbw)/2,(ih-tbh)/2,tbw,tbh);
);
// outline or shadow of applicable
style.olt>0?(
  !HQMode?style.ola*=40; //opacity compensation for fast mode
  style.shmode?(style.ola=exp(style.ola*style.fga*4.5-4);style.shangl=style.shangl*oldiv/360):(style.ola=exp((oldiv/20)*style.ola*style.fga-5.7);style.shangl=0;); 
  gfx_set(style.olr,style.olg,style.olb,style.ola*style.fga,mode,img);
  i=0; loop(style.shmode?oldiv/16:oldiv, 
    phi=2*(i+style.shangl)*$pi/oldiv;
    polar2xy(style.olt,phi,ox,oy);
    gfx_str_draw(#text,(iw-tw)/2+ox,(ih-th)/2+oy);
    i+=1;
  );
);
// 'normal' text 
gfx_set(style.fgr,style.fgg,style.fgb,style.fga,mode,img);
gfx_str_draw(#text,(iw-tw)/2,(ih-th)/2);

//final render
gfx_set(1,1,1,1,mode,-1,1);
gfx_blit(0,1);
//offset factor compensation according to alignement reference  
tofx+=hRef*(sw-tbw)/(2*sw);
tofy+=vRef*(sh-tbh)/(2*sh);
//final position
rx=tofx*sw+sw/2-iw/2;
ry=tofy*sh+sh/2-ih/2;
//final blit + clean
gfx_rotoblit(img,rota,rx,ry,iw,ih);
gfx_img_free(img);
papagirafe is offline   Reply With Quote