[PATCH 2/2] d2d1: Implement ellipse and rounded rectangle stroking with arcs.

Henri Verbeet hverbeet at gmail.com
Mon Feb 17 10:01:32 CST 2020


On Fri, 14 Feb 2020 at 22:11, Giovanni Mascellani <gio at debian.org> wrote:
> +struct d2d_arc_outline_vertex
> +{
> +    D2D1_POINT_2F position;
> +    D2D1_POINT_2F p0, p1, p2;
> +    D2D1_POINT_2F prev, next;
> +};
> +
Much like for fills, I'd argue for combining this with the
d2d_bezier_outline_vertex structure.

> +    static const D3D10_INPUT_ELEMENT_DESC il_desc_arc_outline[] =
> +    {
> +        {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
> +        {"P", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0},
> +        {"P", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0},
> +        {"P", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
> +        {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D10_INPUT_PER_VERTEX_DATA, 0},
> +        {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D10_INPUT_PER_VERTEX_DATA, 0},
> +    };
Likewise.

> +    static const DWORD vs_code_arc_outline[] =
> +    {
> +#if 0
> +        float3x2 transform_geometry;
> +        float stroke_width;
> +        float4 transform_rtx;
> +        float4 transform_rty;
> +
> +        struct output
> +        {
> +            float2 p : WORLD_POSITION;
> +            float4 b : BEZIER;
> +            nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
> +            float4 position : SV_POSITION;
> +        };
> +
> +        void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2,
> +                float2 prev : PREV, float2 next : NEXT, out struct output o)
> +        {
> +            float2 q_prev, q_next, v_p, q_i, p;
> +            float2x2 geom, rt, p_inv;
> +            float l;
> +            float a;
> +            float2 bc;
> +
> +            geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);
> +            rt = float2x2(transform_rtx.xy, transform_rty.xy);
> +            o.stroke_transform = rt * stroke_width * 0.5f;
> +
> +            p = mul(geom, position);
> +            p0 = mul(geom, p0);
> +            p1 = mul(geom, p1);
> +            p2 = mul(geom, p2);
> +
> +            p -= p0;
> +            p1 -= p0;
> +            p2 -= p0;
> +
> +            q_prev = normalize(mul(geom, prev));
> +            q_next = normalize(mul(geom, next));
> +
> +            v_p = float2(-q_prev.y, q_prev.x);
> +            l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));
> +            q_i = l * q_prev + v_p;
> +            p += 0.5f * stroke_width * q_i;
> +
> +            p_inv = float2x2(p1.y, -p1.x, p2.y - p1.y, p1.x - p2.x) / (p1.x * p2.y - p2.x * p1.y);
> +            o.b.xy = mul(p_inv, p) + float2(1.0f, 0.0f);
> +            o.b.zw = 0.0f;
> +
> +            o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i;
> +            position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))
> +                    * float2(transform_rtx.w, transform_rty.w);
> +            o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);
> +        }
This should just be a slightly simpler version of
"vs_code_bezier_outline", but it's probably still best to include the
equivalent comment.

> @@ -3374,10 +3554,18 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
>                  uv = i.b;
>                  du = float2(ddx(uv.x), ddy(uv.x));
>                  dv = float2(ddx(uv.y), ddy(uv.y));
> -                df = 2.0f * uv.x * du - dv;
>
> -                clip(dot(df, uv.zw));
> -                clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y));
> +                if (!is_arc) {
> +                    df = 2.0f * uv.x * du - dv;
> +
> +                    clip(dot(df, uv.zw));
> +                    clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y));
> +                } else {
> +                    df = 2.0f * uv.x * du + 2.0f * uv.y * dv;
> +
> +                    clip(dot(df, uv.zw));
> +                    clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f));
> +                }
Likewise, please update the comment here as well. There's also a minor
formatting issue.



More information about the wine-devel mailing list