Colors and transparency

Adding colors is quite trivial. We already used setgray and currentgray with internal RGB values. We just have to add setrgbcolor and currentrgbcolor operators.

Javascript Editor

Javascript Editor

We might also deal later with CMYK colors, but for the moment this is not our focus.

Transparency however is not standard in PostScript. But we will add custom operators setalpha and currentalpha

Javascript Editor

Alpha is the 4th component of context.graphics.color, so we are fine for the context. But currently, setgray and setrgbcolor overwrite it with 255, so we need to fix that and use the current alpha.

Javascript Editor

Let's test alpha. The raw rendering is lighter, but there is nothing transparent. Note that alpha is inside the picture, Transparent makes the entire picture transparent instead of having a white background,

Javascript Editor

We need to implement alpha in all devices. First raw.

The traditional formula for alpha is D = F * Fa + B * (1 - Fa) where D is destination, B background, F foreground and Fa foreground alpha. The formula can be simplified as D = B + Fa * (Fa - B).

However, this formula does not work if the background is itself transparent. We must calculate in 2 steps: Da = Fa + Ba * (1 - Fa) and D = (F * Fa + B * Ba * (1 - Fa)) / Da

Javascript Editor

Canvas has a property ctx.globalAlpha.

Javascript Editor

SVG has attributes fill-alpha and stroke-alpha.

Javascript Editor

PDF does not have an operator for transparency. However PDF 1.4 allows to define graphics parameters in a dictionary. Therefore i created 16 dictionaries that set CA (stroke alpha) and ca (fill alpha) to values between 0 and 1. The dictionary are referenced in the source of the page. 16 levels should be enough to blend.

for (let i = 0; i < 17; i++ ) {
alphadict["GS"+i] = (5+i) + " 0 R";
const ad = {};
ad.type = "/ExtGState";
ad.ca = i / 16.0;
ad.CA = i / 16.0;
objects.push([ad])
}

For every fill, stroke and show setalpha is used.

setalpha(context) {
const gs = Math.round(context.graphics.color[3]/16)
this.elements.push("/GS"+gs+" gs");
}

Javascript Editor

3453 lines ps20241028.js

My Journey to PostScript