Patch title: Release 84 bulk changes
Abstract:
File: /pliant/graphic/color/ink.pli
Key:
    Removed line
    Added line
   
abstract
  [Inks simulation]



constant standard_dot_growth 0.05
constant default_opacity 0
constant ink_cache 256
constant extrapolation_exposure 0.25
abstract
  [Inks simulation]



constant standard_dot_growth 0.05
constant default_opacity 0
constant ink_cache 256
constant extrapolation_exposure 0.25
constant display_specular false



type ColorFast
  field ColorRGB rgb



type ColorFast
  field ColorRGB rgb
  field Float specular ; field Int count
  
type ColorInkFastFilter
  field Float32 r_filter r_generator
  field Float32 g_filter g_generator
  field Float32 b_filter b_generator


method cf init
  arg_w ColorFast cf
  cf:rgb r := 1 ; cf:rgb g := 1 ; cf:rgb b := 1
  
type ColorInkFastFilter
  field Float32 r_filter r_generator
  field Float32 g_filter g_generator
  field Float32 b_filter b_generator


method cf init
  arg_w ColorFast cf
  cf:rgb r := 1 ; cf:rgb g := 1 ; cf:rgb b := 1
  if display_specular
    cf specular := 0 ; cf count := 0

method cf apply ink l
  arg_rw ColorFast cf ; arg ColorInk ink ; arg Int l
  var Pointer:ColorInkFastFilter p :> ink:fast_filter l
  cf:rgb r := cf:rgb:r*p:r_filter+p:r_generator
  cf:rgb g := cf:rgb:g*p:g_filter+p:g_generator
  cf:rgb b := cf:rgb:b*p:b_filter+p:b_generator

method cf apply ink l
  arg_rw ColorFast cf ; arg ColorInk ink ; arg Int l
  var Pointer:ColorInkFastFilter p :> ink:fast_filter l
  cf:rgb r := cf:rgb:r*p:r_filter+p:r_generator
  cf:rgb g := cf:rgb:g*p:g_filter+p:g_generator
  cf:rgb b := cf:rgb:b*p:b_filter+p:b_generator
  if display_specular
    cf:specular += ink specular ; cf count += 1

method cf terminate rgb
  arg_rw ColorFast cf ; arg_w ColorRGB888 rgb

method cf terminate rgb
  arg_rw ColorFast cf ; arg_w ColorRGB888 rgb
  if display_specular
    if cf:specular<>0
      var Float s := cf:specular/cf:count
      cf:rgb r := cf:rgb:r*(1-s)+s
      cf:rgb g := cf:rgb:g*(1-s)+s
      cf:rgb b := cf:rgb:b*(1-s)+s
  rgb := cf rgb



  rgb := cf rgb



function adjust f0 options all -> f
  arg ColorSpectrum32 f0 ; arg Str options ; arg CBool all ;
