# $Revision: 1.12 $
use hkpcore;
use Win32::OLE::Variant;
use constant PLUGIN_NAME => 'js29a_rbow_p';
sub min_max {
my ($min,$max)=($_[0],$_[0]);
shift;
while(defined($_=shift)){
$min=$_ if $_ < $min;
$max=$_ if $_ > $max;
}
$min,$max
}
sub rgb_to_hsv {
return unless defined wantarray;
my ($r,$g,$b);
my ($h,$s,$v)=(0,0,0);
if(ref $_[0] eq 'HASH'){
($r,$g,$b)=($_[0]->{R},$_[0]->{G},$_[0]->{B});
}else{
($r,$g,$b)=@_;
}
my ($var_Min,$var_Max)=min_max($r,$g,$b);
my $del_Max = $var_Max - $var_Min;
$v=$var_Max;
if (!$del_Max){
$h=$s=0.0;
}else{
$s=$del_Max/$var_Max;
my $del_R=((($var_Max-$r)/6.0)+($del_Max/2.0))/$del_Max;
my $del_G=((($var_Max-$g)/6.0)+($del_Max/2.0))/$del_Max;
my $del_B=((($var_Max-$b)/6.0)+($del_Max/2.0))/$del_Max;
if ($r == $var_Max){ $h =$del_B - $del_G; }
elsif ($g == $var_Max){ $h =(1.0/3.0)+$del_R-$del_B; }
elsif ($b == $var_Max){ $h =(2.0/3.0)+$del_G-$del_R; }
else { die 'internal failure'; }
$h+=1.0 if $h < 0.0;
$h-=1.0 if $h > 1.0;
}
return ($h,$s,$v) if wantarray;
return {H=>$h, S=>$s, V=>$v};
}
sub hsv_to_rgb {
return unless defined wantarray;
my ($h,$s,$v);
my ($r,$g,$b)=(0,0,0);
if(ref $_[0] eq 'HASH'){
($h,$s,$v)=($_[0]->{H},$_[0]->{S},$_[0]->{V});
}else{
($h,$s,$v)=@_;
}
if ( !$s ){
$r=$g=$b=$v;
}else{
my $var_h= $h * 6.0;
my $var_i=int $var_h;
my $var_1=$v*(1-$s );
my $var_2=$v*(1-$s*($var_h-$var_i));
my $var_3=$v*(1-$s*(1-($var_h-$var_i)));
if ($var_i==0){ $r=$v ; $g=$var_3; $b=$var_1; }
elsif ($var_i==1){ $r=$var_2; $g=$v ; $b=$var_1; }
elsif ($var_i==2){ $r=$var_1; $g=$v ; $b=$var_3; }
elsif ($var_i==3){ $r=$var_1; $g=$var_2; $b=$v ; }
elsif ($var_i==4){ $r=$var_3; $g=$var_1; $b=$v ; }
elsif ($var_i==5){ $r=$v ; $g=$var_1; $b=$var_2; }
else { die 'internal failure'; }
}
return ($r,$g,$b) if wantarray;
return {R=>$r, G=>$g, B=>$b};
}
sub prop_put($$$){
my $v=shift;
my ($key,$value)=@_;
$v->hkp_FuncOpen($hkp_f_PluginDataWrite);
$v->hkp_DataAdd($hkp_FUNC_P1,PLUGIN_NAME);
$v->hkp_DataAdd($hkp_FUNC_P2,$key);
$v->hkp_DataAdd($hkp_FUNC_P3,$value);
$v->hkp_FuncRun();
$v->hkp_FuncClose();
}
sub prop_get($$$){
my $v=shift;
my ($key,$defl)=@_;
$v->hkp_FuncOpen($hkp_f_PluginDataRead);
$v->hkp_DataAdd($hkp_FUNC_P1,PLUGIN_NAME);
$v->hkp_DataAdd($hkp_FUNC_P2,$key);
$v->hkp_DataAdd($hkp_FUNC_P3,$defl);
$v->hkp_FuncRun();
my $res=$v->hkp_DataGetStr($hkp_FUNC_P1,'');
$v->hkp_FuncClose();
return $res;
}
sub wizard($$) {
my $v=$_[0];
my $text=$_[1];
$text=prop_get($v,'text','enter some text here') if $text eq '';
$text=~s/&/&/g;
$text=~s/</g;
$text=~s/>/>/g;
my $c0=prop_get($v,'c0','#dead00');
my $c1=prop_get($v,'c1','#00beef');
$v->hkp_FuncOpen($hkp_f_InputWizard);
$v->hkp_DataAddInt($hkp_FUNC_P1, 1);
$v->hkp_DataAdd($hkp_FUNC_P2, "Rainbow text and color selection");
$v->hkp_DataAdd($hkp_FUNC_P3, "pick two colors");
$v->hkp_DataAdd($hkp_FUNC_P4, <<"EOS");
EOS
$v->hkp_DataAddInt($hkp_FUNC_P5, 0);
$v->hkp_DataAdd($hkp_FUNC_P6, "about:");
$v->hkp_FuncRun();
$v->hkp_FuncClose();
$v->hkp_FuncOpen($hkp_f_InputWizard);
$v->hkp_DataAddInt($hkp_FUNC_P1, 2);
$v->hkp_DataAdd($hkp_FUNC_P2, 'c0');
$v->hkp_FuncRun();
$c0=$v->hkp_DataGetStr($hkp_FUNC_P2,'');
$v->hkp_DataAdd($hkp_FUNC_P2, 'c1');
$v->hkp_FuncRun();
$c1=$v->hkp_DataGetStr($hkp_FUNC_P2,'');
$v->hkp_DataAdd($hkp_FUNC_P2, 'txt');
$v->hkp_FuncRun();
$text=$v->hkp_DataGetStr($hkp_FUNC_P2,'');
$v->hkp_FuncClose();
return (undef,undef,undef) if $c0 eq '' or $c1 eq '' or $text eq '';
$c0=undef if $c0 !~ /^\#[0-9a-fA-F]{6,6}$/;
$c1=undef if $c1 !~ /^\#[0-9a-fA-F]{6,6}$/;
return (undef,undef,undef) if !defined $c0 or !defined $c1;
prop_put($v,'c0',$c0);
prop_put($v,'c1',$c1);
prop_put($v,'text',$text);
return ($c0,$c1,$text);
}
sub esc($){
my $chr=$_[0];
return '&' if $chr eq '&';
return '<' if $chr eq '<';
return '>' if $chr eq '>';
return $chr;
}
sub emit($$$$){
my $chr=$_[0];
my ($r,$g,$b)=@_[1..3];
$r=int($r*255.0);
$g=int($g*255.0);
$b=int($b*255.0);
my $txt=''.esc($chr)."";
return $txt;
}
sub blend($$$){
my $txt=$_[0];
my ($r0,$g0,$b0)=@{$_[1]};
my ($r1,$g1,$b1)=@{$_[2]};
($r0,$g0,$b0,
$r1,$g1,$b1) = map {$_/255.0} ($r0,$g0,$b0,$r1,$g1,$b1);
my ($h0,$s0,$v0)=rgb_to_hsv($r0,$g0,$b0);
my ($h1,$s1,$v1)=rgb_to_hsv($r1,$g1,$b1);
my $out;
my $last=(length $txt)-1;
for $pos (0..$last){
my $hx=($h1-$h0)*$pos/$last+$h0;
my $sx=($s1-$s0)*$pos/$last+$s0;
my $vx=($v1-$v0)*$pos/$last+$v0;
my ($rx,$gx,$bx)=hsv_to_rgb($hx,$sx,$vx);
$out.=emit((substr $txt,$pos,1),$rx,$gx,$bx);
}
return $out;
}
if('-hkpreg' eq $ARGV[0]){
my $icon=
'AAABAAEAEBAEAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAA'
.'AAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8A'
.'AAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAA7u67u6qqAADu7ru7qqoAAO7uu7uqqg'
.'AA7u67u6qqAADu7ru7qqoAAO7uu7uqqgAA7u67u6qqAADu7ru7qqoAAO7uu7uqqgAA7u67'
.'u6qqAADu7ru7qqoAAO7uu7uqqgAA7u67u6qqAADu7ru7qqoAAAAAAAAAAAD//wAAwAMAAM'
.'ADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAAD/'
.'/wAA';
my $v=hkp_CreateObjectHKPCore();
$v->hkp_DataSetGlobalSuffix('_1');
$v->hkp_DataAdd($hkp_NAME,'Rainbow');
$v->hkp_DataAdd($hkp_VERSION,'1.0');
$v->hkp_DataAdd($hkp_SECTION,'js29a');
$v->hkp_DataAdd($hkp_DESCRIPTION,'Rainbow text. Uses HSV color model.');
$v->hkp_DataAdd($hkp_HINT,'make a rainbow text');
$v->hkp_DataAdd($hkp_COPYRIGHT_SHORT,'Copyright (C) 2002,2005 by js29a.');
$v->hkp_DataAdd($hkp_COPYRIGHT_LONG,'Copyright (C) 2002,2005 by js29a.\nAll rights reserved.');
$v->hkp_DataAdd($hkp_AUTHOR,'js29a');
$v->hkp_DataAdd($hkp_EMAIL,'js29a@o2.pl');
$v->hkp_DataAdd($hkp_ICON_SMALL,$icon);
$v->hkp_DataAdd($hkp_LICENSE_TYPE,'freeware');
$v->hkp_DataAddInt($hkp_MODE_IN_TEXT_SELECTED,1);
$v->hkp_DataAddInt($hkp_MODE_ICON,$hkp_c_MODE_ICON_DATA);
$v->hkp_DataSetGlobalSuffix('');
}
elsif('-hkprun' eq $ARGV[0]){
my $v=hkp_CreateObjectHKPCore();
my $text=Variant(VT_BSTR|VT_BYREF,'');
my $want_struct=0;
$v->hkp_DataGet($hkp_INPUT_SELECTED,$text);
my ($c0,$c1,$txt)=wizard($v,$text);
my $out=undef;
if(defined $c0 && defined $c1 && defined $txt){
my ($r0,$g0,$b0)=unpack 'xA2A2A2',$c0;
my ($r1,$g1,$b1)=unpack 'xA2A2A2',$c1;
($r0,$g0,$b0,$r1,$g1,$b1)=map { hex $_ } ($r0,$g0,$b0,$r1,$g1,$b1);
my $rgb_str_0=sprintf("rgb(%3d,%3d,%3d)",$r0,$g0,$b0);
my $rgb_str_1=sprintf("rgb(%3d,%3d,%3d)",$r1,$g1,$b1);
$out=<<"EOS";
EOS
$out .= blend($txt,[$r0,$g0,$b0],[$r1,$g1,$b1]);
}
$v->hkp_DataAdd('OUTPUT',$out) if defined $out;
}