about summary refs log tree commit diff stats
path: root/505colors.mu
blob: 3185f9f7db37a6a5109ee1e3f43dfdaa1080ce20 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
parse/0: label: +foo
parse/0: instruction: 1
parse/0:   ingredient: {name: "23", value: 0, type: 0, properties: ["23": "literal"]}
parse/0:   product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]}
parse/0: instruction: 1
parse/0:   ingredient: {name: "1", value: 0, type: 1, properties: ["1": "integer"]}
parse/0:   product: {name: "2", value: 0, type: 1, properties: ["2": "integer"]}
after-brace/0: recipe main
after-brace/0: copy ...
after-brace/0: copy ...
run/0: instruction main/1
run/0: ingredient 0 is 23
mem/0: storing 23 in location 1
run/0: instruction main/2
run/0: ingredient 0 is 1
mem/0: location 1 is 23
mem/0: storing 23 in location 2
>225 226 227 228 229 230 231 232 233 234
# Hue/saturation/luminance for an rgb triple.
# rgb are in [0, 256)
# hsl are also returned in [0, 256)
# from https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl
fn hsl r: int, g: int, b: int -> _/ecx: int, _/edx: int, _/ebx: int {
  var _max/eax: int <- maximum r, g
  _max <- maximum _max, b
  var max/ecx: int <- copy _max
  var _min/eax: int <- minimum r, g
  _min <- minimum _min, b
  var min/edx: int <- copy _min
  var luminance/ebx: int <- copy min
  luminance <- add max
  luminance <- shift-right 1  # TODO: round up instead of down
  # if rgb are all equal, it's a shade of grey
  compare min, max
  {
    break-if-!=
    return 0, 0, luminance
  }
  # saturation =
  #   luminance < 128 | 255*(max-min)/         (max+min)
  #   otherwise       | 255*(max-min)/(2*255 - (max+min))
  var nr/esi: int <- copy max
  nr <- subtract min
  var dr/eax: int <- copy 0
  compare luminance, 0x80
  {
    break-if->=
    dr <- copy max
    dr <- add min
  }
  {
    break-if-<
    dr <- copy 0xff
    dr <- shift-left 1
    dr <- subtract max
    dr <- subtract min
  }
  var q/xmm0: float <- convert nr
  var tmp/xmm1: float <- convert dr
  q <- divide tmp
  var int-255/eax: int <- copy 0xff
  tmp <- convert int-255
  q <- multiply tmp
  var saturation/esi: int <- convert q
  # hue = 
  #   red is max   | 256.0/6*       (g-b)/(max-min)
  #   green is max | 256.0/6*(2.0 + (b-r)/(max-min))
  #   blue is max  | 256.0/6*(4.0 + (r-g)/(max-min))
  var zero/eax: int <- copy 0
  var hue-f/xmm0: float <- convert zero
  var dr/eax: int <- copy max
  dr <- subtract min
  var dr-f/xmm1: float <- convert dr
  $hsl:compute-hue-normalized: {
    compare r, max
    {
      break-if-!=
      var nr/eax: int <- copy g
      nr <- subtract b
      hue-f <- convert nr
      hue-f <- divide dr-f
      break $hsl:compute-hue-normalized
    }
    compare g, max
    {
      break-if-!=
      var nr/eax: int <- copy b
      nr <- subtract r
      var f/xmm2: float <- convert nr
      f <- divide dr-f
      var two/ecx: int <- copy 2
      hue-f <- convert two
      hue-f <- add f
      break $hsl:compute-hue-normalized
    }
    compare b, max
    {
      break-if-!=
      var nr/eax: int <- copy r
      nr <- subtract g
      var f/xmm2: float <- convert nr
      f <- divide dr-f
      var two/ecx: int <- copy 4
      hue-f <- convert two
      hue-f <- add f
      break $hsl:compute-hue-normalized
    }
  }
  var int-256/eax: int <- copy 0x100
  var scaling-factor/xmm1: float <- convert int-256
  var int-6/eax: int <- copy 6
  var six-f/xmm2: float <- convert int-6
  scaling-factor <- divide six-f
  hue-f <- multiply scaling-factor
  var hue/eax: int <- convert hue-f
  # if hue < 0, hue = 256 - hue
  compare hue, 0
  {
    break-if->=
    var tmp/ecx: int <- copy 0x100
    tmp <- subtract hue
    hue <- copy tmp
  }
  return hue, saturation, luminance
}

