@tokens-studio/tokenscript-schemas 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.cjs +31 -8
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +30 -8
- package/dist/cli/index.js.map +1 -1
- package/package.json +2 -1
- package/src/bundler/bundle-schema.ts +146 -0
- package/src/bundler/index.ts +151 -0
- package/src/bundler/schema-dependency-resolver.ts +299 -0
- package/src/bundler/selective-bundler.test.ts +94 -0
- package/src/bundler/selective-bundler.ts +159 -0
- package/src/bundler/types.ts +93 -0
- package/src/bundler/utils.ts +74 -0
- package/src/cli/commands/bundle.integration.test.ts +153 -0
- package/src/cli/commands/bundle.test.ts +57 -0
- package/src/cli/commands/bundle.ts +237 -0
- package/src/cli/commands/list.ts +109 -0
- package/src/cli/config-schema.ts +36 -0
- package/src/cli/index.ts +50 -0
- package/src/cli/output-generator.ts +63 -0
- package/src/downloader/index.ts +248 -0
- package/src/downloader/types.ts +48 -0
- package/src/index.ts +8 -0
- package/src/schemas/functions/adjust_chroma/adjust-chroma.tokenscript +27 -0
- package/src/schemas/functions/adjust_chroma/schema.json +48 -0
- package/src/schemas/functions/adjust_chroma/unit.test.ts +76 -0
- package/src/schemas/functions/adjust_hue/adjust-hue.tokenscript +32 -0
- package/src/schemas/functions/adjust_hue/schema.json +48 -0
- package/src/schemas/functions/adjust_hue/unit.test.ts +68 -0
- package/src/schemas/functions/adjust_lightness/adjust-lightness.tokenscript +31 -0
- package/src/schemas/functions/adjust_lightness/schema.json +48 -0
- package/src/schemas/functions/adjust_lightness/unit.test.ts +88 -0
- package/src/schemas/functions/adjust_to_contrast/adjust-to-contrast.tokenscript +131 -0
- package/src/schemas/functions/adjust_to_contrast/schema.json +56 -0
- package/src/schemas/functions/adjust_to_contrast/unit.test.ts +81 -0
- package/src/schemas/functions/alpha_blend/alpha-blend.tokenscript +46 -0
- package/src/schemas/functions/alpha_blend/schema.json +28 -0
- package/src/schemas/functions/alpha_blend/unit.test.ts +135 -0
- package/src/schemas/functions/alpha_scale/alpha-scale.tokenscript +38 -0
- package/src/schemas/functions/alpha_scale/schema.json +24 -0
- package/src/schemas/functions/alpha_scale/unit.test.ts +50 -0
- package/src/schemas/functions/analogous/analogous.tokenscript +47 -0
- package/src/schemas/functions/analogous/schema.json +28 -0
- package/src/schemas/functions/analogous/unit.test.ts +64 -0
- package/src/schemas/functions/apca_contrast/apca-contrast.tokenscript +129 -0
- package/src/schemas/functions/apca_contrast/schema.json +24 -0
- package/src/schemas/functions/apca_contrast/unit.test.ts +259 -0
- package/src/schemas/functions/are_similar/are-similar.tokenscript +24 -0
- package/src/schemas/functions/are_similar/schema.json +57 -0
- package/src/schemas/functions/are_similar/unit.test.ts +57 -0
- package/src/schemas/functions/auto_text_color/auto-text-color.tokenscript +41 -0
- package/src/schemas/functions/auto_text_color/schema.json +53 -0
- package/src/schemas/functions/auto_text_color/unit.test.ts +122 -0
- package/src/schemas/functions/best_contrast/best-contrast.tokenscript +66 -0
- package/src/schemas/functions/best_contrast/schema.json +24 -0
- package/src/schemas/functions/best_contrast/unit.test.ts +64 -0
- package/src/schemas/functions/chroma/chroma.tokenscript +12 -0
- package/src/schemas/functions/chroma/schema.json +44 -0
- package/src/schemas/functions/chroma/unit.test.ts +86 -0
- package/src/schemas/functions/clamp_chroma/clamp-chroma.tokenscript +21 -0
- package/src/schemas/functions/clamp_chroma/schema.json +52 -0
- package/src/schemas/functions/clamp_chroma/unit.test.ts +60 -0
- package/src/schemas/functions/clamp_lightness/clamp-lightness.tokenscript +21 -0
- package/src/schemas/functions/clamp_lightness/schema.json +52 -0
- package/src/schemas/functions/clamp_lightness/unit.test.ts +76 -0
- package/src/schemas/functions/clamp_to_gamut/clamp-to-gamut.tokenscript +41 -0
- package/src/schemas/functions/clamp_to_gamut/schema.json +20 -0
- package/src/schemas/functions/clamp_to_gamut/unit.test.ts +167 -0
- package/src/schemas/functions/complement/complement.tokenscript +21 -0
- package/src/schemas/functions/complement/schema.json +20 -0
- package/src/schemas/functions/complement/unit.test.ts +81 -0
- package/src/schemas/functions/contrast_ratio/contrast-ratio.tokenscript +36 -0
- package/src/schemas/functions/contrast_ratio/schema.json +24 -0
- package/src/schemas/functions/contrast_ratio/unit.test.ts +91 -0
- package/src/schemas/functions/cooler/cooler.tokenscript +45 -0
- package/src/schemas/functions/cooler/schema.json +43 -0
- package/src/schemas/functions/cooler/unit.test.ts +69 -0
- package/src/schemas/functions/darken/darken.tokenscript +37 -0
- package/src/schemas/functions/darken/schema.json +24 -0
- package/src/schemas/functions/darken/unit.test.ts +105 -0
- package/src/schemas/functions/delta_e_2000/delta-e-2000.tokenscript +184 -0
- package/src/schemas/functions/delta_e_2000/schema.json +36 -0
- package/src/schemas/functions/delta_e_2000/unit.test.ts +243 -0
- package/src/schemas/functions/delta_e_76/delta-e-76.tokenscript +45 -0
- package/src/schemas/functions/delta_e_76/schema.json +24 -0
- package/src/schemas/functions/delta_e_76/unit.test.ts +123 -0
- package/src/schemas/functions/delta_e_ok/delta-e-ok.tokenscript +43 -0
- package/src/schemas/functions/delta_e_ok/schema.json +24 -0
- package/src/schemas/functions/delta_e_ok/unit.test.ts +235 -0
- package/src/schemas/functions/desaturate/desaturate.tokenscript +32 -0
- package/src/schemas/functions/desaturate/schema.json +24 -0
- package/src/schemas/functions/desaturate/unit.test.ts +54 -0
- package/src/schemas/functions/distributed/distributed.tokenscript +54 -0
- package/src/schemas/functions/distributed/schema.json +32 -0
- package/src/schemas/functions/distributed/unit.test.ts +58 -0
- package/src/schemas/functions/diverging/diverging.tokenscript +58 -0
- package/src/schemas/functions/diverging/schema.json +32 -0
- package/src/schemas/functions/diverging/unit.test.ts +70 -0
- package/src/schemas/functions/grayscale/grayscale.tokenscript +17 -0
- package/src/schemas/functions/grayscale/schema.json +20 -0
- package/src/schemas/functions/grayscale/unit.test.ts +79 -0
- package/src/schemas/functions/harmonize/harmonize.tokenscript +61 -0
- package/src/schemas/functions/harmonize/schema.json +52 -0
- package/src/schemas/functions/harmonize/unit.test.ts +56 -0
- package/src/schemas/functions/hue/hue.tokenscript +12 -0
- package/src/schemas/functions/hue/schema.json +44 -0
- package/src/schemas/functions/hue/unit.test.ts +75 -0
- package/src/schemas/functions/hue_difference/hue-difference.tokenscript +42 -0
- package/src/schemas/functions/hue_difference/schema.json +24 -0
- package/src/schemas/functions/hue_difference/unit.test.ts +125 -0
- package/src/schemas/functions/in_gamut/in-gamut.tokenscript +51 -0
- package/src/schemas/functions/in_gamut/schema.json +24 -0
- package/src/schemas/functions/in_gamut/unit.test.ts +178 -0
- package/src/schemas/functions/interpolate/interpolate.tokenscript +61 -0
- package/src/schemas/functions/interpolate/schema.json +52 -0
- package/src/schemas/functions/interpolate/unit.test.ts +96 -0
- package/src/schemas/functions/invert/invert-initializer.tokenscript +29 -0
- package/src/schemas/functions/invert/schema.json +20 -0
- package/src/schemas/functions/invert/unit.test.ts +216 -0
- package/src/schemas/functions/is_cool/is-cool.tokenscript +41 -0
- package/src/schemas/functions/is_cool/schema.json +20 -0
- package/src/schemas/functions/is_cool/unit.test.ts +189 -0
- package/src/schemas/functions/is_dark/is-dark.tokenscript +16 -0
- package/src/schemas/functions/is_dark/schema.json +24 -0
- package/src/schemas/functions/is_dark/unit.test.ts +87 -0
- package/src/schemas/functions/is_light/is-light.tokenscript +16 -0
- package/src/schemas/functions/is_light/schema.json +24 -0
- package/src/schemas/functions/is_light/unit.test.ts +86 -0
- package/src/schemas/functions/is_neutral/is-neutral.tokenscript +16 -0
- package/src/schemas/functions/is_neutral/schema.json +53 -0
- package/src/schemas/functions/is_neutral/unit.test.ts +85 -0
- package/src/schemas/functions/is_warm/is-warm.tokenscript +62 -0
- package/src/schemas/functions/is_warm/schema.json +20 -0
- package/src/schemas/functions/is_warm/unit.test.ts +161 -0
- package/src/schemas/functions/lighten/lighten.tokenscript +37 -0
- package/src/schemas/functions/lighten/schema.json +24 -0
- package/src/schemas/functions/lighten/unit.test.ts +109 -0
- package/src/schemas/functions/lightness/lightness.tokenscript +12 -0
- package/src/schemas/functions/lightness/schema.json +49 -0
- package/src/schemas/functions/lightness/unit.test.ts +99 -0
- package/src/schemas/functions/luminance/luminance.tokenscript +16 -0
- package/src/schemas/functions/luminance/schema.json +20 -0
- package/src/schemas/functions/luminance/unit.test.ts +105 -0
- package/src/schemas/functions/meets_contrast/meets-contrast.tokenscript +49 -0
- package/src/schemas/functions/meets_contrast/schema.json +28 -0
- package/src/schemas/functions/meets_contrast/unit.test.ts +170 -0
- package/src/schemas/functions/mix/mix.tokenscript +47 -0
- package/src/schemas/functions/mix/schema.json +28 -0
- package/src/schemas/functions/mix/unit.test.ts +95 -0
- package/src/schemas/functions/monochromatic/monochromatic.tokenscript +72 -0
- package/src/schemas/functions/monochromatic/schema.json +24 -0
- package/src/schemas/functions/monochromatic/unit.test.ts +91 -0
- package/src/schemas/functions/muted/muted.tokenscript +25 -0
- package/src/schemas/functions/muted/schema.json +48 -0
- package/src/schemas/functions/muted/unit.test.ts +100 -0
- package/src/schemas/functions/neutral_variant/neutral-variant.tokenscript +23 -0
- package/src/schemas/functions/neutral_variant/schema.json +48 -0
- package/src/schemas/functions/neutral_variant/unit.test.ts +102 -0
- package/src/schemas/functions/relative_luminance/relative-luminance.tokenscript +15 -0
- package/src/schemas/functions/relative_luminance/schema.json +49 -0
- package/src/schemas/functions/relative_luminance/unit.test.ts +104 -0
- package/src/schemas/functions/rotate_hue/rotate-hue.tokenscript +20 -0
- package/src/schemas/functions/rotate_hue/schema.json +24 -0
- package/src/schemas/functions/rotate_hue/unit.test.ts +86 -0
- package/src/schemas/functions/saturate/saturate.tokenscript +33 -0
- package/src/schemas/functions/saturate/schema.json +24 -0
- package/src/schemas/functions/saturate/unit.test.ts +59 -0
- package/src/schemas/functions/scale_chroma/scale-chroma.tokenscript +22 -0
- package/src/schemas/functions/scale_chroma/schema.json +48 -0
- package/src/schemas/functions/scale_chroma/unit.test.ts +79 -0
- package/src/schemas/functions/scale_lightness/scale-lightness.tokenscript +23 -0
- package/src/schemas/functions/scale_lightness/schema.json +48 -0
- package/src/schemas/functions/scale_lightness/unit.test.ts +73 -0
- package/src/schemas/functions/sepia/schema.json +48 -0
- package/src/schemas/functions/sepia/sepia.tokenscript +54 -0
- package/src/schemas/functions/sepia/unit.test.ts +88 -0
- package/src/schemas/functions/set_chroma/schema.json +24 -0
- package/src/schemas/functions/set_chroma/set-chroma.tokenscript +18 -0
- package/src/schemas/functions/set_chroma/unit.test.ts +79 -0
- package/src/schemas/functions/set_hue/schema.json +24 -0
- package/src/schemas/functions/set_hue/set-hue.tokenscript +18 -0
- package/src/schemas/functions/set_hue/unit.test.ts +90 -0
- package/src/schemas/functions/set_lightness/schema.json +24 -0
- package/src/schemas/functions/set_lightness/set-lightness.tokenscript +18 -0
- package/src/schemas/functions/set_lightness/unit.test.ts +80 -0
- package/src/schemas/functions/shade_scale/schema.json +24 -0
- package/src/schemas/functions/shade_scale/shade-scale.tokenscript +61 -0
- package/src/schemas/functions/shade_scale/unit.test.ts +64 -0
- package/src/schemas/functions/split_complement/schema.json +24 -0
- package/src/schemas/functions/split_complement/split-complement.tokenscript +38 -0
- package/src/schemas/functions/split_complement/unit.test.ts +53 -0
- package/src/schemas/functions/steps/schema.json +28 -0
- package/src/schemas/functions/steps/steps.tokenscript +54 -0
- package/src/schemas/functions/steps/unit.test.ts +71 -0
- package/src/schemas/functions/tetradic/schema.json +20 -0
- package/src/schemas/functions/tetradic/tetradic.tokenscript +40 -0
- package/src/schemas/functions/tetradic/unit.test.ts +50 -0
- package/src/schemas/functions/tint_scale/schema.json +32 -0
- package/src/schemas/functions/tint_scale/tint-scale.tokenscript +71 -0
- package/src/schemas/functions/tint_scale/unit.test.ts +64 -0
- package/src/schemas/functions/to_gamut/schema.json +48 -0
- package/src/schemas/functions/to_gamut/to-gamut.tokenscript +96 -0
- package/src/schemas/functions/to_gamut/unit.test.ts +97 -0
- package/src/schemas/functions/triadic/schema.json +20 -0
- package/src/schemas/functions/triadic/triadic.tokenscript +33 -0
- package/src/schemas/functions/triadic/unit.test.ts +64 -0
- package/src/schemas/functions/vibrant/schema.json +48 -0
- package/src/schemas/functions/vibrant/unit.test.ts +55 -0
- package/src/schemas/functions/vibrant/vibrant.tokenscript +29 -0
- package/src/schemas/functions/warmer/schema.json +43 -0
- package/src/schemas/functions/warmer/unit.test.ts +69 -0
- package/src/schemas/functions/warmer/warmer.tokenscript +45 -0
- package/src/schemas/functions/wcag_level/schema.json +48 -0
- package/src/schemas/functions/wcag_level/unit.test.ts +75 -0
- package/src/schemas/functions/wcag_level/wcag-level.tokenscript +50 -0
- package/src/schemas/types/css-color/from-hsl-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-hwb-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-lab-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-lch-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-oklab-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-oklch-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-p3-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-rgb-color.tokenscript +15 -0
- package/src/schemas/types/css-color/from-srgb-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-srgb-linear-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-xyz-d50-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-xyz-d65-color.tokenscript +16 -0
- package/src/schemas/types/css-color/initializer.tokenscript +13 -0
- package/src/schemas/types/css-color/schema.json +148 -0
- package/src/schemas/types/css-color/unit.test.ts +402 -0
- package/src/schemas/types/hex-color/initializer.tokenscript +3 -0
- package/src/schemas/types/hex-color/schema.json +24 -0
- package/src/schemas/types/hex-color/unit.test.ts +123 -0
- package/src/schemas/types/hsl-color/from-srgb.tokenscript +87 -0
- package/src/schemas/types/hsl-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hsl-color/schema.json +48 -0
- package/src/schemas/types/hsl-color/unit.test.ts +201 -0
- package/src/schemas/types/hsv-color/from-srgb.tokenscript +80 -0
- package/src/schemas/types/hsv-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hsv-color/schema.json +48 -0
- package/src/schemas/types/hsv-color/unit.test.ts +162 -0
- package/src/schemas/types/hwb-color/from-hsv.tokenscript +31 -0
- package/src/schemas/types/hwb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hwb-color/schema.json +48 -0
- package/src/schemas/types/hwb-color/unit.test.ts +150 -0
- package/src/schemas/types/lab-color/from-xyz-d50.tokenscript +78 -0
- package/src/schemas/types/lab-color/initializer.tokenscript +16 -0
- package/src/schemas/types/lab-color/schema.json +48 -0
- package/src/schemas/types/lab-color/unit.test.ts +263 -0
- package/src/schemas/types/lch-color/from-lab.tokenscript +44 -0
- package/src/schemas/types/lch-color/initializer.tokenscript +16 -0
- package/src/schemas/types/lch-color/schema.json +48 -0
- package/src/schemas/types/lch-color/unit.test.ts +173 -0
- package/src/schemas/types/okhsl-color/from-oklab.tokenscript +410 -0
- package/src/schemas/types/okhsl-color/initializer.tokenscript +24 -0
- package/src/schemas/types/okhsl-color/schema.json +48 -0
- package/src/schemas/types/okhsl-color/unit.test.ts +514 -0
- package/src/schemas/types/okhsv-color/from-oklab.tokenscript +286 -0
- package/src/schemas/types/okhsv-color/initializer.tokenscript +24 -0
- package/src/schemas/types/okhsv-color/schema.json +48 -0
- package/src/schemas/types/okhsv-color/unit.test.ts +499 -0
- package/src/schemas/types/oklab-color/from-okhsl.tokenscript +195 -0
- package/src/schemas/types/oklab-color/from-okhsv.tokenscript +197 -0
- package/src/schemas/types/oklab-color/from-oklch.tokenscript +39 -0
- package/src/schemas/types/oklab-color/from-xyz-d65.tokenscript +43 -0
- package/src/schemas/types/oklab-color/initializer.tokenscript +16 -0
- package/src/schemas/types/oklab-color/schema.json +78 -0
- package/src/schemas/types/oklab-color/unit.test.ts +345 -0
- package/src/schemas/types/oklch-color/from-oklab.tokenscript +45 -0
- package/src/schemas/types/oklch-color/initializer.tokenscript +16 -0
- package/src/schemas/types/oklch-color/schema.json +48 -0
- package/src/schemas/types/oklch-color/unit.test.ts +267 -0
- package/src/schemas/types/p3-color/from-p3-linear.tokenscript +59 -0
- package/src/schemas/types/p3-color/initializer.tokenscript +16 -0
- package/src/schemas/types/p3-color/schema.json +48 -0
- package/src/schemas/types/p3-color/unit.test.ts +119 -0
- package/src/schemas/types/p3-linear-color/from-xyz-d65.tokenscript +47 -0
- package/src/schemas/types/p3-linear-color/initializer.tokenscript +16 -0
- package/src/schemas/types/p3-linear-color/schema.json +48 -0
- package/src/schemas/types/p3-linear-color/unit.test.ts +82 -0
- package/src/schemas/types/rgb-color/from-hex.tokenscript +43 -0
- package/src/schemas/types/rgb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/rgb-color/schema.json +55 -0
- package/src/schemas/types/rgb-color/to-hex.tokenscript +42 -0
- package/src/schemas/types/rgb-color/unit.test.ts +302 -0
- package/src/schemas/types/srgb-color/from-hsl.tokenscript +106 -0
- package/src/schemas/types/srgb-color/from-linear.tokenscript +58 -0
- package/src/schemas/types/srgb-color/from-rgb.tokenscript +20 -0
- package/src/schemas/types/srgb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/srgb-color/schema.json +68 -0
- package/src/schemas/types/srgb-color/unit.test.ts +303 -0
- package/src/schemas/types/srgb-linear-color/from-srgb.tokenscript +55 -0
- package/src/schemas/types/srgb-linear-color/from-xyz-d65.tokenscript +34 -0
- package/src/schemas/types/srgb-linear-color/initializer.tokenscript +13 -0
- package/src/schemas/types/srgb-linear-color/schema.json +58 -0
- package/src/schemas/types/srgb-linear-color/unit.test.ts +291 -0
- package/src/schemas/types/xyz-d50-color/from-xyz-d65.tokenscript +36 -0
- package/src/schemas/types/xyz-d50-color/initializer.tokenscript +16 -0
- package/src/schemas/types/xyz-d50-color/schema.json +48 -0
- package/src/schemas/types/xyz-d50-color/unit.test.ts +240 -0
- package/src/schemas/types/xyz-d65-color/from-linear-p3.tokenscript +47 -0
- package/src/schemas/types/xyz-d65-color/from-linear-srgb.tokenscript +38 -0
- package/src/schemas/types/xyz-d65-color/from-oklab.tokenscript +44 -0
- package/src/schemas/types/xyz-d65-color/initializer.tokenscript +16 -0
- package/src/schemas/types/xyz-d65-color/schema.json +68 -0
- package/src/schemas/types/xyz-d65-color/unit.test.ts +319 -0
- package/src/utils/schema-uri.ts +192 -0
- package/src/utils/type.ts +194 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Linear sRGB to sRGB Conversion
|
|
2
|
+
// Applies gamma correction (transfer function)
|
|
3
|
+
// Reference: IEC 61966-2-1:1999 (sRGB specification)
|
|
4
|
+
//
|
|
5
|
+
// Algorithm:
|
|
6
|
+
// if linear ≤ 0.0031308: srgb = linear * 12.92
|
|
7
|
+
// else: srgb = 1.055 * linear^(1/2.4) - 0.055
|
|
8
|
+
//
|
|
9
|
+
// Input: Color.LinearSRGB with r, g, b in linear 0-1 range
|
|
10
|
+
// Output: Color.SRGB with r, g, b in gamma-corrected 0-1 range
|
|
11
|
+
|
|
12
|
+
// Gamma correction constants (IEC 61966-2-1)
|
|
13
|
+
variable threshold: Number = 0.0031308;
|
|
14
|
+
variable linear_scale: Number = 12.92;
|
|
15
|
+
variable gamma_offset: Number = 0.055;
|
|
16
|
+
variable gamma_scale: Number = 1.055;
|
|
17
|
+
variable gamma_exponent: Number = 0.416666666666667;
|
|
18
|
+
|
|
19
|
+
// Get input linear values
|
|
20
|
+
variable linear_r: Number = {input}.r;
|
|
21
|
+
variable linear_g: Number = {input}.g;
|
|
22
|
+
variable linear_b: Number = {input}.b;
|
|
23
|
+
|
|
24
|
+
// Convert red channel
|
|
25
|
+
variable srgb_r: Number = 0;
|
|
26
|
+
if (linear_r <= threshold) [
|
|
27
|
+
srgb_r = linear_r * linear_scale;
|
|
28
|
+
] else [
|
|
29
|
+
srgb_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// Convert green channel
|
|
33
|
+
variable srgb_g: Number = 0;
|
|
34
|
+
if (linear_g <= threshold) [
|
|
35
|
+
srgb_g = linear_g * linear_scale;
|
|
36
|
+
] else [
|
|
37
|
+
srgb_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
// Convert blue channel
|
|
41
|
+
variable srgb_b: Number = 0;
|
|
42
|
+
if (linear_b <= threshold) [
|
|
43
|
+
srgb_b = linear_b * linear_scale;
|
|
44
|
+
] else [
|
|
45
|
+
srgb_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// Create output
|
|
49
|
+
variable output: Color.SRGB;
|
|
50
|
+
output.r = srgb_r;
|
|
51
|
+
output.g = srgb_g;
|
|
52
|
+
output.b = srgb_b;
|
|
53
|
+
|
|
54
|
+
return output;
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// RGB to sRGB Conversion
|
|
2
|
+
// Converts RGB (0-255) to sRGB (0-1) by normalizing
|
|
3
|
+
// Input: Color.Rgb with r, g, b in 0-255 range
|
|
4
|
+
// Output: Color.SRGB with r, g, b in 0-1 range
|
|
5
|
+
// Lossless: Yes (simple division)
|
|
6
|
+
|
|
7
|
+
variable r_normalized: Number = {input}.r / 255;
|
|
8
|
+
variable g_normalized: Number = {input}.g / 255;
|
|
9
|
+
variable b_normalized: Number = {input}.b / 255;
|
|
10
|
+
|
|
11
|
+
variable output: Color.SRGB;
|
|
12
|
+
output.r = r_normalized;
|
|
13
|
+
output.g = g_normalized;
|
|
14
|
+
output.b = b_normalized;
|
|
15
|
+
|
|
16
|
+
return output;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// sRGB Color Initializer
|
|
2
|
+
// Creates an sRGB color from normalized 0-1 values
|
|
3
|
+
// Input: List of [r, g, b] values in 0-1 range
|
|
4
|
+
|
|
5
|
+
variable color_values: List = {input};
|
|
6
|
+
variable output: Color.SRGB;
|
|
7
|
+
|
|
8
|
+
output.r = color_values.get(0);
|
|
9
|
+
output.g = color_values.get(1);
|
|
10
|
+
output.b = color_values.get(2);
|
|
11
|
+
|
|
12
|
+
return output;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "SRGB",
|
|
3
|
+
"type": "color",
|
|
4
|
+
"description": "sRGB color space with normalized 0-1 range. The standard color space for web and displays.",
|
|
5
|
+
"schema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"r": {
|
|
9
|
+
"type": "number",
|
|
10
|
+
"description": "Red channel (0-1)"
|
|
11
|
+
},
|
|
12
|
+
"g": {
|
|
13
|
+
"type": "number",
|
|
14
|
+
"description": "Green channel (0-1)"
|
|
15
|
+
},
|
|
16
|
+
"b": {
|
|
17
|
+
"type": "number",
|
|
18
|
+
"description": "Blue channel (0-1)"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["r", "g", "b"],
|
|
22
|
+
"order": ["r", "g", "b"],
|
|
23
|
+
"additionalProperties": false
|
|
24
|
+
},
|
|
25
|
+
"initializers": [
|
|
26
|
+
{
|
|
27
|
+
"title": "sRGB Color Initializer",
|
|
28
|
+
"keyword": "srgb",
|
|
29
|
+
"description": "Creates an sRGB color from normalized 0-1 values",
|
|
30
|
+
"script": {
|
|
31
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
32
|
+
"script": "./initializer.tokenscript"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"conversions": [
|
|
37
|
+
{
|
|
38
|
+
"source": "/api/v1/core/rgb-color/0/",
|
|
39
|
+
"target": "$self",
|
|
40
|
+
"description": "Converts RGB (0-255) to sRGB (0-1) by normalizing",
|
|
41
|
+
"lossless": true,
|
|
42
|
+
"script": {
|
|
43
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
44
|
+
"script": "./from-rgb.tokenscript"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"source": "/api/v1/core/hsl-color/0/",
|
|
49
|
+
"target": "$self",
|
|
50
|
+
"description": "Converts HSL to sRGB",
|
|
51
|
+
"lossless": true,
|
|
52
|
+
"script": {
|
|
53
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
54
|
+
"script": "./from-hsl.tokenscript"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"source": "/api/v1/core/srgb-linear-color/0/",
|
|
59
|
+
"target": "$self",
|
|
60
|
+
"description": "Converts Linear sRGB to sRGB by applying gamma correction",
|
|
61
|
+
"lossless": true,
|
|
62
|
+
"script": {
|
|
63
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
64
|
+
"script": "./from-linear.tokenscript"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sRGB Color Schema Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the sRGB color space (normalized 0-1 range)
|
|
5
|
+
* Validates against ColorJS for parity
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { log } from "@tests/helpers/logger";
|
|
9
|
+
import { executeWithSchema, getBundledSchema } from "@tests/helpers/schema-test-utils";
|
|
10
|
+
import Color from "colorjs.io";
|
|
11
|
+
import { describe, expect, it } from "vitest";
|
|
12
|
+
import type { ColorSpecification } from "@/bundler/types";
|
|
13
|
+
|
|
14
|
+
// ColorJS reference tolerance
|
|
15
|
+
const TOLERANCE = 1e-10;
|
|
16
|
+
|
|
17
|
+
describe("sRGB Color Schema", () => {
|
|
18
|
+
describe("Schema Definition", () => {
|
|
19
|
+
it("should have correct schema structure", async () => {
|
|
20
|
+
const schema = (await getBundledSchema("srgb-color")) as ColorSpecification;
|
|
21
|
+
|
|
22
|
+
expect(schema.name).toBe("SRGB");
|
|
23
|
+
expect(schema.type).toBe("color");
|
|
24
|
+
expect(schema.schema).toBeDefined();
|
|
25
|
+
expect(schema.schema?.properties).toHaveProperty("r");
|
|
26
|
+
expect(schema.schema?.properties).toHaveProperty("g");
|
|
27
|
+
expect(schema.schema?.properties).toHaveProperty("b");
|
|
28
|
+
expect(schema.schema?.required).toEqual(["r", "g", "b"]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should have srgb initializer", async () => {
|
|
32
|
+
const schema = (await getBundledSchema("srgb-color")) as ColorSpecification;
|
|
33
|
+
|
|
34
|
+
expect(schema.initializers).toHaveLength(1);
|
|
35
|
+
expect(schema.initializers[0].keyword).toBe("srgb");
|
|
36
|
+
expect(schema.initializers[0].script.script).toContain("Color.SRGB");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should have conversion from RGB", async () => {
|
|
40
|
+
const schema = (await getBundledSchema("srgb-color")) as ColorSpecification;
|
|
41
|
+
|
|
42
|
+
expect(schema.conversions.length).toBeGreaterThanOrEqual(1);
|
|
43
|
+
|
|
44
|
+
const rgbToSrgb = schema.conversions.find((c: { source: string }) =>
|
|
45
|
+
c.source.includes("rgb-color"),
|
|
46
|
+
);
|
|
47
|
+
expect(rgbToSrgb).toBeDefined();
|
|
48
|
+
expect(rgbToSrgb?.lossless).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("Initialization", () => {
|
|
53
|
+
it("should create sRGB color from normalized values", async () => {
|
|
54
|
+
const result = await executeWithSchema(
|
|
55
|
+
"srgb-color",
|
|
56
|
+
"type",
|
|
57
|
+
`
|
|
58
|
+
variable c: Color.SRGB;
|
|
59
|
+
c.r = 1.0;
|
|
60
|
+
c.g = 0.5;
|
|
61
|
+
c.b = 0.25;
|
|
62
|
+
c
|
|
63
|
+
`,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
expect(result?.constructor.name).toBe("ColorSymbol");
|
|
67
|
+
expect((result as any).subType).toBe("SRGB");
|
|
68
|
+
expect((result as any).value.r.value).toBeCloseTo(1.0, 10);
|
|
69
|
+
expect((result as any).value.g.value).toBeCloseTo(0.5, 10);
|
|
70
|
+
expect((result as any).value.b.value).toBeCloseTo(0.25, 10);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("should handle black (0, 0, 0)", async () => {
|
|
74
|
+
const result = await executeWithSchema(
|
|
75
|
+
"srgb-color",
|
|
76
|
+
"type",
|
|
77
|
+
`
|
|
78
|
+
variable c: Color.SRGB;
|
|
79
|
+
c.r = 0;
|
|
80
|
+
c.g = 0;
|
|
81
|
+
c.b = 0;
|
|
82
|
+
c
|
|
83
|
+
`,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
expect((result as any).value.r.value).toBe(0);
|
|
87
|
+
expect((result as any).value.g.value).toBe(0);
|
|
88
|
+
expect((result as any).value.b.value).toBe(0);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should handle white (1, 1, 1)", async () => {
|
|
92
|
+
const result = await executeWithSchema(
|
|
93
|
+
"srgb-color",
|
|
94
|
+
"type",
|
|
95
|
+
`
|
|
96
|
+
variable c: Color.SRGB;
|
|
97
|
+
c.r = 1;
|
|
98
|
+
c.g = 1;
|
|
99
|
+
c.b = 1;
|
|
100
|
+
c
|
|
101
|
+
`,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
expect((result as any).value.r.value).toBe(1);
|
|
105
|
+
expect((result as any).value.g.value).toBe(1);
|
|
106
|
+
expect((result as any).value.b.value).toBe(1);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe("Conversion from RGB (0-255) to sRGB (0-1)", () => {
|
|
111
|
+
it("should convert RGB red to sRGB", async () => {
|
|
112
|
+
const result = await executeWithSchema(
|
|
113
|
+
"srgb-color",
|
|
114
|
+
"type",
|
|
115
|
+
`
|
|
116
|
+
variable rgb: Color.Rgb;
|
|
117
|
+
rgb.r = 255;
|
|
118
|
+
rgb.g = 0;
|
|
119
|
+
rgb.b = 0;
|
|
120
|
+
rgb.to.srgb()
|
|
121
|
+
`,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// ColorJS reference
|
|
125
|
+
const colorJS = new Color("srgb", [1, 0, 0]);
|
|
126
|
+
|
|
127
|
+
expect(result?.constructor.name).toBe("ColorSymbol");
|
|
128
|
+
expect((result as any).subType).toBe("SRGB");
|
|
129
|
+
expect((result as any).value.r.value).toBeCloseTo(colorJS.coords[0], 10);
|
|
130
|
+
expect((result as any).value.g.value).toBeCloseTo(colorJS.coords[1], 10);
|
|
131
|
+
expect((result as any).value.b.value).toBeCloseTo(colorJS.coords[2], 10);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should convert RGB green to sRGB", async () => {
|
|
135
|
+
const result = await executeWithSchema(
|
|
136
|
+
"srgb-color",
|
|
137
|
+
"type",
|
|
138
|
+
`
|
|
139
|
+
variable rgb: Color.Rgb;
|
|
140
|
+
rgb.r = 0;
|
|
141
|
+
rgb.g = 255;
|
|
142
|
+
rgb.b = 0;
|
|
143
|
+
rgb.to.srgb()
|
|
144
|
+
`,
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const colorJS = new Color("srgb", [0, 1, 0]);
|
|
148
|
+
|
|
149
|
+
expect((result as any).value.r.value).toBeCloseTo(colorJS.coords[0], 10);
|
|
150
|
+
expect((result as any).value.g.value).toBeCloseTo(colorJS.coords[1], 10);
|
|
151
|
+
expect((result as any).value.b.value).toBeCloseTo(colorJS.coords[2], 10);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("should convert RGB blue to sRGB", async () => {
|
|
155
|
+
const result = await executeWithSchema(
|
|
156
|
+
"srgb-color",
|
|
157
|
+
"type",
|
|
158
|
+
`
|
|
159
|
+
variable rgb: Color.Rgb;
|
|
160
|
+
rgb.r = 0;
|
|
161
|
+
rgb.g = 0;
|
|
162
|
+
rgb.b = 255;
|
|
163
|
+
rgb.to.srgb()
|
|
164
|
+
`,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
const colorJS = new Color("srgb", [0, 0, 1]);
|
|
168
|
+
|
|
169
|
+
expect((result as any).value.r.value).toBeCloseTo(colorJS.coords[0], 10);
|
|
170
|
+
expect((result as any).value.g.value).toBeCloseTo(colorJS.coords[1], 10);
|
|
171
|
+
expect((result as any).value.b.value).toBeCloseTo(colorJS.coords[2], 10);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("should convert mid-gray RGB to sRGB", async () => {
|
|
175
|
+
const result = await executeWithSchema(
|
|
176
|
+
"srgb-color",
|
|
177
|
+
"type",
|
|
178
|
+
`
|
|
179
|
+
variable rgb: Color.Rgb;
|
|
180
|
+
rgb.r = 128;
|
|
181
|
+
rgb.g = 128;
|
|
182
|
+
rgb.b = 128;
|
|
183
|
+
rgb.to.srgb()
|
|
184
|
+
`,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// 128/255 ≈ 0.50196
|
|
188
|
+
const expected = 128 / 255;
|
|
189
|
+
|
|
190
|
+
expect((result as any).value.r.value).toBeCloseTo(expected, 10);
|
|
191
|
+
expect((result as any).value.g.value).toBeCloseTo(expected, 10);
|
|
192
|
+
expect((result as any).value.b.value).toBeCloseTo(expected, 10);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("should convert coral (#ff5733) RGB to sRGB", async () => {
|
|
196
|
+
const result = await executeWithSchema(
|
|
197
|
+
"srgb-color",
|
|
198
|
+
"type",
|
|
199
|
+
`
|
|
200
|
+
variable rgb: Color.Rgb;
|
|
201
|
+
rgb.r = 255;
|
|
202
|
+
rgb.g = 87;
|
|
203
|
+
rgb.b = 51;
|
|
204
|
+
rgb.to.srgb()
|
|
205
|
+
`,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// ColorJS reference
|
|
209
|
+
const colorJS = new Color("#ff5733");
|
|
210
|
+
|
|
211
|
+
expect((result as any).value.r.value).toBeCloseTo(colorJS.coords[0], 5);
|
|
212
|
+
expect((result as any).value.g.value).toBeCloseTo(colorJS.coords[1], 5);
|
|
213
|
+
expect((result as any).value.b.value).toBeCloseTo(colorJS.coords[2], 5);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe("ColorJS Parity", () => {
|
|
218
|
+
const testCases = [
|
|
219
|
+
{ name: "red", rgb: [255, 0, 0], srgb: [1, 0, 0] },
|
|
220
|
+
{ name: "green", rgb: [0, 255, 0], srgb: [0, 1, 0] },
|
|
221
|
+
{ name: "blue", rgb: [0, 0, 255], srgb: [0, 0, 1] },
|
|
222
|
+
{ name: "black", rgb: [0, 0, 0], srgb: [0, 0, 0] },
|
|
223
|
+
{ name: "white", rgb: [255, 255, 255], srgb: [1, 1, 1] },
|
|
224
|
+
{ name: "gray", rgb: [128, 128, 128], srgb: [128 / 255, 128 / 255, 128 / 255] },
|
|
225
|
+
{ name: "coral", rgb: [255, 87, 51], srgb: [1, 87 / 255, 51 / 255] },
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
for (const { name, rgb, srgb } of testCases) {
|
|
229
|
+
it(`should match ColorJS for ${name}`, async () => {
|
|
230
|
+
const result = await executeWithSchema(
|
|
231
|
+
"srgb-color",
|
|
232
|
+
"type",
|
|
233
|
+
`
|
|
234
|
+
variable rgb: Color.Rgb;
|
|
235
|
+
rgb.r = ${rgb[0]};
|
|
236
|
+
rgb.g = ${rgb[1]};
|
|
237
|
+
rgb.b = ${rgb[2]};
|
|
238
|
+
rgb.to.srgb()
|
|
239
|
+
`,
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// ColorJS reference
|
|
243
|
+
const colorJS = new Color("srgb", srgb as [number, number, number]);
|
|
244
|
+
|
|
245
|
+
const tsR = (result as any).value.r.value;
|
|
246
|
+
const tsG = (result as any).value.g.value;
|
|
247
|
+
const tsB = (result as any).value.b.value;
|
|
248
|
+
|
|
249
|
+
const diffR = Math.abs(tsR - colorJS.coords[0]);
|
|
250
|
+
const diffG = Math.abs(tsG - colorJS.coords[1]);
|
|
251
|
+
const diffB = Math.abs(tsB - colorJS.coords[2]);
|
|
252
|
+
const maxDiff = Math.max(diffR, diffG, diffB);
|
|
253
|
+
|
|
254
|
+
// Log for documentation (only shown when LOG_LEVEL is set)
|
|
255
|
+
log.info(`\n=== ${name.toUpperCase()} ColorJS Parity ===`);
|
|
256
|
+
log.info(`TokenScript: { r: ${tsR}, g: ${tsG}, b: ${tsB} }`);
|
|
257
|
+
log.info(
|
|
258
|
+
`ColorJS: { r: ${colorJS.coords[0]}, g: ${colorJS.coords[1]}, b: ${colorJS.coords[2]} }`,
|
|
259
|
+
);
|
|
260
|
+
log.info(`Max Diff: ${maxDiff.toExponential(2)}`);
|
|
261
|
+
log.info(`Status: ${maxDiff < TOLERANCE ? "✅ PASS" : "❌ FAIL"}`);
|
|
262
|
+
|
|
263
|
+
expect(maxDiff).toBeLessThan(TOLERANCE);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
describe("Edge Cases", () => {
|
|
269
|
+
it("should handle very small values", async () => {
|
|
270
|
+
const result = await executeWithSchema(
|
|
271
|
+
"srgb-color",
|
|
272
|
+
"type",
|
|
273
|
+
`
|
|
274
|
+
variable rgb: Color.Rgb;
|
|
275
|
+
rgb.r = 1;
|
|
276
|
+
rgb.g = 1;
|
|
277
|
+
rgb.b = 1;
|
|
278
|
+
rgb.to.srgb()
|
|
279
|
+
`,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
const expected = 1 / 255;
|
|
283
|
+
expect((result as any).value.r.value).toBeCloseTo(expected, 10);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it("should handle near-max values", async () => {
|
|
287
|
+
const result = await executeWithSchema(
|
|
288
|
+
"srgb-color",
|
|
289
|
+
"type",
|
|
290
|
+
`
|
|
291
|
+
variable rgb: Color.Rgb;
|
|
292
|
+
rgb.r = 254;
|
|
293
|
+
rgb.g = 254;
|
|
294
|
+
rgb.b = 254;
|
|
295
|
+
rgb.to.srgb()
|
|
296
|
+
`,
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
const expected = 254 / 255;
|
|
300
|
+
expect((result as any).value.r.value).toBeCloseTo(expected, 10);
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// sRGB to Linear sRGB Conversion
|
|
2
|
+
// Removes gamma correction (inverse transfer function)
|
|
3
|
+
// Reference: IEC 61966-2-1:1999 (sRGB specification)
|
|
4
|
+
//
|
|
5
|
+
// Algorithm:
|
|
6
|
+
// if srgb ≤ 0.04045: linear = srgb / 12.92
|
|
7
|
+
// else: linear = ((srgb + 0.055) / 1.055) ^ 2.4
|
|
8
|
+
//
|
|
9
|
+
// Input: Color.SRGB with r, g, b in 0-1 range
|
|
10
|
+
// Output: Color.LinearSRGB with r, g, b in linear 0-1 range
|
|
11
|
+
|
|
12
|
+
// Gamma correction constants (IEC 61966-2-1)
|
|
13
|
+
variable threshold: Number = 0.04045;
|
|
14
|
+
variable linear_scale: Number = 12.92;
|
|
15
|
+
variable gamma_offset: Number = 0.055;
|
|
16
|
+
variable gamma_scale: Number = 1.055;
|
|
17
|
+
variable gamma_exponent: Number = 2.4;
|
|
18
|
+
|
|
19
|
+
// Get input sRGB values
|
|
20
|
+
variable srgb_r: Number = {input}.r;
|
|
21
|
+
variable srgb_g: Number = {input}.g;
|
|
22
|
+
variable srgb_b: Number = {input}.b;
|
|
23
|
+
|
|
24
|
+
// Convert red channel
|
|
25
|
+
variable linear_r: Number = 0;
|
|
26
|
+
if (srgb_r <= threshold) [
|
|
27
|
+
linear_r = srgb_r / linear_scale;
|
|
28
|
+
] else [
|
|
29
|
+
linear_r = pow((srgb_r + gamma_offset) / gamma_scale, gamma_exponent);
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// Convert green channel
|
|
33
|
+
variable linear_g: Number = 0;
|
|
34
|
+
if (srgb_g <= threshold) [
|
|
35
|
+
linear_g = srgb_g / linear_scale;
|
|
36
|
+
] else [
|
|
37
|
+
linear_g = pow((srgb_g + gamma_offset) / gamma_scale, gamma_exponent);
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
// Convert blue channel
|
|
41
|
+
variable linear_b: Number = 0;
|
|
42
|
+
if (srgb_b <= threshold) [
|
|
43
|
+
linear_b = srgb_b / linear_scale;
|
|
44
|
+
] else [
|
|
45
|
+
linear_b = pow((srgb_b + gamma_offset) / gamma_scale, gamma_exponent);
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// Create output
|
|
49
|
+
variable output: Color.LinearSRGB;
|
|
50
|
+
output.r = linear_r;
|
|
51
|
+
output.g = linear_g;
|
|
52
|
+
output.b = linear_b;
|
|
53
|
+
|
|
54
|
+
return output;
|
|
55
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// XYZ-D65 to Linear sRGB Conversion
|
|
2
|
+
// Reference: ColorJS exact matrix values (extracted via unit vector conversion)
|
|
3
|
+
//
|
|
4
|
+
// Matrix (XYZ D65 to Linear sRGB):
|
|
5
|
+
// [ 3.2409699419045226, -1.537383177570094, -0.4986107602930034 ]
|
|
6
|
+
// [-0.9692436362808796, 1.8759675015077202, 0.04155505740717559]
|
|
7
|
+
// [ 0.05563007969699366, -0.20397695888897652, 1.0569715142428786]
|
|
8
|
+
//
|
|
9
|
+
// Input: Color.XYZD65 with x, y, z tristimulus values
|
|
10
|
+
// Output: Color.LinearSRGB with r, g, b in linear 0-1 range
|
|
11
|
+
|
|
12
|
+
// Get input XYZ values
|
|
13
|
+
variable x: Number = {input}.x;
|
|
14
|
+
variable y: Number = {input}.y;
|
|
15
|
+
variable z: Number = {input}.z;
|
|
16
|
+
|
|
17
|
+
// Apply inverse matrix transformation (ColorJS exact values)
|
|
18
|
+
// Row 1: R
|
|
19
|
+
variable linear_r: Number = 3.2409699419045226 * x + -1.537383177570094 * y + -0.4986107602930034 * z;
|
|
20
|
+
|
|
21
|
+
// Row 2: G
|
|
22
|
+
variable linear_g: Number = -0.9692436362808796 * x + 1.8759675015077202 * y + 0.04155505740717559 * z;
|
|
23
|
+
|
|
24
|
+
// Row 3: B
|
|
25
|
+
variable linear_b: Number = 0.05563007969699366 * x + -0.20397695888897652 * y + 1.0569715142428786 * z;
|
|
26
|
+
|
|
27
|
+
// Create output
|
|
28
|
+
variable output: Color.LinearSRGB;
|
|
29
|
+
output.r = linear_r;
|
|
30
|
+
output.g = linear_g;
|
|
31
|
+
output.b = linear_b;
|
|
32
|
+
|
|
33
|
+
return output;
|
|
34
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Linear sRGB Color Initializer
|
|
2
|
+
// Creates a linear sRGB color from linear 0-1 values
|
|
3
|
+
// Input: List of [r, g, b] linear values
|
|
4
|
+
|
|
5
|
+
variable color_values: List = {input};
|
|
6
|
+
variable output: Color.LinearSRGB;
|
|
7
|
+
|
|
8
|
+
output.r = color_values.get(0);
|
|
9
|
+
output.g = color_values.get(1);
|
|
10
|
+
output.b = color_values.get(2);
|
|
11
|
+
|
|
12
|
+
return output;
|
|
13
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "LinearSRGB",
|
|
3
|
+
"type": "color",
|
|
4
|
+
"description": "Linear sRGB color space (gamma-decoded). Used for matrix transformations to XYZ and other linear operations.",
|
|
5
|
+
"schema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"r": {
|
|
9
|
+
"type": "number",
|
|
10
|
+
"description": "Linear red channel (0-1)"
|
|
11
|
+
},
|
|
12
|
+
"g": {
|
|
13
|
+
"type": "number",
|
|
14
|
+
"description": "Linear green channel (0-1)"
|
|
15
|
+
},
|
|
16
|
+
"b": {
|
|
17
|
+
"type": "number",
|
|
18
|
+
"description": "Linear blue channel (0-1)"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["r", "g", "b"],
|
|
22
|
+
"order": ["r", "g", "b"],
|
|
23
|
+
"additionalProperties": false
|
|
24
|
+
},
|
|
25
|
+
"initializers": [
|
|
26
|
+
{
|
|
27
|
+
"title": "Linear sRGB Color Initializer",
|
|
28
|
+
"keyword": "linearsrgb",
|
|
29
|
+
"description": "Creates a linear sRGB color from linear 0-1 values",
|
|
30
|
+
"script": {
|
|
31
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
32
|
+
"script": "./initializer.tokenscript"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"conversions": [
|
|
37
|
+
{
|
|
38
|
+
"source": "/api/v1/core/srgb-color/0/",
|
|
39
|
+
"target": "$self",
|
|
40
|
+
"description": "Converts sRGB to Linear sRGB by removing gamma correction (IEC 61966-2-1)",
|
|
41
|
+
"lossless": true,
|
|
42
|
+
"script": {
|
|
43
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
44
|
+
"script": "./from-srgb.tokenscript"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"source": "/api/v1/core/xyz-d65-color/0/",
|
|
49
|
+
"target": "$self",
|
|
50
|
+
"description": "Converts XYZ-D65 to Linear sRGB using inverse transformation matrix",
|
|
51
|
+
"lossless": true,
|
|
52
|
+
"script": {
|
|
53
|
+
"type": "/api/v1/core/tokenscript/0/",
|
|
54
|
+
"script": "./from-xyz-d65.tokenscript"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|