Hi,
I am trying to understand how the vertex shader for the Bézier curve outline works in d2d1. The relevant code is the bytecode in vs_code_bezier_outline[] in dlls/d2d1/device.c.
In particular, I have problems with this snippet:
if (abs(dot(mul(rt, p1), v_p)) < 1.0f) { o.b.xzw = float3(0.0f, 0.0f, 0.0f); o.b.y = dot(mul(rt, p), v_p); } else { o.b.zw = sign(dot(mul(rt, p1), v_p)) * v_p; v_p = -float2(-p.y, p.x) / dot(float2(-p1.y, p1.x), p2); o.b.x = dot(v_p, p1 - 0.5f * p2); o.b.y = dot(v_p, p1); }
The idea as I understand is that o.b.xy should contain the u and v coordinates over which the implicit curve u^2-v is evaluated. They are defined to be (0, 0), (1/2, 0) and (1,1) on the vertices of the "original" Bézier triangle, as in the filling case. Since now the original triangle has to be enlarged by a stroke width, the u and v coordinates should be extended by linearity, I believe.
However, I don't see why this is what is happening here. To extend by linearity one should invert the 2x2 matrix given by p1-p0 and p2-p0 or something similar. And I see no reason to have an "if" branch.
Also, I completely do not understand what the coordinates o.b.zw are for. On the other hand, I understand (or at least I think I do) the screen-space derivative trick used to stroke a line of the right width. It is probably a rather rough approximation, but it is clever!
If someone (probably Henri Verbeet, I think) can help to understand the missing bits I would be very thankful!
Giovanni.