[PATCH 1/2] Document PDF blend operators
Andrea Canciani
ranma42 at gmail.com
Thu Jul 28 10:27:54 PDT 2011
PDF blend operators were added in RENDER 0.11, but no documentation is
available in the specification.
---
renderproto.txt | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 119 insertions(+), 7 deletions(-)
diff --git a/renderproto.txt b/renderproto.txt
index 3aad841..be8e208 100644
--- a/renderproto.txt
+++ b/renderproto.txt
@@ -345,7 +345,119 @@ When the mask contains separate alpha values for each channel, the
alpha value resulting from the combination of that value with the source
alpha channel is used in the final image composition.
-9. Source and Mask Transformations
+9. Blend Operators
+
+The blend operators are based on the PDF ISO 32000 specification and
+its supplement ISO 32000-1, which at this point in time is available
+from:
+
+http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
+http://www.adobe.com/devnet/acrobat/pdfs/adobe_supplement_iso32000.pdf
+
+The relevant chapters are 11.3.5 and 11.3.6.
+
+The formula for computing the final pixel color given in 11.3.6 is:
+ * αr à Cr = (1 â αs) à αb à Cb + (1 â αb) à αs à Cs + αb à αs à B(Cb, Cs)
+ * with B() being the blend function.
+ * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs
+ *
+ * These blend modes should match the SVG filter draft specification, as
+ * it has been designed to mirror ISO 32000. Note that at the current point
+ * no released draft exists that shows this, as the formulas have not been
+ * updated yet after the release of ISO 32000.
+ *
+ * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
+ * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
+ * argument. Note that this implementation operates on premultiplied colors,
+ * while the PDF specification does not. Therefore the code uses the formula
+ * Cra = (1 â as) . Dca + (1 â ad) . Sca + B(Dca, ad, Sca, as)
+
+When the PictOp is a blend operator, the alpha channel of the image is
+computed with:
+
+ A = Aa + Ab - Aa * Ab
+
+where A, Aa, Ab are the values of the respective alpha channels. This
+results in the same alpha as if the operator had been Over.
+
+For separable blend operators, the color components are computed as:
+
+ C = (1 â Aa) * Cb + (1 â Ab) * Ca + B
+
+where C, Ca, Cb are the values of the respective channels and B comes
+from the following table:
+
+Multiply, Screen, Overlay, Darken, Lighten, ColorDodge,
+ColorBurn, HardLight, SoftLight, Difference, Exclusion,
+HSLHue, HSLSaturation, HSLColor, HSLLuminosity
+
+ PictOp B
+ -----------------
+ Multiply Ca*Cb
+ Screen Aa*Cb + Ab*Ca - Ca*Cb
+ Overlay 2*Cb < Ab ? 2*Ca*Cb : Aa*Ab - 2*(Aa-Ca)*(Ab-Cb)
+ Darken min(Aa*Cb, Ab*Ca)
+ Lighten max(Aa*Cb, Ab*Ca)
+ ColorDodge Aa * (Cb == 0 ? 0 : Ca >= Aa ? Ab : min(Ab,Aa*Cb/(Aa-Ca)))
+ ColorBurn Aa * (Cb >= Ab ? Ab : Ca == 0 ? 0 : max(0,Ab-Aa*(Ab-Cb)/Ca))
+ HardLight 2*Ca < Aa ? 2*Ca*Cb : Aa*Ab - 2*(Aa-Ca)*(Ab-Cb)
+ SoftLight (see below)
+ Difference abs(Aa*Cb - Ab*Ca)
+ Exclusion Aa*Cb + Ab*Ca - 2*Cb*Ca
+ HSLHue set_lum(set_sat(Ab*Ca, Aa * sat(Cb)), Aa * LUM(Cb))
+ HSLSaturation set_lum(set_sat(Aa*Cb, Ab * sat(Ca)), Aa * LUM(Cb))
+ HSLColor set_lum(Ab*Ca, Aa * lum(Cb))
+ HSLLuminosity set_lum(Aa*Cb, Ab * lum(Ca))
+
+The B value of the SoftLight operator is computed as:
+
+ if (2*Ca <= Aa)
+ Cb * (Aa - (2*Ca - Aa)*(Ab - Cb)/Ab)
+ else if (4*Cb <= Ab)
+ Cb * (Aa + (2*Ca - Aa)*((16*Cb - 12*Ab)/Ab*Cb/Ab + 3)
+ else
+ Cb * Aa + (2*Ca - Aa)*(Ab*sqrt(Cb/Ab) - Cb)
+
+HSLHue, HSLSaturation, HSLColor, HSLLuminosity are non-separable blend
+operators, which means that the value of each component of the result
+depends on the values of all of the components of the colors being
+blended. When Cb and Ca are used to define their B value, they
+indicate the color and alpha components, taken as a vector. The
+resulting B has the same form.
+
+To define the non-separable blend operators, some utility functions
+are needed. Assuming that Cred, Cgreen and Cblue are the
+(premultiplied) red, green and blue component of the C color and Cmin,
+Cmid and Cmax are the smallest, middle and biggest component
+respectively:
+
+lum (C) = 0.3*Cred + 0.59*Cgreen + 0.11*Cblue
+sat (C) = Cmax - Cmin
+
+clip_color (C):
+ l = lum (C)
+ if Cmin < 0
+ Crgb = l + (Crgb - (l,l,l)) * l / (l - Cmin)
+ if Cmax > Ca
+ Crgb = l + (Crgb - (l,l,l)) * l / (Cmax - l)
+ return C
+
+set_lum (C, l):
+ d = l â lum (C)
+ Crgb += (d,d,d)
+ return clip_color (C)
+
+set_sat (C, s):
+ if Cmax > Cmin
+ Cmid = s * (Cmid - Cmin) / (Cmax - Cmin)
+ Cmax = s
+ else
+ Cmid = Cmax = Cmin = 0.0
+ return C
+
+
+
+10. Source and Mask Transformations
When fetching pixels from the source or mask pictures, Render provides four
options for pixel values which fall outside the drawable (this includes
@@ -375,7 +487,7 @@ fundamental rendering operator described above. Each screen provides a list
of supported filter names. There are a few required filters, and several
required filter alias which must map to one of the available filters.
-10. Polygon Rasterization
+11. Polygon Rasterization
Render provides only two kinds of polygons, trapezoids and triangles. To
improve efficiency, several different wire encodings exist for each.
@@ -431,7 +543,7 @@ the implementation must conform to the following constraints:
+ Order independent. Two identical polygons specified with vertices
in different orders must generate identical results.
-11. Image Filtering
+12. Image Filtering
When computing pixels from source and mask images, a filter may be applied
to the data. This is usually used with a non-identity transformation
@@ -477,7 +589,7 @@ the definition specified here.
binomial Binomial blur. An approximation of a Gaussian
blur using binomial coefficients
-12. Glyph Rendering
+13. Glyph Rendering
Glyphs are small alpha masks which can be stored in the X server and
rendered by referring to them by name. A set of glyphs can be rendered in a
@@ -492,7 +604,7 @@ client-specified 32-bit numbers.
Glyphs can be stored in any PictFormat supported by the server. All glyphs
in a GlyphSet are stored in the same format.
-13. Extension Initialization
+14. Extension Initialization
The client must negotiate the version of the extension before executing
extension requests. Behavior of the server is undefined otherwise.
@@ -567,7 +679,7 @@ QueryFilters
aliases: LISTofCARD16
-14. Extension Requests
+15. Extension Requests
CreatePicture
@@ -1147,7 +1259,7 @@ CreateConicalGradient
The colors are non premultiplied.
-15. Extension Versioning
+16. Extension Versioning
The Render extension was developed in parallel with the implementation to
ensure the feasibility of various portions of the design. As portions of
--
1.7.1
More information about the xorg-devel
mailing list