none
GraphicsPath.PathPoints throwing an ArgumentException RRS feed

  • Question

  • Hi all;

    On a call to GraphicsPath.PathPoints it is throwing an ArgumentException "Error: Parameter is not valid."

    First off, looking at the source for PathPoints - it doesn't throw an exception. It's just a couple of calls into the underlying native Windows API. So how could it do this?

    Second, any idea how I can figure out what's wrong? This problem started when we changed the code slightly in ikvm.awt.C2J.ConvertShape() in IKVM because the previous code was very slow. The change we made should not have caused any problem, much less led to an exception.

    Here's the exception (the java parts are because we use IKVM):

    System.ArgumentException was unhandled
      HResult=-2147024809
      Message=Parameter is not valid.
      Source=System.Drawing
      StackTrace:
           at System.Drawing.Drawing2D.GraphicsPath.get_PathPoints()
           at ikvm.awt.C2J.ConvertShape(GraphicsPath path)
           at ikvm.awt.NetToolkit.outline(Font javaFont, FontRenderContext frc, String text, Single x, Single y)
           at sun.font.StandardGlyphVector.getGlyphVisualBounds(Int32 glyphIndex)
           at sun.font.StandardGlyphVector.getGlyphInfo()
           at sun.font.ExtendedTextSourceLabel.createCharinfo()
           at sun.font.ExtendedTextSourceLabel.getCharinfo()
           at sun.font.ExtendedTextSourceLabel.getLineBreakIndex(Int32 , Single )
           at java.awt.font.TextMeasurer.calcLineBreak(Int32 , Single )
           at java.awt.font.TextMeasurer.getLineBreakIndex(Int32 start, Single maxAdvance)
           at java.awt.font.LineBreakMeasurer.nextOffset(Single wrappingWidth, Int32 offsetLimit, Boolean requireNextWord)
           at java.awt.font.LineBreakMeasurer.nextLayout(Single wrappingWidth, Int32 offsetLimit, Boolean requireNextWord)
           at java.awt.font.LineBreakMeasurer.nextLayout(Single wrappingWidth)
           at net.windward.format.graphics2D.Graphics2DPageWriter.writeLineBuffer(ArrayList elements, ElementSection sect, ElementMark markOn, RectangleInt crop, ElementPara para, ElementLine line, ElementChar chrStart, Int32 mode, Single rotation) in Graphics2DPageWriter.java:line 226
           at net.windward.format.PageObject.LineBuffer.write(IPageWriter pageWriter) in PageObject.java:line 280
           at net.windward.format.PageOutputBuilder.writeAllObjectsToPage() in PageOutputBuilder.java:line 1449
           at net.windward.format.PageOutputBuilder.buildEof() in PageOutputBuilder.java:line 1367
           at net.windward.format.OutputDirector.build(Boolean docIsLaidOut) in OutputDirector.java:line 122
           at net.windward.xmlreport.ProcessReport.processComplete() in ProcessReport.java:line 3425
           at net.windward.api.csharp.Report.ProcessComplete() in C:\git\Jenova\engine\DotNetEngine\WindwardReportsAPI\net\windward\api\csharp\Report.cs:line 903
           at RunReport.net.windward.samples.RunReport.RunOneReport(CommandLine cmdLine, Boolean preservePodFraming) in C:\git\Jenova\engine\DotNetEngine\RunReport\net\windward\samples\RunReport.cs:line 443
           at RunReport.net.windward.samples.RunReport.Main(String[] args) in C:\git\Jenova\engine\DotNetEngine\RunReport\net\windward\samples\RunReport.cs:line 138
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: 


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing

    Friday, June 29, 2018 11:19 AM

Answers

  • I found it - the exception comes from calling 

    PointF[] points = path.PathPoints;
    byte[] types = path.PathTypes;

    when path.PointCount == 0.

    Please report this as a bug to the appropriate team.

    Also, please suggest that path.PathPoints & path.PathTypes have a cached array that they return on subsequent calls. Building any array on each call to a property is a very bad idea.

    thanks - dave


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing

    • Marked as answer by DavidThi808 Tuesday, July 3, 2018 6:57 AM
    Tuesday, July 3, 2018 6:57 AM

