A colour sliding into another

Declare a gradient, along a line or between circles, then fill a shape with it by naming it.

Summary

An evening sky goes from orange to blue with no telling where one stops. That is a gradient. One kind slides from one point to another, the way that sky does; another radiates from one circle to another, like a halo around a lamp. A third works out the colour of every point from where that point stands, how far across and how far up, so it turns both ways at once. The fourth is cut into triangles, each corner holding its own colour, and it goes where a line and a pair of circles cannot: a face lit from two sides, a map whose ground changes in every direction. Any of them fills whatever shape you like: a title band, a card background, a disc.

Technically

Written at the top level of a request, under "shadings"

shadings declares the gradients the document defines for itself, each under the name a fill selects it by. A gradient is written as a shading pattern — /ShadingType 1 read from a function of two coordinates, 2 along a line, 3 between two circles, 4 across a mesh of triangles — reached through /PatternType 2, so the colour shows through whatever the shape lets through rather than being painted over a clip. The two that run end to end state their colours in two ways, and one at a time: two colours end to end, or a space and a function. Two colours end to end are written in the space the count of their numbers names: three numbers write /DeviceRGB, four write /DeviceCMYK, so a gradient runs on the four press plates as readily as on a screen. A mesh states a colour at every corner instead, and what lies inside a triangle is worked out from its three. A colour read from a function is read over a rectangle of its own, placed on the page by six numbers, and it is the one gradient whose colour turns in both directions at once.

Request schema

  • shadings — array, optional, empty by default.
  • shadings[].name — string, required. The name a fill selects this gradient by.
  • shadings[].shading — object, required. Seven kinds:
    • axialfrom two numbers required, to two numbers required, in page coordinates.
    • radialfrom and to in three numbers each, required: centre x, centre y, radius.
    • function_baseddomain, matrix, space and function all required. domain states two pairs of numbers, the interval x runs over then the interval y runs over; matrix the six numbers of the cm operator of the PDF language, which places that rectangle on the page, [200, 0, 0, 100, 50, 60] stretching the domain [[0, 1], [0, 1]] over the 200 by 100 rectangle whose lower left corner stands at 50, 60; space one of gray, rgb and cmyk, or one press ink named and stated in full through separation, or several such inks at once through device_n, a declared space of any other kind being refused; function the function the colour at each point is read from, the point's two coordinates in and the components of a colour out, so only calculation and sampled state it and a function of any other count of numbers is refused. Nothing outside the placed rectangle is painted. Written as /ShadingType 1.
    • meshtriangles required, an array of groups of three corners. A corner states at, two numbers in page coordinates, then color, or tints where the mesh states a space. A mesh stating no triangle is refused.
    • lattice_meshrows required, an array of rows of corners stated as a mesh states them, every row as long as the first, at least two rows of two corners. Each square of four neighbouring corners makes two triangles, so a corner several triangles meet at is stated once. Written as /ShadingType 5.
    • coons_patch_meshpatches required, an array of patches. A patch states points, twelve control points of two numbers each in page coordinates, and colors, the colour of each of its four corners, or tints where the mesh states a space. The twelve run from the first corner right round the patch, each side a corner then the two points that bend the side leaving it, so the corners are the first, the fourth, the seventh and the tenth point. Written as /ShadingType 6.
    • tensor_patch_mesh — the same patches, with sixteen points to a patch: the twelve of the boundary, then the four inside it, the one nearest the first corner first, then those nearest the fourth, the seventh and the tenth. Written as /ShadingType 7. Any other count of points is refused, and where two patches overlap the later one is painted over the earlier.
  • The two that run end to end share: start and end, optional colours, named together; space and function, optional, named together; extend, two optional booleans, [false, false] by default. space is one of gray, rgb and cmyk, or one press ink named and stated in full through separation, or several such inks at once through device_n, a declared space of any other kind being refused. A mesh takes neither start, end nor extend: its colours are its corners. A colour read from a function states its own space and function, both required there, and neither start, end nor extend.
  • Every one of the seven kinds takes anti_alias on top of its own fields: one optional boolean asking the reader to filter the colour transitions of the shading against aliasing — the false pattern that shows where the colour varies fast compared with the rate the output device samples it at — or asking it not to. Absent, no /AntiAlias entry is written, and a reader then takes it as false, the default ISO 32000-2 gives the entry.
  • A mesh states its colours one of two ways, and one at a time: color at every corner and no space, or space and tints at every corner. Its space reads what a gradient's space reads, and tints states one number per component of it — one per ink where the space is named inks, which is what carries a mesh onto the plates of a press. A space beside a corner color, tints under no space, and a corner stating neither, are each refused.
  • Exactly one of the two ways of stating the colour: start and end together, or space and function together. Both together are refused, neither is refused too.
  • start and end are stated both in light or both in ink: three numbers each, or four each writing the gradient on the four press plates. A grey is light. One end in light and the other in ink is refused, the message naming the numbers of both ends.
  • function takes four shapes. exponential, with low and high required, domain two numbers optional (0 to 1), exponent optional (1) and range optional. stitching, with functions, bounds and encode required, domain and range optional.
  • sampled writes the answers out as a table over a grid, which is what says a curve no formula describes — a spectrum, a press characterisation, a measured response: domain, range, size and samples required, bits, decode, encode and between optional, between saying how the answer runs from one sample to the next, linear by default, or cubic, which the format allows only for a function of one number. calculation states the answer as a small program, for a colour worked out rather than looked up: program, the steps run on a stack, with domain and range, all three required.
  • A mesh states every corner both in light or both in ink, as the two ends of the other kinds are: three numbers each, or four each writing the mesh on the four press plates. One corner in light and another in ink is refused.
  • A fill names a gradient through the shape {"shading": "the name"}.

A whole request that creates a PDF

{
  "shadings": [
    {
      "name": "sunrise",
      "shading": {
        "axial": {
          "from": [60, 700],
          "to": [300, 700],
          "start": [0.95, 0.75, 0.2],
          "end": [0.2, 0.35, 0.75]
        }
      }
    },
    {
      "name": "spectrum",
      "shading": {
        "axial": {
          "from": [320, 700],
          "to": [535, 700],
          "space": "rgb",
          "function": {
            "sampled": {
              "domain": [[0, 1]],
              "range": [[0, 1], [0, 1], [0, 1]],
              "size": [4],
              "bits": 16,
              "between": "cubic",
              "samples": [
                0.85, 0.12, 0.1,
                0.92, 0.66, 0.11,
                0.16, 0.6, 0.31,
                0.11, 0.26, 0.72
              ]
            }
          }
        }
      }
    }
  ],
  "items": [
    {
      "type": "rect",
      "rect": { "llx": 60, "lly": 700, "urx": 300, "ury": 780 },
      "fill": { "shading": "sunrise" }
    },
    {
      "type": "rect",
      "rect": { "llx": 320, "lly": 700, "urx": 535, "ury": 780 },
      "fill": { "shading": "spectrum" }
    }
  ]
}

The line that sends it, in three languages

Colour and how it is shown

The device the colours are stated for Which plate of a separated sheet a page is The device one page's colours are stated for Declaring colour beyond red, green and blue What a page's bare numbers mean Opacity, mixing, and what a press asks for A cell repeated to fill a shape The space a page mixes its colours in

Where to go next

Every JSON key of a request, in one page The other forty-one settings of a request

See the prices See the examples