fn test-hsl-black {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0, 0, 0
  check-ints-equal h, 0, "F - test-hsl-black/hue"
  check-ints-equal s, 0, "F - test-hsl-black/saturation"
  check-ints-equal l, 0, "F - test-hsl-black/luminance"
}

fn test-hsl-white {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0xff, 0xff, 0xff
  check-ints-equal h, 0, "F - test-hsl-white/hue"
  check-ints-equal s, 0, "F - test-hsl-white/saturation"
  check-ints-equal l, 0xff, "F - test-hsl-white/luminance"
}

fn test-hsl-grey {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0x30, 0x30, 0x30
  check-ints-equal h, 0, "F - test-hsl-grey/hue"
  check-ints-equal s, 0, "F - test-hsl-grey/saturation"
  check-ints-equal l, 0x30, "F - test-hsl-grey/luminance"
}

# red hues: 0-0x54
fn test-hsl-slightly-red {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0xff, 0xfe, 0xfe
  check-ints-equal h, 0, "F - test-hsl-slightly-red/hue"
  check-ints-equal s, 0xff, "F - test-hsl-slightly-red/saturation"
  check-ints-equal l, 0xfe, "F - test-hsl-slightly-red/luminance"  # TODO: should round up
}

fn test-hsl-extremely-red {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0xff, 0, 0
  check-ints-equal h, 0, "F - test-hsl-extremely-red/hue"
  check-ints-equal s, 0xff, "F - test-hsl-extremely-red/saturation"
  check-ints-equal l, 0x7f, "F - test-hsl-extremely-red/luminance"  # TODO: should round up
}

# green hues: 0x55-0xaa
fn test-hsl-slightly-green {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0xfe, 0xff, 0xfe
  check-ints-equal h, 0x55, "F - test-hsl-slightly-green/hue"
  check-ints-equal s, 0xff, "F - test-hsl-slightly-green/saturation"
  check-ints-equal l, 0xfe, "F - test-hsl-slightly-green/luminance"  # TODO: should round up
}

fn test-hsl-extremely-green {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0, 0xff, 0
  check-ints-equal h, 0x55, "F - test-hsl-extremely-green/hue"
  check-ints-equal s, 0xff, "F - test-hsl-extremely-green/saturation"
  check-ints-equal l, 0x7f, "F - test-hsl-extremely-green/luminance"  # TODO: should round up
}

# blue hues: 0xab-0xff
fn test-hsl-slightly-blue {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0xfe, 0xfe, 0xff
  check-ints-equal h, 0xab, "F - test-hsl-slightly-blue/hue"
  check-ints-equal s, 0xff, "F - test-hsl-slightly-blue/saturation"
  check-ints-equal l, 0xfe, "F - test-hsl-slightly-blue/luminance"  # TODO: should round up
}

fn test-hsl-extremely-blue {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0, 0, 0xff
  check-ints-equal h, 0xab, "F - test-hsl-extremely-blue/hue"
  check-ints-equal s, 0xff, "F - test-hsl-extremely-blue/saturation"
  check-ints-equal l, 0x7f, "F - test-hsl-extremely-blue/luminance"  # TODO: should round up
}

# cyan: 0x7f

fn test-hsl-cyan {
  var h/ecx: int <- copy 0
  var s/edx: int <- copy 0
  var l/ebx: int <- copy 0
  h, s, l <- hsl 0, 0xff, 0xff
  check-ints-equal h, 0x80, "F - test-hsl-cyan/hue"
  check-ints-equal s, 0xff, "F - test-hsl-cyan/saturation"
  check-ints-equal l, 0x7f, "F - test-hsl-cyan/luminance"  # TODO: should round up
}

###

fn maximum a: int, b: int -> _/eax: int {
  var a2/eax: int <- copy a
  compare a2, b
  {
    break-if-<
    return a
  }
  return b
}

fn minimum a: int, b: int -> _/eax: int {
  var a2/eax: int <- copy a
  compare a2, b
  {
    break-if->
    return a
  }
  return b
}