All replies

  • Hi DavidThi808,

    Thank you for posting here.

    For your question, could you provide the codes which thrown the exception?

    >>First off, looking at the source for PathPoints - it doesn't throw an exception.

    According to my check for PathPoints property source code, I get the source code, it would thrown exception. And maybe the exception caused by the parameter in source code. Please check it.

    /*
             * Return the path point coordinate information
             * @notes Should there be PathData that contains types[] and points[]
             *        for get & set purposes.
             */
            // float points
            /// <include file='doc\GraphicsPath.uex' path='docs/doc[@for="GraphicsPath.PathPoints"]/*' />
            /// <devdoc>
            ///    <para>[To be supplied.]</para>
            /// </devdoc>
            public PointF[] PathPoints {
                get {
                    int count = PointCount;
                    int size = (int) Marshal.SizeOf(typeof(GPPOINTF));
                    IntPtr buf = Marshal.AllocHGlobal(checked(count * size));
                    try {
                        int status = SafeNativeMethods.Gdip.GdipGetPathPoints(new HandleRef(this, nativePath), new HandleRef(null, buf), count);
     
                        if (status != SafeNativeMethods.Gdip.Ok) {
                            throw SafeNativeMethods.Gdip.StatusException(status);
                        }
     
                        PointF[] points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, count);
                        return points;
                    } finally {
                        Marshal.FreeHGlobal(buf);
                    }
                }

    For more details about the source code, please refer to the .net framework source code.

    https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/GraphicsPath.cs,18830f9c15ff0889

    >>Second, any idea how I can figure out what's wrong?

    I could not find what cause the exception according to your information. Try to use Windbg to analyze the exception.

    Download Windbg from the link below.

    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools

    Please check the MSDN document about how to use Windbg.

    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/getting-started-with-windbg

    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-using-windbg

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, July 2, 2018 7:30 AM
    Moderator
  • This is getting weirder and weirder. The following code works:

    		internal static java.awt.Shape ConvertShape(GraphicsPath path)
    		{
    
                java.awt.geom.GeneralPath shape = new java.awt.geom.GeneralPath();
                shape.setWindingRule((int)path.FillMode);
                for (int i = 0; i < path.PointCount; i++) {
                    byte pathType = path.PathTypes[i];
                    int type = pathType & 0x07;
                    PointF point = path.PathPoints[i];
                    switch (type) {
                        case 0:
                            // Indicates that the point is the start of a figure. 
                            shape.moveTo(point.X, point.Y);
                            break;
                        case 1:
                            // Indicates that the point is one of the two endpoints of a line. 
                            shape.lineTo(point.X, point.Y);
                            break;
                        case 3:
                            // Indicates that the point is an endpoint or control point of a cubic B?zier spline. 
                            PointF point2 = path.PathPoints[++i];
                            PointF point3 = path.PathPoints[++i];
                            shape.curveTo(point.X, point.Y, point2.X, point2.Y, point3.X, point3.Y);
                            pathType = path.PathTypes[i];
                            break;
                        default:
                            Console.WriteLine("Unknown GraphicsPath type: " + type);
                            break;
                    }
                    if ((pathType & 0x80) > 0) {
                        // Specifies that the point is the last point in a closed subpath (figure).
                        shape.closePath();
                    }
                }
                return shape;
    }

    While the following throws the exception:

    		internal static java.awt.Shape ConvertShape(GraphicsPath path)
    		{
               java.awt.geom.GeneralPath shape = new java.awt.geom.GeneralPath();
                shape.setWindingRule((int)path.FillMode);
    
    			// get these here because a lot of processing goes on to generate these arrays
    			PointF[] points = path.PathPoints;
    			byte[] types = path.PathTypes;
    			int pointCount = path.PointCount;
    
    			for (int i = 0; i < pointCount; i++) {
                    byte pathType = types[i];
                    int type = pathType & 0x07;
                    PointF point = points[i];
                    switch (type) {
                        case 0:
                            // Indicates that the point is the start of a figure. 
                            shape.moveTo(point.X, point.Y);
                            break;
                        case 1:
                            // Indicates that the point is one of the two endpoints of a line. 
                            shape.lineTo(point.X, point.Y);
                            break;
                        case 3:
                            // Indicates that the point is an endpoint or control point of a cubic B?zier spline. 
                            PointF point2 = points[++i];
                            PointF point3 = points[++i];
                            shape.curveTo(point.X, point.Y, point2.X, point2.Y, point3.X, point3.Y);
                            pathType = types[i];
                            break;
                        default:
                            Console.WriteLine("Unknown GraphicsPath type: " + type);
                            break;
                    }
                    if ((pathType & 0x80) > 0) {
                        // Specifies that the point is the last point in a closed subpath (figure).
                        shape.closePath();
                    }
                }
                return shape;
    }

    Using the debugger won't drop me in the source code. I think it's because this is created in IKVM and those DLLs are then copied across so no debug info with them. I'm going to try logging events.


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing

    Tuesday, July 3, 2018 1:25 AM
  • I found it - the exception comes from calling 

    PointF[] points = path.PathPoints;
    byte[] types = path.PathTypes;

    when path.PointCount == 0.

    Please report this as a bug to the appropriate team.

    Also, please suggest that path.PathPoints & path.PathTypes have a cached array that they return on subsequent calls. Building any array on each call to a property is a very bad idea.

    thanks - dave


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing

    • Marked as answer by DavidThi808 Tuesday, July 3, 2018 6:57 AM
    Tuesday, July 3, 2018 6:57 AM