Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinearGradientBrush Problem #37

Open
paulushub opened this issue Nov 29, 2017 · 3 comments
Open

LinearGradientBrush Problem #37

paulushub opened this issue Nov 29, 2017 · 3 comments
Assignees
Labels

Comments

@paulushub
Copy link
Contributor

paulushub commented Nov 29, 2017

I am trying to open the following SVG file after downloading from: http://upload.wikimedia.org/wikipedia/commons/1/15/Boiling_water_reactor_english.svg

The "GdiTestSvgViewer" reports incorrectly the LinearGradientBrush, if it is 'vertical'. However the 'horizontal' LGB is ok.

Also the 'arrow-head' is incorrectly rendered.

I have downloaded the the change-set 19058.

Attached is the rendered image.

Attachments

boiler.jpg

This work item was migrated from CodePlex

CodePlex work item ID: '1438'
Vote count: '2'

@paulushub
Copy link
Contributor Author

[tanveerakl@2013/03/01]
Following Code change seems to render the LinearGradient Properly.

But still the "pipe4.svg" in Issue: 434, radial parts is not getting rendered. Also, this should work with fractional angles of linear gradient.

Also the http://en.wikipedia.org/wiki/File:COGAS_diagram.svg does not render the gradient properly, because there seems to be no provision for "pad" spreadmethod in GDI+. Or am I missing something?

    private LinearGradientBrush GetLinearGradientBrush(SvgLinearGradientElement res, RectangleF bounds)
    {
        float fLeft = (float)res.X1.AnimVal.Value;
        float fRight = (float)res.X2.AnimVal.Value;
        float fTop = (float)res.Y1.AnimVal.Value;
        float fBottom = (float)res.Y2.AnimVal.Value;

        #region code by tanveerakl

        PointF[] pa = new PointF[] { new PointF(fLeft, fTop), new PointF(fRight, fBottom) };

        Matrix m = GetTransformMatrix(res);
        m.TransformPoints(pa);

        LinearGradientBrush brush = new LinearGradientBrush(pa[0], pa[1], Color.White, Color.White);

        #endregion

        bool bForceUserSpaceOnUse = (fLeft > 1 || fRight > 1 || fTop > 1 || fBottom > 1);

        //float fEffectiveLeft = fLeft;
        //float fEffectiveRight = fRight;
        //float fEffectiveTop = fTop;
        //float fEffectiveBottom = fBottom;

        //if (res.GradientUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox) && !bForceUserSpaceOnUse)
        //{
        //    if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad))
        //    {
        //        fEffectiveRight = bounds.Right;
        //        fEffectiveLeft = bounds.Left;
        //    }
        //    else
        //    {
        //        fEffectiveLeft = bounds.Left + fLeft * (bounds.Width);
        //        fEffectiveRight = bounds.Left + fRight * (bounds.Width);
        //    }

        //    fEffectiveTop = bounds.Top + fTop * (bounds.Height);
        //    fEffectiveBottom = bounds.Top + fBottom * (bounds.Height);
        //}

        //LinearGradientMode mode = LinearGradientMode.Horizontal;

        //if (fTop == fBottom)
        //{
        //    mode = LinearGradientMode.Horizontal;
        //}
        //else
        //{
        //    if (fLeft == fRight)
        //    {
        //        mode = LinearGradientMode.Vertical;
        //    }
        //    else
        //    {
        //        if (fLeft < fRight)
        //            mode = LinearGradientMode.ForwardDiagonal;
        //        else
        //            mode = LinearGradientMode.BackwardDiagonal;
        //    }
        //}

        //float fEffectiveWidth = fEffectiveRight - fEffectiveLeft;

        //if (fEffectiveWidth <= 0)
        //    fEffectiveWidth = bounds.Width;

        //float fEffectiveHeight = fEffectiveBottom - fEffectiveTop;

        //if (fEffectiveHeight <= 0)
        //    fEffectiveHeight = bounds.Height;

        //LinearGradientBrush brush = new LinearGradientBrush(new RectangleF(fEffectiveLeft - 1,
        //    fEffectiveTop - 1, fEffectiveWidth + 2, fEffectiveHeight + 2),
        //    Color.White, Color.White, mode);

        XmlNodeList stops = res.Stops;

        ColorBlend cb = new ColorBlend();

        List<Color> adjcolors = new List<Color>();
        List<float> adjpositions = new List<float>();
        GetColorsAndPositions(stops, adjpositions, adjcolors);

        if (res.GradientUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox) && !bForceUserSpaceOnUse)
        {
            if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad))
            {
                for (int i = 0; i < adjpositions.Count; i++)
                {
                    if (fLeft == fRight)
                        adjpositions[i] = fTop + adjpositions[i] * (fBottom - fTop);
                    else
                        adjpositions[i] = fLeft + adjpositions[i] * (fRight - fLeft);
                }

                // this code corrects the values again... fix
                int nSize = adjcolors.Count;

                if (adjpositions[0] > 0.0)
                    ++nSize;

                if (adjpositions[adjcolors.Count - 1] < 1)
                    ++nSize;

                Color[] readjcolors = new Color[nSize];
                float[] readjpositions = new float[nSize];

                if (adjpositions[0] > 0.0)
                {
                    adjpositions.CopyTo(readjpositions, 1);
                    adjcolors.CopyTo(readjcolors, 1);

                    readjcolors[0] = readjcolors[1];
                    readjpositions[0] = 0;
                }
                else
                {
                    adjpositions.CopyTo(readjpositions, 0);
                    adjcolors.CopyTo(readjcolors, 0);
                }

                if (adjpositions[adjcolors.Count - 1] < 1)
                {
                    readjcolors[nSize - 1] = readjcolors[nSize - 2];
                    readjpositions[nSize - 1] = 1;
                }

                cb.Colors = readjcolors;
                cb.Positions = readjpositions;
            }
            else
            {
                cb.Colors = adjcolors.ToArray();
                cb.Positions = adjpositions.ToArray();
            }
        }
        else
        {
            cb.Colors = adjcolors.ToArray();
            cb.Positions = adjpositions.ToArray();
        }

        brush.InterpolationColors = cb;

        brush.WrapMode = WrapMode.TileFlipXY;


        if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Reflect))
        {
            brush.WrapMode = WrapMode.TileFlipXY;
        }
        else if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Repeat))
        {
            brush.WrapMode = WrapMode.Tile;
        }
        else if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad))
        {
            brush.WrapMode = WrapMode.Tile;
        }

       // brush.Transform = GetTransformMatrix(res);

        if (res.GetPropertyValue("color-interpolation") == "linearRGB")
        {
            brush.GammaCorrection = true;
        }
        else
        {
            brush.GammaCorrection = false;
        }

        return brush;
    }

@paulushub
Copy link
Contributor Author

[UnknownUser@2013/03/09]

@MikeGratsas
Copy link

I found another issue rendering SVG file with linear gradient using GDI+. As I understand the code stop colors and positions correction is not performed always. Therefore, an exception can be thrown on the line

brush.InterpolationColors = cb;

I attached sample file to demonstrate this issue.
YouTube_logo.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants