## Understanding ternary raster operations

 Date: May 24, 2005 / year-entry #128 Tags: code Orig Link: https://blogs.msdn.microsoft.com/oldnewthing/20050524-48/?p=35553 Comments: 9 Summary: It's perfectly logical, which doesn't mean that it's easy to understand. A ternary raster operation describes how three boolean values should combine to form an output boolean. I was going to write up a description but found that the existing documentation pretty much covers it, so I refer you to that. In particular, look at...

 It's perfectly logical, which doesn't mean that it's easy to understand. A ternary raster operation describes how three boolean values should combine to form an output boolean. I was going to write up a description but found that the existing documentation pretty much covers it, so I refer you to that. In particular, look at the table that explains where PSo and DPSoo come from. Now, one question that has come up is "What is the algorithm for deriving the RPN raster operation description string from the operation index?" The answer is, "You stare at it and use your brain's power of pattern-matching." There is no single "correct" expression of an operation index as RPN. For example, "DPSoo" could have been written as "DSPoo" or "DSoPo" or as the equivalent but pointlessly esoteric "DPoDnPnSaao". All of these expressions have the same boolean truth table.

 Comments (9) josh says: IMO the RPN string is completely useless. Just make a truth table for what you want and forget about the operation required. I #define a long list of ROP3_33, ROP3_8C, etc. so I can just use the number straight out of the truth table as well. (I also write the table sideways so it’s easier to read that way…) Same deal for binary raster ops. Mike says: I agree. The whole discussion about RPN really just obfuscates the whole thing. The first time I tried to find some non-standard rop I wasted a huge amount of time coming up with RPN forms and alternatives and trying to match them to the table. Just going by the truth table is much simpler. Sergey Vlasov says: I have found an old book "Writing Windows device drivers" by Daniel Norton, and was surprised to see that even the raster operation codes are not unique. E.g., the "DPSoo" you give as an example is encoded as 0x02a9 (this gives the 0x00FE02A9 value in the MSDN table), but if represented as "DSPoo", the same operation can be encoded as 0x02a6, or as 0x2a0 ("SPDoo"), or even as 0x02a5 ("PDSoo")… Probably there was some ordering between the alternative representations which gave the rule to choose one from them. E. Massey says: The ROP codes have always been a bit "mysterious" since there’s little detailed documentation about them. However, there used to be a MS knowledge base article titled "The Lower Order Word of 32-Bit ROP Codes" (Q74508) that explained the ROP codes in detail. I can’t find it online, but it’s part of the MSDN that came with VC++ 6.0. Some key points from this article: …only the higher-order word or most-significant word (MSW) of the 32-bit ROP code is explained. This word is an index in the ROP table. The use of the lower-order word or least-significant word (LSW) of the ROP code is not addressed in the Windows Device Development Kit (DDK). The LSW of the ROP code may be used by display drivers to assist in parsing the ROP. A complete explanation of the LSW of the ROP code can be found in the file COMMENT.BLT, which is included with the DDK display driver sample source code. … The low-order word in and of itself does not contain enough information to generate the ROP code. What it contains is: 1. An index specifying which predefined parse sting to use. 2. Amount to rotate the parse string. 3. Five logic operations. 4. A parity bit used to imply a sixth logic operation of NOT. Pairs of trailing NOTs are discarded since they cancel.
Example 1: 85, 0085 1E05, PDSPnoaxn,            D = not ((((not P) or S) and D) xor P) 1E08 = 00 01 11 10 00 0 001 01        |  |  |  |  |  |  |  |        |  |  |  |  |  |  |  |___ bias start by 1        |  |  |  |  |  |  |______ use string 1        |  |  |  |  |  |_________ parity – no trailing NOT        |  |  |  |  |____________ Logic operation #1 is a NOT        |  |  |  |_______________ Logic operation #2 is a OR        |  |  |__________________ Logic operation #3 is a AND        |  |_____________________ Logic operation #4 is a XOR        |________________________ Logic operation #5 is a NOT String #1 is defined as:      SPDSPDSP After the bias, it will be:   PDSPDSPS