blob: d8f5fbcd0bf9892db249967de80122e45fb62538 [file] [log] [blame]
import 'HSVTree.ecore#/';
import 'HSLTree.ecore#/';
import 'HSV2HSL.ecore#/';
transformation hsv2hsl
{
hsv imports HSVTree;
hsl imports HSLTree;
imports HSV2HSL;
}
map HSV2HSLRoot in hsv2hsl
{
check hsv(hsvRoot : HSVTree::HSVNode[1]
|
hsvRoot.parent = null;) {}
check enforce hsl() {
realize hslRoot : HSLTree::HSLNode[1]
|
hslRoot.parent := null;
}
where() {
realize middleRoot : HSV2HSL::HSVNode2HSLNode[1]
|
middleRoot.parent := null;
middleRoot.hsv := hsvRoot;
middleRoot.hsl := hslRoot;
}
map
{
where() {
middleRoot.name := hsvRoot.name;
middleRoot.name := hslRoot.name;
hsvRoot.name := middleRoot.name;
hslRoot.name := middleRoot.name;
hsvRoot.hsv := rgb2hsv(middleRoot.rgb);
hslRoot.hsl := rgb2hsl(middleRoot.rgb);
middleRoot.rgb := hsv2rgb(hsvRoot.hsv);
middleRoot.rgb := hsl2rgb(hslRoot.hsl);
}
}
}
map HSV2HSLRecursion in hsv2hsl
{
check enforce hsv(hsvParent : HSVTree::HSVNode[1]
|) {
realize hsvNode : HSVTree::HSVNode[1]
|
hsvNode.parent := hsvParent;
}
check enforce hsl(hslParent : HSLTree::HSLNode[1]
|) {
realize hslNode : HSLTree::HSLNode[1]
|
hslNode.parent := hslParent;
}
where(middleParent : HSV2HSL::HSVNode2HSLNode[1]
|
middleParent.hsv = hsvParent;
middleParent.hsl = hslParent;) {
realize middleNode : HSV2HSL::HSVNode2HSLNode[1]
|
middleNode.parent := middleParent;
middleNode.hsv := hsvNode;
middleNode.hsl := hslNode;
}
map
{
where() {
middleNode.name := hsvNode.name;
middleNode.name := hslNode.name;
hslNode.name := middleNode.name;
hsvNode.name := middleNode.name;
hsvNode.hsv := rgb2hsv(middleNode.rgb);
hslNode.hsl := rgb2hsl(middleNode.rgb);
middleNode.rgb := hsv2rgb(hsvNode.hsv);
middleNode.rgb := hsl2rgb(hslNode.hsl);
}
}
}
query hsv2hsl::hsl2rgb(color : HSLTree::HSL) : HSV2HSL::RGB[1]
{
HSV2HSL::RGB{value=color}
}
query hsv2hsl::hsv2rgb(color : HSVTree::HSV[1]) : HSV2HSL::RGB[1]
{
let hsv : Sequence(String[*|1]) = color.tokenize(',') in
let hopt : Real = hsv->at(1).toReal() in
let sopt : Real = hsv->at(2).toReal() in
let vopt : Real = hsv->at(3).toReal() in
let h : Integer = if hopt <> null then hopt.round() else 0 endif in
let s : Real = if sopt <> null then sopt/100.0 else 0 endif in
let v : Real = if vopt <> null then vopt/100.0 else 0 endif in
let c : Real = v * s in
let hh1 : Real = h/120 in
let hh2 : Real = 2 * (hh1 - hh1.floor()) in
let x : Real = c * (1 - (hh2 - 1).abs()) in
let m : Real = v -c in
let t : Tuple(r:Real,g:Real,b:Real) =
if h < 60 then Tuple{r=c,g=x,b=0.0}
elseif h < 120 then Tuple{r=x,g=c,b=0.0}
elseif h < 180 then Tuple{r=0.0,g=c,b=x}
elseif h < 240 then Tuple{r=0.0,g=x,b=c}
elseif h < 300 then Tuple{r=x,g=0.0,b=c}
else Tuple{r=c,g=0.0,b=x} endif in
let r = (255 * (t.r + m)).round() in
let g = (255 * (t.g + m)).round() in
let b = (255 * (t.b + m)).round() in
HSV2HSL::RGB{value=r.toString() + ',' + g.toString() + ',' + b.toString()}
}
query hsv2hsl::rgb2hsl(color : HSV2HSL::RGB[1]) : HSLTree::HSL[1]
{
let rgb : Sequence(String[*|1]) = color.tokenize(',') in
let ropt : Real = rgb->at(1).toReal() in
let gopt : Real = rgb->at(2).toReal() in
let bopt : Real = rgb->at(3).toReal() in
let r : Real = if ropt <> null then ropt/255.0 else 0 endif in
let g : Real = if gopt <> null then gopt/255.0 else 0 endif in
let b : Real = if bopt <> null then bopt/255.0 else 0 endif in
let cMax : Real = r.max(g).max(b) in
let cMin : Real = r.min(g).min(b) in
let l : Real = (cMax + cMin) / 2 in
let delta : Real = cMax - cMin in
let h : Real = if delta = 0 then 0
elseif cMax = r and g >= b then 60 * ((g - b) / delta + 0)
elseif cMax = r and g < b then 60 * ((g - b) / delta + 6)
elseif cMax = g then 60 * ((b - r) / delta + 2)
else 60 * ((r - g) / delta + 4) endif in
let s : Real = if delta = 0 then 0 else delta / (1 - (2 * l - 1).abs()) endif in
HSLTree::HSL{value=h.round().toString() + ',' + (100*s).round().toString() + ',' + (100*l).round().toString()}
}
query hsv2hsl::rgb2hsv(color : HSV2HSL::RGB) : HSVTree::HSV[1]
{
HSVTree::HSV{value=color}
}
/*
query hsv2hsl::rgb2hsl(rgb:Sequence(Integer)) : Sequence(Real) {
let r: Real = rgb->at(1),
g: Real = rgb->at(2),
b: Real = rgb->at(3),
rgbReal = Sequence{r,g,b},
max: Real = rgbReal->iterate(x : Real, y:Real=0 | y.max(x)),
min: Real = rgbReal->iterate(x : Real, y:Real=1 | y.min(x)),
l: Real = (max+min)/2
in
if max = min then
Sequence{0, 0, l*100}
else
let c:Real = max-min,
s:Real = if l < 0.5 then
c / (max+min)
else
c / (2-max-min)
endif,
r1:Real = ((max-r)/6 + c/2)/c,
g1:Real = ((max-g)/6 + c/2)/c,
b1:Real = ((max-b)/6 + c/2)/c
in
if max = r then
let h:Real = b1 - g1
in
Sequence{h*360, s*100, l*100}
else
if max = g then
let h: Real = 1/3 + r1 - b1
in
Sequence{h*360, s*100, l*100}
else -- max = b
let h: Real = 2/3 + g1 - r1
in
Sequence{h*360, s*100, l*100}
endif
endif
endif
}
query hsv2hsl::hsl2rgb(hsl:Sequence(Real)) : Sequence(Integer) {
let h: Real = hsl->at(1),
s: Real = hsl->at(2)/100,
l: Real = hsl->at(3)/100,
c: Real = 1 - (2*l-1).abs()*s,
h2: Real = (h/60),
hmod: Real = h2.floor().mod(2) + (h/60 - h2.floor()),
x:Real = c*(1-(hmod-1).abs()),
m:Real = l - 0.5*c
in
if h2 < 1 then
Sequence{c+m, x+m, m}
else
if h2 < 2 then
Sequence{x+m, c+m, m}
else
if h2 < 3 then
Sequence{m, c+m, x+m}
else
if h2 < 4 then
Sequence{m, x, c}
else
if h2 < 5 then
Sequence{x+m, m, c+m}
else
Sequence{c+m, m, x+m}
endif
endif
endif
endif
endif
}
query hsv2hsl::rgb2hsv(rgb:Sequence(Integer)) : Sequence(Real) {
let r: Real = rgb->at(1),
g: Real = rgb->at(2),
b: Real = rgb->at(3),
rgbReal = Sequence{r,g,b},
max: Real = rgbReal->iterate(x : Real, y:Real=0 | y.max(x)),
min: Real = rgbReal->iterate(x : Real, y:Real=1 | y.min(x)),
v: Real = max
in
if max = min then
Sequence{0, 0, v*100}
else
let c:Real = max-min,
s:Real = c/max,
r1:Real = ((max-r)/6 + c/2)/c,
g1:Real = ((max-g)/6 + c/2)/c,
b1:Real = ((max-b)/6 + c/2)/c
in
if max = r then
let h:Real = b1 - g1
in
Sequence{h*360, s*100, v*100}
else
if max = g then
let h: Real = 1/3 + r1 - b1
in
Sequence{h*360, s*100, v*100}
else -- max = b
let h: Real = 2/3 + g1 - r1
in
Sequence{h*360, s*100, v*100}
endif
endif
endif
}
query hsv2hsl::hsv2rgb(hsv:Sequence(Real)) : Sequence(Integer) {
let h: Real = hsv->at(1),
s: Real = hsv->at(2)/100,
v: Real = hsv->at(3)/100,
i:Integer = (h/60).floor(),
f:Real = h/60 - i,
p:Real = v * (1 - s),
q:Real = v * (1 - f * s),
t:Real = v * (1 - (1 - f) * s)
in
if i = 0 then
Sequence{v, t, p}
else
if i = 1 then
Sequence{q, v, p}
else
if i = 2 then
Sequence{p, v, t}
else
if i = 3 then
Sequence{p, q, v}
else
if i = 4 then
Sequence{t, p, v}
else
Sequence{v, p, q}
endif
endif
endif
endif
endif
}
*/