gbaychev / NClass

NClass - the free UML editor, reloaded
GNU General Public License v3.0
171 stars 50 forks source link

Cannot generate PDF #45

Open Baltasarq opened 4 years ago

Baltasarq commented 4 years ago

I'm using Manjaro Linux with mono 6.10.

When trying to generate PDF, and after clicking Ok in the dialog, NClass crashes with the following stack trace:

System.EntryPointNotFoundException: GetDC assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) PdfSharp.Internal.NativeMethods.GetDC(intptr)
  at PdfSharp.Fonts.OpenType.FontData.CreateGdiFontImage (PdfSharp.Drawing.XFont font, PdfSharp.Drawing.XPdfFontOptions options) [0x00020] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Fonts.OpenType.FontData..ctor (PdfSharp.Drawing.XFont font, PdfSharp.Drawing.XPdfFontOptions options) [0x00011] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Fonts.OpenType.OpenTypeDescriptor..ctor (PdfSharp.Drawing.XFont font, PdfSharp.Drawing.XPdfFontOptions options) [0x00028] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Fonts.OpenType.OpenTypeDescriptor..ctor (PdfSharp.Drawing.XFont font) [0x00008] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Fonts.FontDescriptorStock.CreateDescriptor (PdfSharp.Drawing.XFont font) [0x00046] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Drawing.XFont.get_Metrics () [0x0000d] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Drawing.XFont.Initialize () [0x0007e] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PdfSharp.Drawing.XFont..ctor (System.String familyName, System.Double emSize, PdfSharp.Drawing.XFontStyle style) [0x00026] in <2a80a7aa909f4f4394d33f68c6061743>:0 
  at PDFExport.PDFGraphics.FontToXFont (System.Drawing.Font font) [0x0001f] in <ed3dc674d55a465cadf7d0f8ef13bd98>:0 
  at PDFExport.PDFGraphics.DrawString (System.String s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.RectangleF layoutRectangle, System.Drawing.StringFormat format) [0x00008] in <ed3dc674d55a465cadf7d0f8ef13bd98>:0 
  at NClass.DiagramEditor.ClassDiagram.Shapes.TypeShape.DrawHeaderText (NClass.DiagramEditor.IGraphics g, NClass.DiagramEditor.Style style) [0x0015a] in <6ebb94798b114ed1b331f3764e45c037>:0 
  at NClass.DiagramEditor.ClassDiagram.Shapes.TypeShape.Draw (NClass.DiagramEditor.IGraphics g, System.Boolean onScreen, NClass.DiagramEditor.Style style) [0x00009] in <6ebb94798b114ed1b331f3764e45c037>:0 
  at NClass.DiagramEditor.Diagrams.Diagram`1[T].Print (NClass.DiagramEditor.IGraphics g, System.Boolean selectedOnly, NClass.DiagramEditor.Style style) [0x000ef] in <6ebb94798b114ed1b331f3764e45c037>:0 
  at PDFExport.PDFExporter.Export () [0x00147] in <ed3dc674d55a465cadf7d0f8ef13bd98>:0 
  at PDFExport.PDFExportPlugin.Launch () [0x0012c] in <ed3dc674d55a465cadf7d0f8ef13bd98>:0 
  at PDFExport.PDFExportPlugin.menuItem_Click (System.Object sender, System.EventArgs e) [0x00000] in <ed3dc674d55a465cadf7d0f8ef13bd98>:0 
  at System.Windows.Forms.ToolStripItem.OnClick (System.EventArgs e) [0x00019] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripMenuItem.OnClick (System.EventArgs e) [0x00090] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripMenuItem.HandleClick (System.Int32 mouse_clicks, System.EventArgs e) [0x00000] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripItem.FireEvent (System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met) [0x00054] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.ToolStripItem.FireEvent(System.EventArgs,System.Windows.Forms.ToolStripItemEventType)
  at System.Windows.Forms.ToolStrip.OnMouseUp (System.Windows.Forms.MouseEventArgs mea) [0x00048] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripDropDown.OnMouseUp (System.Windows.Forms.MouseEventArgs mea) [0x00000] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.Control.WmLButtonUp (System.Windows.Forms.Message& m) [0x00078] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x001b4] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message& m) [0x00000] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStrip.WndProc (System.Windows.Forms.Message& m) [0x00000] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripDropDown.WndProc (System.Windows.Forms.Message& m) [0x00017] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x0000b] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.NativeWindow.WndProc (System.IntPtr hWnd, System.Windows.Forms.Msg msg, System.IntPtr wParam, System.IntPtr lParam) [0x00085] in <313abb6e08e943459ea3b455bc2f9adb>:0
gbaychev commented 4 years ago

Now this is going to be real pain in the ass. PdfSharp pinvokes Windows methods (GetDC), which are of course not present under linux. Unless someone can tell me an open source project for pdf generation, which does not rely on native mechanism, this cannot be fixed.

As a workaround I suggest exporting your diagram as a png and then embedding it into pdf. I'm terribly sorry. :(

Baltasarq commented 4 years ago

Indeed PDF rendering seems something tricky for the .NET world, though it is something really common in the JavaScript scene, for example.

Looking around, it seems that the only library that is cross-platform and free/open-source (there are a few open-source libs which are not free), is wkhtmltopdf.

There exists a tutorial for using wkhtmltopdf.

That said, I suppose it'd be a pain in the ass to port your source code from pdfsharp to wkhtmltopdf, and also repackage your app with a native dll lib dependency, one for each OS.

Baltasarq commented 4 years ago

Anyway, a better error handling would be needed, saying that the plugin could not be executed or something like that, instead of crashing.

Baltasarq commented 4 years ago

Another idea would be to just generate HTML, which can be easily converted to PDF or even any other format.

gbaychev commented 4 years ago

You're correct, I also thought about extending the plugin system, so that you one signify whether or not a plugin supports mono. As for the actual issue, there is some hope:

I'm gonna run some experiments these days.

gbaychev commented 4 years ago

Hey, @Baltasarq , this should be fixed now, do you want to give it a try? https://baychev.visualstudio.com/9beaa731-7bd9-4de3-b1c7-f733d1d99c42/_apis/build/builds/113/artifacts?artifactName=drop&api-version=6.0&%24format=zip

Baltasarq commented 4 years ago

Yep, now the PDF extractor works!!

A minor issue is that NClass asks you to whether open the obtained PDF or not. If you do, then it crashes. It sees it's using a P/Invoke of some kind (System.Diagnostics.Process.StartWithShellExecuteEx).

System.ComponentModel.Win32Exception (0x80004005): Access denied
  at System.Diagnostics.Process.StartWithShellExecuteEx (System.Diagnostics.ProcessStartInfo startInfo) [0x00102] in <11033cee9c4147e6ac319423397ec1b6>:0 
  at System.Diagnostics.Process.Start () [0x00032] in <11033cee9c4147e6ac319423397ec1b6>:0 
  at (wrapper remoting-invoke-with-check) System.Diagnostics.Process.Start()
  at System.Diagnostics.Process.Start (System.Diagnostics.ProcessStartInfo startInfo) [0x0001b] in <11033cee9c4147e6ac319423397ec1b6>:0 
  at System.Diagnostics.Process.Start (System.String fileName) [0x00006] in <11033cee9c4147e6ac319423397ec1b6>:0 
  at PDFExport.PDFExportPlugin.Launch () [0x00181] in <90e8013d90964116ab8f8db487895503>:0 
  at PDFExport.PDFExportPlugin.menuItem_Click (System.Object sender, System.EventArgs e) [0x00000] in <90e8013d90964116ab8f8db487895503>:0 
  at System.Windows.Forms.ToolStripItem.OnClick (System.EventArgs e) [0x00019] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripMenuItem.OnClick (System.EventArgs e) [0x00090] in <313abb6e08e943459ea3b455bc2f9adb>:0 
  at System.Windows.Forms.ToolStripMenuItem.HandleClick (System.Int32 mouse_clicks, System.EventArgs e) [0x00000] in <313abb6e08e943459ea3b455bc2f9adb>:0

This is strange, since the trigger is line 183 in PDFExport/PDFExportPlugin.cs:

Process.Start(fileName);

Something that I remember doing but now throws that exception. I've been able to reproduce it with a simple program:

using System.Diagnostics;

class Viewer {
        static void Main(string[] args)
        {
                Process.Start( args[ 0 ] );                 // Crashes with the exception above
                Process.Start( "xdg-open", args[ 0 ] );     // Works!
        }
}

So the options are:

  1. Wrap that call around a try... except and report the user it could not be launched.
  2. Use that Mono helper class to detect mono and then use xdg-open to open the PDF. I'd still use also option 1.
  3. Detect if you are using Mono and then do not offer the user to open anything.

xdg-open is available in all major linux distributions, so though annoying, I'd use 1 & 2 together or directly 3. ;-)

gbaychev commented 4 years ago

Shit, you're right, I totally forgot about one. Basically, what happens is, that if you pass the name only, .net tries to do ShellExec, what is the Windows equivalent of xdg-open (which I knew nothing about until now).

Yes, I will go with your suggestion - wrap it in an exception handler and if on mono - do xdg-open.

Baltasarq commented 4 years ago

Great!!

gbaychev commented 4 years ago

This should be fine now. I have another question, does the 'open pdf dialog' look the same on your machine? With not enough place for the buttons?

image

Baltasarq commented 4 years ago

Most dialogs have the same problem, though I did not want to overwhelm you, since after all it is not critical. I suppose this does not happen in Windows.. Again, I guess this is for using the designer with absolute sizes and positions. I'll take a look at the code and get back to you on monday.

On Sat, Sep 12, 2020 at 2:35 PM Georgi Baychev notifications@github.com wrote:

This should be fine now. I have another question, does the 'open pdf dialog' look the same on your machine? With not enough place for the buttons?

[image: image] https://user-images.githubusercontent.com/3358056/92995587-20abe800-f505-11ea-9cdf-bef644571fa3.png

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/gbaychev/NClass/issues/45#issuecomment-691481290, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABRCNHE3ARWOXGSQEMNPK3SFNTI7ANCNFSM4QJP7JQQ .

-- -- Baltasar