0

I am using Mitov's IGDIPlus library for Delphi. I am getting Exception "Generic Error" in a completelly innocent situation. I have five overlapping rectangles and would like to use aPath.outline() to find outline path (I am running this example on Win7, with all outline related patches applied).

uses
System.Types, IGDIPlus, VCL.IGDIPlusExt;


procedure TForm1.FormPaint(Sender: TObject);
var
  AGraphics       : IGPGraphics;
  APath,aPathO    : IGPGraphicsPath;

begin
  AGraphics := TIGPGraphics.Create( Canvas );
  AGraphics.SmoothingMode := SmoothingModeAntiAlias;
  AGraphics.TextRenderingHint := TextRenderingHintAntiAlias;
  aPath := TIGPGraphicsPath.create() ;
  // this path gives generic error 
  aPath.addRectangle(73,201,108,96);
// --------the difference----------
  aPath.addRectangle(73,292,58,96);
// --------the difference----------
  aPath.addRectangle(73,383,108,96);
  aPath.addRectangle(177,201,108,96);
  aPath.addRectangle(177,383,108,96);

  try
    aPathO := apath.clone().Outline();
    AGraphics.DrawPath(TIGPPen.Create( aclRed,1),
      aPathO);
  except
    on E: Exception do
    begin
      AGraphics.DrawStringF( e.message,
                            TIGPFont.Create( 'Microsoft Sans Serif', 16, [ fsBold ] ),
                            TPointF.Create( 23, 23 ),
                            TIGPSolidBrush.Create( aclRed ) )   ;

      AGraphics.DrawPath(TIGPPen.Create( aclRed,1),
        aPath);
    end;
  end;
  aPath.reset();
// this path works fine
  aPath.addRectangle(373,201,108,96);
// --------the difference----------
  aPath.addRectangle(373,292,108,96);    
// --------the difference----------
  aPath.addRectangle(373,383,108,96);
  aPath.addRectangle(477,201,108,96);
  aPath.addRectangle(477,383,108,96);

  try
    aPathO := apath.clone().Outline();
    AGraphics.DrawPath(TIGPPen.Create( aclRed,1),
      aPathO);
    AGraphics.DrawStringF( 'it works',
                            TIGPFont.Create( 'Microsoft Sans Serif', 16, [ fsBold ] ),
                            TPointF.Create( 423, 23 ),
                            TIGPSolidBrush.Create( aclRed ) )   ;

  except
    on E: Exception do
    begin
      AGraphics.DrawStringF( e.message,
                            TIGPFont.Create( 'Microsoft Sans Serif', 16, [ fsBold ] ),
                            TPointF.Create( 223, 23 ),
                            TIGPSolidBrush.Create( aclRed ) )   ;

      AGraphics.DrawPath(TIGPPen.Create( aclRed,1),
        aPath);
    end;
  end;
end;

Any ideas, suggestions are welcome.

Running the same example in C# gives the same error (using Outline a path with GDI+ in .Net )



    GraphicsPath aPath = new GraphicsPath();
                aPath.AddRectangle(new Rectangle(73, 201, 108, 96));
                aPath.AddRectangle(new Rectangle(73, 292, 58, 96));
                aPath.AddRectangle(new Rectangle(73, 383, 108, 96));
                aPath.AddRectangle(new Rectangle(177, 201, 108, 96));
                aPath.AddRectangle(new Rectangle(177, 383, 108, 96));

                HandleRef handle = new HandleRef(aPath, (IntPtr)aPath.GetType().GetField("nativePath", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(aPath));
                try
                {

                    int status = GdipWindingModeOutline(handle, IntPtr.Zero, 0.25F);
                    using (Pen outlinePen = new Pen(Color.FromArgb(255, Color.Red), 2))
                    {
                        g.DrawPath(outlinePen, aPath);
                    }
                }

                catch (Exception exp)
                { ...
                }  

GdipWindingModeOutline function returns status=1 (Generic error)

Because I really need to use the outline curve and the direct way aPath.clone().outline() is due gdi+ error impossible, I have to go arround. The suitable solution - perhaps not the best, but works - could be:



        procedure TForm1.FormPaint(Sender: TObject);
        var
          AGraphics       : IGPGraphics;
          APath,aPathO    : IGPGraphicsPath;
          aRegion         : IGPRegion;
          aScan           :  TArray;
          aMatrix         : IGPmatrix;

        begin
          AGraphics := TIGPGraphics.Create( Canvas );
          AGraphics.SmoothingMode := SmoothingModeAntiAlias;
          AGraphics.TextRenderingHint := TextRenderingHintAntiAlias;
          aPath := TIGPGraphicsPath.create() ;
          aRegion := TIGPRegion.create().MakeEmpty();
          aRegion.Union(  TIGPRect.create(73,201,108,96));
          aRegion.Union(  TIGPRect.create(73,292,58,96));
          aRegion.Union(  TIGPRect.create(73,383,108,96));
          aRegion.Union(  TIGPRect.create(177,201,108,96));
          aRegion.Union(  TIGPRect.create(177,383,108,96));
          aMatrix := TIGPMatrix.Create();
          aScan := lRegion.GetRegionScans(aMatrix);
          for i  := 0 to High(aScan) do
            aPath.addRectangle( GPInflateRect( aScan[i], 1));


          aPathO := aPath.Clone().Outline();
          AGraphics.DrawPath(TIGPPen.Create( aclRed,1), aPathO);

      end;

Community
  • 1
  • 1
EvaF
  • 1
  • 1

1 Answers1

0

Your line AGraphics.DrawPath(TIGPPen.Create( aclRed,1), ... is dangerous in teh Delphi world if you use interfaces (which this library obviously does). Delphi has some problems when it comes to reference counting and object creation within function calls (I don't remember which though...) .. Try to not create the object within the function call but rather define a new local variable that holds the reference to the interface.

mrabat
  • 802
  • 7
  • 15
  • No , the problem is not in this line ( the code is based on Mitov demo), the generic error counts from the line above `aPathO := apath.clone().Outline();` It would be helpful if someone tried to run similiar example in C# or some different language – EvaF Apr 22 '16 at 15:18