//--------------------- about this script -------------------------meta = {"@prefix": "<http://purl.org/net/ns/doas#>","@about": "<http://www.kanzaki.com/docs/html/cc.js>", a: ":Javascript", title: "Color check utility scripts", shortdesc: "ulitity scripts to calculate some color values.", created: "2003-05-08", release: {revision: "2.1.0", created: "2005-11-26"}, author: {name: "KANZAKI, Masahide", homepage: "<http://www.kanzaki.com/>"}, license: "<http://creativecommons.org/licenses/GPL/2.0/>"};//-----------------------------------------------------------------/** * Set 'span' elements' text and background color to demonstrate color contrast. * @param	o : object that holds span elements * @param	fa : array of foreground color RGB * @param	ba : array of background color RGB * @param	fa2 : optional array of foreground color RGB of second text * @param	fa3 : optional array of foreground color RGB of third text */function set_color_rgb(o,fa,ba,fa2,fa3){	var s = o.getElementsByTagName('span').item(0);	var s2 = o.getElementsByTagName('span').item(1);	var ttl = "FG("+fa[0]+","+fa[1]+","+fa[2]+") BG("+ba[0]+","+ba[1]+","+ba[2]+") ";	o.style.color = "rgb(" + fa[0] + "," + fa[1] + "," + fa[2] + ")";	o.style.background = "rgb(" + ba[0] + "," + ba[1] + "," + ba[2] + ")";	if(fa2 != ''){		s.style.color = "rgb(" + fa2[0] + "," + fa2[1] + "," + fa2[2] + ")";		s.style.display = "inline";		ttl += " FG2("+fa2[0]+","+fa2[1]+","+fa2[2]+")";	}else{		s.style.display = "none";	}	if(fa3 != ''){		s2.style.color = "rgb(" + fa3[0] + "," + fa3[1] + "," + fa3[2] + ")";		s2.style.display = "inline";		ttl += " FG3("+fa3[0]+","+fa3[1]+","+fa3[2]+")";	}else{		s2.style.display = "none";	}	o.setAttribute("title",ttl);}/** * Simulate how the color combination will be percieived by color deficiencies. * @param	fga : array of foreground color RGB * @param	bga : array of background color RGB * @param	fga2 : array of foreground color RGB of the second text * @param	fga3 : array of foreground color RGB of the third text * @param	proid : id of the element to display protanope simulation * @param	deuid : id of the element to display deuteranope simulation * @param	triid : id of the element to display tritanope simulation */function test_color_deficiency(fga,bga,fga2,fga3,proid,deuid,triid){	var pro=0,deu=1,tri=2;	var fpro,bpro,fdeu,bdeu,ftri,btri;	var f2pro,f2deu,f2tri,f3pro,f3deu,f3tri;	fpro = simulate_cv(fga,pro);	bpro = simulate_cv(bga,pro);	fdeu = simulate_cv(fga,deu);	bdeu = simulate_cv(bga,deu);	ftri = simulate_cv(fga,tri);	btri = simulate_cv(bga,tri);	if(fga2){		f2pro = simulate_cv(fga2,pro);		f2deu = simulate_cv(fga2,deu);		f2tri = simulate_cv(fga2,tri);	}else{		f2pro = f2deu = f2tri = '';	}	if(fga3){		f3pro = simulate_cv(fga3,pro);		f3deu = simulate_cv(fga3,deu);		f3tri = simulate_cv(fga3,tri);	}else{		f3pro = f3deu = f3tri = '';	}	set_color_rgb(document.getElementById(proid),fpro,bpro,f2pro,f3pro);	set_color_rgb(document.getElementById(deuid),fdeu,bdeu,f2deu,f3deu);	set_color_rgb(document.getElementById(triid),ftri,btri,f2tri,f3tri);}/** * Calculates simulated color values from color transformation table. * Requires global var gaCtrans read from ct.js. * @param	rgb : array of original RGB value * @param	type : type of color deficiency: 0=pro,1=deu,2=tri. * @return	array of simulated RGB */function simulate_cv(rgb,type){	var sfv = Array(0,51,102,153,204,255,999);	var minrgb = Array(0,0,0), maxrgb = Array(255,255,255);	var r,g,b,spf = new Array(); //scale position factor	var i,j,minvals,maxvals;	var cid = rgb[0] + '_' + rgb[1] + '_' + rgb[2];	if(gaCtrans[cid]) return gaCtrans[cid][type];	for(i=0;i<3;i++){		for(j=0;j<6;j++){			if(rgb[i] == sfv[j]){				minrgb[i] = sfv[j];				maxrgb[i] = sfv[j];				spf[i] = 0;				break;			}if(rgb[i] > sfv[j] && rgb[i] < sfv[j+1]){				minrgb[i] = sfv[j];				maxrgb[i] = sfv[j+1];				spf[i] = (rgb[i] - sfv[j])/51;				break;			}		}	}	minvals = gaCtrans[minrgb[0] + '_' + minrgb[1] + '_' + minrgb[2]][type];	maxvals = gaCtrans[maxrgb[0] + '_' + maxrgb[1] + '_' + maxrgb[2]][type];	r = (spf[0] > 0) ? minvals[0] + Math.round((maxvals[0] - minvals[0])*spf[0]) : minvals[0];	g = (spf[1] > 0) ? minvals[1] + Math.round((maxvals[1] - minvals[1])*spf[1]) : minvals[1];	b = (spf[2] > 0) ? minvals[2] + Math.round((maxvals[2] - minvals[2])*spf[2]) : minvals[2];	return Array(r,g,b);}// requires x11/** * Parses input color value and calculate appropriate RGB. * Requires global var x11 read from x11.js to handle SVG/X11 color names. * @param	c : color name, hex code or rgb() function * @param	stage : optional param, force to return white if set 'pre' * @return	array of RGB values, each decimal 0 - 255 */function parse_color(c,stage){	if(stage == 'pre' && c=='') return Array(255,255,255);	c = c.toLowerCase();	if(c.match(/rgb\(([^)]*)\)/) ){return rgb2dec(RegExp.$1);}	else if(x11[c]){c = x11[c]}	else if(c.match(/[^#0-9a-f]/)){		alert("未知の色名です: " + c);		return false;	}	//if(c.substr(0,1) != "#"){c = "#" + c;}	var d = new Array();	if(c.substr(0,1) == "#"){c = c.substr(1);}	if(c.length == 3){		c = c.charAt(0) + c.charAt(0) + c.charAt(1) + c.charAt(1) + c.charAt(2) + c.charAt(2);	}else if(c.length !=6){		alert("色値の桁数が不正です（3桁もしくは6桁の16進数）: #" + c);		return false;	}	d[0] = ge.h2d(c.substr(0,2));	d[1] = ge.h2d(c.substr(2,2));	d[2] = ge.h2d(c.substr(4,2));		return d;}/** * Checks and calculates decimal RGB value from rgb() function argument string. * @param	c : argument list of rgb() function, e.g. "100%,40%,33%" * @return	array of RGB values, each decimal 0 - 255 */function rgb2dec(c){	var d = new Array(), v,i,p;	var c2 = c.replace(/ /g,"");	d = c2.split(",");	for(i=0;i<3;i++){		v = d[i];		if(v.match(/[^0-9%]/)){			alert("RGB色値が不正です: rgb(" + c + ")");			return false;		}else if(v.match(/%/)){			p = v.replace("%","");			d[i] = Math.round(p * 255 / 100);		}		if(d[i] < 0 || d[i] > 255){			alert("RGB色値が不正です:" + i + "=" + d[i] + " rgb(" + c + ")");			return false;		}	}	return d;}/** calc Y value of YIQ from RGB array */function yiqy(arr){	return Math.round((arr[0]*299 + arr[1]*587 + arr[2]*114)/1000);}function ydiff(f,b){	return Math.abs(f - b);}function cdiff(f,b){	return Math.abs(f[0] - b[0]) + Math.abs(f[1] - b[1]) + Math.abs(f[2] - b[2]);}/** * Calculation of luminosity contrast ratio, defined by WCAG2.0/20051123 * which is Y value of YPrPb. using linearized R, G, and B values. updated: L = 0.2126 * R + 0.7152 * G + 0.0722 * B        * if RsRGB <= 0.03928 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4
        * if GsRGB <= 0.03928 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4
        * if BsRGB <= 0.03928 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4
 */function yppy(rgb){	var lRGB = new Array(),i; //linearized RGB	for(i=0;i<3;i++){		//lRGB[i] = Math.pow(rgb[i]/255,2.2);		var v = rgb[i] / 255;		lRGB[i] = (v <= 0.03928) ? v/12.92 :  Math.pow(((v+0.055)/1.055),2.4);	}	return Math.round((lRGB[0]*0.2126 + lRGB[1]*0.7152 + lRGB[2]*0.0722) * 100000) / 100000;}//-------------------- palette related functions --------------------var gTgFld, gSmplid, gCp,gCptd,gCphilite=256; //global/** * Generates pseudo color palette table. * expected style: * #cpalette td {font-size:7px;line-height:0.9; *      border:gray outset 1px;margin:1px} * #cpalette .bar td {border:gray 1px inset;font-size:x-small; *      color:blue;text-decoration:underline} * #cpalette table {width:400px;height:100px; *      background:white;border:gray ridge thin;cursor:default} * #cpalette {display:none;position:absolute} * #sfg,#sbg,#sfg2 {border:gray solid 1px;line-height:1; *      font-size:80%; cursor:pointer } */function genctable(func){	var cl = Array('0','3','6','9','c','f');	var i,j,k,v,row;	if(! func) func='sc';	var ctbl = "<div id='cpalette'>\n<table>\n";	/*document.write("<tr class='lbl'><td></td>");	for(i=0;i<6;i++)		document.write("<td colspan='6'>"+cl[i]+"</td>");	document.write("</tr>\n");*/	for(i=0;i<6;i++){		ctbl += "<tr>";		//document.write("<tr><td class='lbl'>"+cl[i]+"</td>");		row='';		for(j=0;j<6;j++){			for(k=0;k<6;k++){				v=cl[i]+cl[j]+cl[k];				//v=cl[j]+cl[i]+cl[k]; // note not cl[i]+cl[j]+cl[k]				row += "<td style=\"background:#"+v+"\" onclick=\""+func+"('"+v+"');\" title='#"+v+"'>&#160;</td>";				//d=gaCtrans[sfv[i]+'_'+sfv[j]+'_'+sfv[k]][0];				//row += "<td style=\"background:rgb("+d[0]+','+d[1]+','+d[2]+')'+"\" onclick=\"sc('"+v+"');\" title='#"+v+"'>&#160;</td>";			}		}		ctbl += row + "</tr>\n";	}	/*document.write("<tr class='lbl'><td></td>");	for(i=0;i<6;i++)		for(j=0;j<6;j++) document.write("<td>"+cl[j]+"</td>");	document.write("</tr>\n");*/	ctbl += "<tr class='bar'><td onclick=\"pc();\" colspan='36'>close</td></tr>\n";	document.write(ctbl + "</table></div>");	gCp = document.getElementById('cpalette');	gCptd = gCp.getElementsByTagName('td');}function palette(ev,tg){	if(window.event) ev = event;	var doc = new _eventDocPos(ev);	var scr = new _eventScrPos(ev);	gCp.style.top = doc.y + "px";	gCp.style.left = doc.x + "px";	//gCp.style.left = ((scr.x < scr.w - 400) ? doc.x + "px" : (doc.x - 400) + "px");	gCp.style.display = "block";	gTgFld = document.getElementById(tg);	gSmplid = 's' + tg;	hilitePalette();}function hilitePalette(c){	if(! c) c = gTgFld.value;	if(c == '') return;	var i,j,bs,w,cc,dec,hc=0,x=0,res=0;	var appx = false;	var hstr = "0123456789abcdef";	if(gCphilite < 256) gCptd.item(gCphilite).style.border="gray outset 1px";	if(x11[c]) c = x11[c];	if(c.charAt(0) =='#') c = c.substr(1);	if(c.length > 3){		if(c.match(/(.)\1(.)\2(.)\3$/)) c = RegExp.$1 + RegExp.$2 + RegExp.$3;		else if(c.match(/(.).(.).(.).$/)){			c = RegExp.$1 + RegExp.$2 + RegExp.$3;			appx = true;		}else return;	}	for(i=0;i<3;i++){		cc=c.charAt(i).toLowerCase();		dec = hstr.indexOf(cc,0);		if(dec % 3 != 0){			appx = true; j = Math.round(dec / 3);		}else 			j = dec / 3;		x += Math.pow(6,(2-i))*j;		//hc += hstr.charAt((19 - dec) % 16);		hc += dec;	}	if(appx){w = 1; bs = " dashed ";}	else{w = 2; bs = " dotted ";}	hc = (hc > 20) ? "navy" : "silver";	gCptd.item(x).style.border=hc + bs + w + "px";	gCphilite = x;}function pc(){	gCp.style.display = "none";}function sc(c){	gTgFld.value = '#'+c;	gCp.style.display = "none";	setSmpl('',gSmplid,c);}//-------------------- misc functions --------------------function setSmpl(o,tg,c){	var d, t=document.getElementById(tg);	if(o) c = o.value;	if((d=parse_color(c,'pre')))		t.style.background = 'rgb('+d[0]+','+d[1]+','+d[2]+')';}/*function rgb2lms(r,g,b){	return Array(		0.214808*r + 0.751035*g + 0.045156*b,		0.022882*r + 0.940534*g + 0.076827*b,		0.0165*g + 0.999989*b	);}*/function rgb2lms(r,g,b){	return Array(		0.64*r + 0.3*g + 0.15*b,		0.33*r + 0.6*g + 0.06*b,		0.03*r + 0.1*g + 0.79*b	);}/*function lms2rgb(l,m,s){	return Array(		5.088287854*l + -4.064545817*m + 0.082501043*s,		-0.123958666*l + 1.163679449*m + -0.083805445*s,		0.00204534*l + -0.019200922*m + 1.001393805*s	);}*/function lms2rgb(l,m,s){	return Array(		2.088353414*l + -0.990629183*m + -0.321285141*s,		-1.155287818*l + 2.236055332*m + 0.049531459*s,		0.066934404*l + -0.245426149*m + 1.271753681*s	);}function trans(l,m,s,type){	if(type==0) return Array(2.02344*m - 2.52581*s,m,s)	else if(type==1) return Array(l,0.494207*l+1.24827*s,s);}
