diff --git a/docs/Project.toml b/docs/Project.toml
index fe5a86db..986a461d 100644
--- a/docs/Project.toml
+++ b/docs/Project.toml
@@ -1,4 +1,5 @@
[deps]
+Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
diff --git a/docs/crosssectionalcharts.jl b/docs/crosssectionalcharts.jl
new file mode 100644
index 00000000..f3521a43
--- /dev/null
+++ b/docs/crosssectionalcharts.jl
@@ -0,0 +1,259 @@
+
+module CrossSectionalCharts
+
+using Colors
+using Base64
+
+struct CrossSectionalChartSVG <: Main.SVG
+ buf::IOBuffer
+end
+
+struct Axis
+ index::Int # compornent index
+ label::String
+ range::AbstractRange
+end
+Base.first(a::Axis) = first(a.range)
+Base.last(a::Axis) = last(a.range)
+
+function crosssection(::Type{C};
+ x::Tuple=(1, "X", 0:1),
+ y::Tuple=(2, "Y", 0:1),
+ z::Tuple=(3, "Z", 0:1)) where C <: Color
+ crosssection(C, Axis(x...), Axis(y...), Axis(z...))
+end
+function crosssection(::Type{C}, x::Axis, y::Axis, z::Axis) where C <: Color
+ io = IOBuffer()
+ id = String(nameof(C))
+
+ write(io,
+ """
+ """)
+ CrossSectionalChartSVG(io)
+end
+
+
+function write_png(io::IO, cs::AbstractArray{T}) where T <: Color
+ buf = IOBuffer() # to calculate chunk CRCs
+ n = 16 # 16 x 16
+ u8(x) = write(buf, UInt8(x & 0xFF))
+ u16(x) = (u8((x & 0xFFFF)>>8); u8(x))
+ u32(x) = (u16((x & 0xFFFFFFFF)>>16); u16(x))
+ b(bstr) = write(buf, bstr)
+ function pallet(c::Color)
+ rgb24 = convert(RGB24,c)
+ u8(rgb24.color>>16); u8(rgb24.color>>8); u8(rgb24.color)
+ end
+ crct(x) = (for i = 1:8; x = x & 1==1 ? 0xEDB88320 ⊻ (x>>1) : x>>1 end; x)
+ table = UInt32[crct(i) for i = 0x00:0xFF]
+ function crc32()
+ seekstart(buf)
+ crc = 0xFFFFFFFF
+ while !eof(buf)
+ crc = (crc>>8) ⊻ table[(crc&0xFF) ⊻ read(buf, UInt8) + 1]
+ end
+ u32(crc ⊻ 0xFFFFFFFF)
+ end
+ flush() = write(io, take!(seekstart(buf)))
+
+ # The following is a pre-encoded 256-indexed-color PNG with size of 16x16.
+ # We only rewrite "pallets".
+ b(b"\x89PNG\x0D\x0A\x1A\x0A")
+ # Image header
+ u32(13); flush(); b(b"IHDR"); u32(n); u32(n); u8(8); u8(3); u8(0); u8(0); u8(0); crc32()
+ # Palette
+ u32(n * n * 3); flush();
+ b(b"PLTE")
+ for y = 1:n, x = 1:n
+ pallet(cs[y,x])
+ end
+ crc32()
+ # Image data
+ u32(58); flush(); b(b"IDAT")
+ b(b"\x78\xDA\x63\x64\x60\x44\x03\x02\xE8\x02\x0A\xE8\x02\x06\xE8\x02")
+ b(b"\x0E\xE8\x02\x01\xE8\x02\x09\xE8\x02\x05\xE8\x02\x0D\xE8\x02\x13")
+ b(b"\xD0\x05\x16\xA0\x0B\x6C\x40\x17\x38\x80\x2E\x70\x01\x5D\xE0\x01")
+ b(b"\xBA\xC0\x07\x34\x3E\x00\x54\x4D\x08\x81"); crc32()
+ # Image trailer
+ u32(0); flush(); b(b"IEND"); crc32()
+ flush()
+end
+
+"""
+# Image data
+using CodecZlib
+raw = IOBuffer()
+for y = 0:15
+ write(raw, UInt8(1)) # filter: SUB
+ write(raw, UInt8(y*16)) # line head
+ write(raw, UInt8[1 for i=1:15]) # left + 1
+end
+flush(raw)
+cd = ZlibCompressorStream(raw,level=9)
+flush(cd)
+seekstart(cd)
+@show read(cd) # UInt8[0x78, 0xda, 0x63, 0x64, ...
+"""
+
+crosssection(::Type{HSV}) = crosssection(HSV, x=(2, "S", 0:1),
+ y=(3, "V", 0:1),
+ z=(1, "H", 0:360))
+crosssection(::Type{HSL}) = crosssection(HSL, x=(2, "S", 0:1),
+ y=(3, "L", 0:1),
+ z=(1, "H", 0:360))
+crosssection(::Type{HSI}) = crosssection(HSI, x=(2, "S", 0:1),
+ y=(3, "I", 0:1),
+ z=(1, "H", 0:360))
+
+crosssection(::Type{Lab}) = crosssection(Lab, x=(2, "a*", -100:100),
+ y=(3, "b*", -100:100),
+ z=(1, "L*", 0:100))
+crosssection(::Type{Luv}) = crosssection(Luv, x=(2, "u*", -100:100),
+ y=(3, "v*", -100:100),
+ z=(1, "L*", 0:100))
+crosssection(::Type{LCHab}) = crosssection(LCHab, x=(2, "C*", 0:100),
+ y=(1, "L*", 0:100),
+ z=(3, "H", 0:360))
+crosssection(::Type{LCHuv}) = crosssection(LCHuv, x=(2, "C*", 0:100),
+ y=(1, "L*", 0:100),
+ z=(3, "H", 0:360))
+
+crosssection(::Type{YIQ}) = crosssection(YIQ, x=(2, "I", -1:1),
+ y=(3, "Q", -1:1),
+ z=(1, "Y", 0:1))
+crosssection(::Type{YCbCr}) = crosssection(YCbCr, x=(2, "Cb", 0:256),
+ y=(3, "Cr", 0:256),
+ z=(1, "Y", 0:256))
+end
diff --git a/docs/make.jl b/docs/make.jl
index 701b4c3c..556b14c8 100644
--- a/docs/make.jl
+++ b/docs/make.jl
@@ -6,6 +6,7 @@ function Base.show(io::IO, mime::MIME"image/svg+xml", svg::SVG)
flush(io)
end
+include("crosssectionalcharts.jl")
include("colormaps.jl")
include("namedcolorcharts.jl")
diff --git a/docs/src/advancedfunctions.md b/docs/src/advancedfunctions.md
index f4a0653f..c437bb6f 100644
--- a/docs/src/advancedfunctions.md
+++ b/docs/src/advancedfunctions.md
@@ -34,7 +34,7 @@ whitebalance
```
-## Simulation of color deficiency ("color blindness")
+## [Simulation of color deficiency ("color blindness")](@id color_deficiency)
Three functions are provided that map colors to a reduced gamut to simulate different types of *dichromacy*, the loss of one of the three types of human photopigments.
diff --git a/docs/src/colordifferences.md b/docs/src/colordifferences.md
index d4223983..cc23eed1 100644
--- a/docs/src/colordifferences.md
+++ b/docs/src/colordifferences.md
@@ -2,9 +2,7 @@
The `colordiff` function gives an approximate value for the difference between two colors.
-```jldoctest example
-julia> using Colors; #hide
-
+```jldoctest example; setup = :(using Colors)
julia> colordiff(colorant"red", parse(Colorant, HSV(360, 0.75, 1)))
8.178248292426845
```
diff --git a/docs/src/constructionandconversion.md b/docs/src/constructionandconversion.md
index e29db134..039e3f27 100644
--- a/docs/src/constructionandconversion.md
+++ b/docs/src/constructionandconversion.md
@@ -8,58 +8,148 @@ The colorspaces used by Colors are defined in [ColorTypes](https://github.com/Ju
- Red-Green-Blue spaces: `RGB`, `BGR`, `XRGB`, `RGBX`, `RGB24`, plus transparent versions `ARGB`, `RGBA`, `ABGR`, `BGRA`, and `ARGB32`.
- `HSV`, `HSL`, `HSI`, plus all 6 transparent variants (`AHSV`, `HSVA`, `AHSL`, `HSLA`, `AHSI`, `HSIA`)
-
+```@example cross
+using Colors # hide
+using Main: CrossSectionalCharts # hide
+CrossSectionalCharts.crosssection(HSV) # hide
+```
+```@example cross
+CrossSectionalCharts.crosssection(HSL) # hide
+```
+```@example cross
+CrossSectionalCharts.crosssection(HSI) # hide
+```
- `XYZ`, `xyY`, `LMS` and all 6 transparent variants
- `Lab`, `Luv`, `LCHab`, `LCHuv` and all 8 transparent variants
-
+```@example cross
+CrossSectionalCharts.crosssection(Lab) # hide
+```
+```@example cross
+CrossSectionalCharts.crosssection(Luv) # hide
+```
+```@example cross
+CrossSectionalCharts.crosssection(LCHab) # hide
+```
+```@example cross
+CrossSectionalCharts.crosssection(LCHuv) # hide
+```
- `DIN99`, `DIN99d`, `DIN99o` and all 6 transparent variants
- Storage formats `YIQ`, `YCbCr` and their transparent variants
-
+```@example cross
+CrossSectionalCharts.crosssection(YIQ) # hide
+```
+```@example cross
+CrossSectionalCharts.crosssection(YCbCr) # hide
+```
- `Gray`, `Gray24`, and the transparent variants `AGray`, `GrayA`, and `AGray32`.
-## Converting colors
-Colors.jl allows you to convert from one colorspace to another using the `convert` function.
+## Color Parsing
-For example:
+You can parse any [CSS color specification](https://developer.mozilla.org/en-US/docs/CSS/color)
+with the exception of `currentColor`. You can construct colors from strings
+using the [`@colorant_str`](@ref) macro and the [`parse`](@ref) function.
```jldoctest example
julia> using Colors
-julia> convert(RGB, HSL(270, 0.5, 0.5))
-RGB{Float64}(0.5,0.25,0.75)
-```
-
-Depending on the source and destination colorspace, this may not be perfectly lossless.
+julia> colorant"red" # named color
+RGB{N0f8}(1.0,0.0,0.0)
-## Color Parsing
+julia> parse(Colorant, "DeepSkyBlue") # color names are case-insensitive
+RGB{N0f8}(0.0,0.749,1.0)
+julia> colorant"#FF0000" # 6-digit hex notation
+RGB{N0f8}(1.0,0.0,0.0)
-```jldoctest example
-julia> c = colorant"red"
+julia> colorant"#f00" # 3-digit hex notation
RGB{N0f8}(1.0,0.0,0.0)
-julia> parse(Colorant, "red")
+julia> colorant"rgb(255,0,0)" # rgb() notation with integers in [0, 255]
RGB{N0f8}(1.0,0.0,0.0)
-julia> parse(Colorant, HSL(1, 1, 1))
-HSL{Float32}(1.0f0,1.0f0,1.0f0)
+julia> colorant"rgba(255,0,0,0.6)" # with alpha in [0, 1]
+RGBA{N0f8}(1.0,0.0,0.0,0.6)
-julia> colorant"#FF0000"
-RGB{N0f8}(1.0,0.0,0.0)
+julia> colorant"rgba(100%,80%,0%,0.6)" # with "integer" percentages
+RGBA{N0f8}(1.0,0.8,0.0,0.6)
-julia> parse(Colorant, RGBA(1, 0.5, 1, 0.5))
-RGBA{Float64}(1.0,0.5,1.0,0.5)
-```
+julia> parse(ARGB, "rgba(255,0,0,0.6)") # you can specify the return type
+ARGB{N0f8}(1.0,0.0,0.0,0.6)
+
+julia> colorant"hsl(120, 100%, 25%)" # hsl() notation
+HSL{Float32}(120.0f0,1.0f0,0.25f0)
-You can parse any [CSS color specification](https://developer.mozilla.org/en-US/docs/CSS/color) with the exception of `currentColor`.
+julia> colorant"hsla(120, 100%, 25%, 0.6)" # hsla() notation
+HSLA{Float32}(120.0f0,1.0f0,0.25f0,0.6f0)
+
+julia> colorant"transparent" # transparent "black"
+RGBA{N0f8}(0.0,0.0,0.0,0.0)
+```
All CSS/SVG named colors are supported, in addition to X11 named colors, when their definitions do not clash with SVG.
+You can find all names and their color swatches in [Named Colors](@ref) page.
When writing functions the `colorant"red"` version is preferred, because the slow step runs when the code is parsed (i.e., during compilation rather than run-time).
+The element types of the return types depend on the colorspaces, i.e. the `hsl()`
+and `hsla()` notations return `HSL`/`HSLA` colors with `Float32` elements, and
+other notations return `RGB`/`RGBA` colors with `N0f8` elements. The result
+colors can be converted to `RGB{N0f16}` (for example) using:
+
+```jldoctest example
+julia> using FixedPointNumbers
+
+julia> RGB{N0f16}(colorant"indianred")
+RGB{N0f16}(0.80392,0.36078,0.36078)
+```
+or
+```jldoctest example
+julia> parse(RGB{N0f16}, "indianred")
+RGB{N0f16}(0.80392,0.36078,0.36078)
+```
+
+You can also pass a color (`Colorant` value) to the second argument of the
+[`parse`](@ref) function, but in this case, `parse` does not apply any
+conversion on the color.
+
+```jldoctest example
+julia> parse(RGB{N0f8}, HSL{Float64}(120, 1, 0.5)) # use `convert` instead
+HSL{Float64}(120.0,1.0,0.5)
+```
+
+
+You can convert colors to hexadecimal strings using the [`hex`](@ref) function.
+Note that the conversion result does not have the prefix `"#"`.
+
+```jldoctest example
+julia> color = colorant"#C0FFEE"
+RGB{N0f8}(0.753,1.0,0.933)
+
+julia> hex(color)
+"C0FFEE"
+```
+
+## Color Conversions
+
+Colors.jl allows you to convert from one colorspace to another using the `convert` function.
+
+For example:
+
+```jldoctest example
+julia> convert(RGB, HSL(270, 0.5, 0.5)) # without the element type
+RGB{Float64}(0.5,0.25,0.75)
+
+julia> convert(RGB{N0f8}, HSL(270, 0.5, 0.5)) # with the element type
+RGB{N0f8}(0.502,0.251,0.749)
+```
+
+Depending on the source and destination colorspace, this may not be perfectly lossless.
+
+---
+
```@docs
@colorant_str
parse
diff --git a/docs/src/index.md b/docs/src/index.md
index b51b7332..dcb1cedb 100644
--- a/docs/src/index.md
+++ b/docs/src/index.md
@@ -1,22 +1,48 @@
# Introduction
-This library provides a wide array of functions for dealing with color.
+This package provides a wide array of functions for dealing with color.
-Supported colorspaces include:
+[Available colorspaces](@ref) include:
-- RGB, BGR, XRGB, RGBX, RGB24, plus transparent versions ARGB, RGBA, ABGR, BGRA, and ARGB32
-- HSV, HSL, HSI, plus all 6 transparent variants (AHSV, HSVA, AHSL, HSLA, AHSI, HSIA)
-- XYZ, xyY, LMS and all 6 transparent variants
-- Lab, Luv, LCHab, LCHuv and all 8 transparent variants
-- DIN99, DIN99d, DIN99o and all 6 transparent variants
-- Storage formats YIQ, YCbCr and their transparent variants
-- Gray, Gray24, and the transparent variants AGray, GrayA, and AGray32.
+- `RGB`, `BGR`, `XRGB`, `RGBX`, `RGB24`
+- `HSV`, `HSL`, `HSI`
+- `XYZ`, `xyY`, `LMS`
+- `Lab`, `Luv`, `LCHab`, `LCHuv`
+- `DIN99`, `DIN99d`, `DIN99o`
+- `YIQ`, `YCbCr`
+- `Gray`, `Gray24`
+- and their transparent variants: `ARGB`, `RGBA`, `ARGB32`, `AHSV`, `HSVA`, and so on
-You can supply colors using names (eg `"red"`) or hex triplets (eg `#7aa457`)
+## Package Features
-Support is also provided for:
+- [Color Parsing](@ref)
+- [Color Conversions](@ref)
+- [Color Differences](@ref)
+- [Colormaps and Colorscales](@ref)
+- [Simulation of color deficiency](@ref color_deficiency)
-- color differences
-- white balance
-- color deficiency ("color blindness")
-- colormaps and colorscales
+
+## Installation
+
+The package can be installed with the Julia package manager. From the Julia
+REPL, type ] to enter the Pkg REPL mode and run:
+```julia
+pkg> add Colors
+```
+
+## Reexport
+
+Note that Colors is used within other packages (e.g. [Images](https://github.com/JuliaImages/Images.jl))
+and may have been [reexport](https://github.com/simonster/Reexport.jl)ed by them.
+In addition, the color types used by Colors are defined in [ColorTypes](https://github.com/JuliaGraphics/ColorTypes.jl)
+package. Colors reexports the types and functions exported by ColorTypes.
+For example, that means:
+```julia
+julia> using Images; # instead `using Colors`
+
+julia> RGB # You can use the types and functions (re-)exported by Colors.
+RGB
+
+julia> RGB === Images.RGB === Colors.RGB === ColorTypes.RGB
+true
+```
diff --git a/docs/src/namedcolors.md b/docs/src/namedcolors.md
index e9d596e0..13d63c75 100644
--- a/docs/src/namedcolors.md
+++ b/docs/src/namedcolors.md
@@ -10,31 +10,6 @@ color_names = Dict(
...
```
-Named colors are available as `RGB{N0f8}` using:
-
-```jldoctest example
-julia> using Colors
-
-julia> color = colorant"indianred"
-RGB{N0f8}(0.804,0.361,0.361)
-```
-
-or
-
-```jldoctest example
-julia> cname = "indianred"
-"indianred"
-
-julia> color = parse(Colorant, cname)
-RGB{N0f8}(0.804,0.361,0.361)
-```
-
-or
-
-```jldoctest example
-julia> color = parse(RGB, cname)
-RGB{N0f8}(0.804,0.361,0.361)
-```
```@example chart
using Main: NamedColorCharts # hide
@@ -87,20 +62,3 @@ NamedColorCharts.ColorChartSVG("grays") # hide
named colors. There are some unnatural definitions due to the different
origins. For example, "LightGray" is lighter than "Gray", but "DarkGray" is
also lighter than "Gray".
-
-
-These colors can be converted to `RGB{N0f32}` (for example) using:
-
-```jldoctest example
-julia> using FixedPointNumbers
-
-julia> RGB{N0f32}(color)
-RGB{N0f32}(0.803922,0.360784,0.360784)
-```
-
-or
-
-```jldoctest example
-julia> parse(RGB{N0f32}, cname)
-RGB{N0f32}(0.803922,0.360784,0.360784)
-```