function adjust f0 options quantity -> f
  arg ColorSpectrum32 f0 ; arg Str options ; arg Float quantity ; arg ColorSpectrum32 f
  f := f0
  f := f0
  var Float power := options option "ink" Float 1
  if power<>1
    f := f^power
  var Float density := options option "density" Float 1
  if density<>1
    f := f^density
  var Float specular := options option "specular" Float 0
  if specular<>0
    f := max f-(cast specular ColorSpectrum32) (cast 0 Color
  var Float specular := options option "specular" Float 0
  if specular<>0
    f := max f-(cast specular ColorSpectrum32) (cast 0 Color
  if all
  if quantity>0
    for (var Int i) 0 3
      var Str color := shunt i=0 "cyan" i=1 "magenta" i=2 "y
      var Float extra := options option color Float
      if extra=defined
        var Data:ColorChannel primary :> color_database:data
    for (var Int i) 0 3
      var Str color := shunt i=0 "cyan" i=1 "magenta" i=2 "y
      var Float extra := options option color Float
      if extra=defined
        var Data:ColorChannel primary :> color_database:data
        f *= (primary:s100/primary:s0)^extra
        f *= (primary:s100/primary:s0)^(extra*quantity)

function color_ink name options -> ink
  arg Str name options ; arg Link:ColorInk ink
  if not (name parse any:(var Str device_id) ":" any:(var St
    device_id := "default" ; channel_id := name
  var Data:ColorChannel channel :> color_database:data:devic
  if not exists:channel and (exists color_database:data:devi
    var Str alias := color_database:data:device:device_id:al
    channel :> color_database:data:device:device_id:channel:
  if channel:s0=undefined or channel:s100=undefined
    ink :> new ColorInk
    return
  var Str opt := options+" "+channel:options+" "+color_datab
  sem request
  var Pointer:Arrow c :> colors first string:name+" "+string
  if c<>null
    ink :> c map ColorInk
    sem release
    return
  if colors:count>=ink_cache
    colors := var Dictionary empty_dictionary
  ink :> new ColorInk

function color_ink name options -> ink
  arg Str name options ; arg Link:ColorInk ink
  if not (name parse any:(var Str device_id) ":" any:(var St
    device_id := "default" ; channel_id := name
  var Data:ColorChannel channel :> color_database:data:devic
  if not exists:channel and (exists color_database:data:devi
    var Str alias := color_database:data:device:device_id:al
    channel :> color_database:data:device:device_id:channel:
  if channel:s0=undefined or channel:s100=undefined
    ink :> new ColorInk
    return
  var Str opt := options+" "+channel:options+" "+color_datab
  sem request
  var Pointer:Arrow c :> colors first string:name+" "+string
  if c<>null
    ink :> c map ColorInk
    sem release
    return
  if colors:count>=ink_cache
    colors := var Dictionary empty_dictionary
  ink :> new ColorInk
  ink s0 := adjust channel:s0 opt false
  ink s50 := adjust channel:s50 opt false
  ink s100 := adjust channel:s100 opt true
  ink s0 := adjust channel:s0 opt 0
  ink s50 := adjust channel:s50 opt 0.5
  ink s100 := adjust channel:s100 opt 1
  ink specular := opt option "specular" Float 0
  ink opacity := opt option "opacity" Float default_opacity
  ink maximum := opt option "maximum" Int 255
  var CBool negative := opt option "negative"
  var CBool linear := opt option "linear"
  ink specular := opt option "specular" Float 0
  ink opacity := opt option "opacity" Float default_opacity
  ink maximum := opt option "maximum" Int 255
  var CBool negative := opt option "negative"
  var CBool linear := opt option "linear"
  var Int maxi := shunt (exists channel:sample:"255") 255 100
  ink options := opt
  var (Index Int ColorSpectrum32) samples
  each sample channel:sample
    if (keyof:sample parse (var Int index))
  ink options := opt
  var (Index Int ColorSpectrum32) samples
  each sample channel:sample
    if (keyof:sample parse (var Int index))
      samples insert index (adjust color_spectrum32:sample o
  var Int maxi := shunt (exists channel:sample:"255") 255 10
      samples insert index (adjust color_spectrum32:sample opt index/maxi)
  var Float dot := opt option "dot" Float 0
  for (var Int l) 0 encoded_resolution-1
    var Float d := ink_dot_growth (shunt negative encoded_re
    var ColorSpectrum32 s
    if samples:size=3 and ink:s50<>undefined
      s := ink_surface_simulation d ink:s0 ink:s50 ink:s100
    eif samples:size=2 # we have only 0 and 100% so we assum
      s := ink_surface_simulation d ink:s0 ink:s100
    else # we have more than three values, so we assume inkj
      var Pointer:ColorSpectrum32 a :> samples first
      var Pointer:ColorSpectrum32 b :> samples next a
      while (samples key b)<d*maxi
        a :> b ; b :> samples next a
      s := unexposure (ink_linear_simulation (d*maxi-(sample
      if not linear
        d := ink_surface s ink:s0 ink:s100
    ink:gradation:decode_table l := shunt negative 1-d d
    ink:filter l := s/ink:s0
    var Pointer:ColorInkFastFilter p :> ink:fast_filter l
    var ColorRGB rgb := cast (filter_XYZ ink:filter:l) Color
    rgb r := bound rgb:r 0 1
    rgb g := bound rgb:g 0 1
    rgb b := bound rgb:b 0 1
    var Float o := l/(encoded_resolution-1)*ink:opacity
    p r_filter := (1-o)*rgb:r ; p r_generator := o*rgb:r
    p g_filter := (1-o)*rgb:g ; p g_generator := o*rgb:g
    p b_filter := (1-o)*rgb:b ; p b_generator := o*rgb:b
  ink status := success
  ink:gradation compute
  if ink:gradation=failure
    ink status := failure
  colors insert string:name+" "+string:opt true addressof:in
  sem release



export migrate
  var Float dot := opt option "dot" Float 0
  for (var Int l) 0 encoded_resolution-1
    var Float d := ink_dot_growth (shunt negative encoded_re
    var ColorSpectrum32 s
    if samples:size=3 and ink:s50<>undefined
      s := ink_surface_simulation d ink:s0 ink:s50 ink:s100
    eif samples:size=2 # we have only 0 and 100% so we assum
      s := ink_surface_simulation d ink:s0 ink:s100
    else # we have more than three values, so we assume inkj
      var Pointer:ColorSpectrum32 a :> samples first
      var Pointer:ColorSpectrum32 b :> samples next a
      while (samples key b)<d*maxi
        a :> b ; b :> samples next a
      s := unexposure (ink_linear_simulation (d*maxi-(sample
      if not linear
        d := ink_surface s ink:s0 ink:s100
    ink:gradation:decode_table l := shunt negative 1-d d
    ink:filter l := s/ink:s0
    var Pointer:ColorInkFastFilter p :> ink:fast_filter l
    var ColorRGB rgb := cast (filter_XYZ ink:filter:l) Color
    rgb r := bound rgb:r 0 1
    rgb g := bound rgb:g 0 1
    rgb b := bound rgb:b 0 1
    var Float o := l/(encoded_resolution-1)*ink:opacity
    p r_filter := (1-o)*rgb:r ; p r_generator := o*rgb:r
    p g_filter := (1-o)*rgb:g ; p g_generator := o*rgb:g
    p b_filter := (1-o)*rgb:b ; p b_generator := o*rgb:b
  ink status := success
  ink:gradation compute
  if ink:gradation=failure
    ink status := failure
  colors insert string:name+" "+string:opt true addressof:in
  sem release



export migrate