Giter Club home page Giter Club logo

Comments (11)

mgieseki avatar mgieseki commented on August 17, 2024 2

I guess it's this issue. The behavior of operator >> differs between libstdc++ and libc++ if applied to floating point numbers. libc++ seems to be the default on Mac.
While ligstdc++ just stops parsing a number as soon as an unexpected character occurs, libc++ immediately raises an error. So, when parsing the path commands M 0 2.50937L 2.50937 2.50937 on a Mac, it fails at the L because it's not a valid digit of the y-coordinate. libstdc++ just stops and returns the proper value 2.50937.
I think I need to find some workaround for this. At the moment, there's probably nothing you can do about it.

from dvisvgm.

mgieseki avatar mgieseki commented on August 17, 2024 2

I've fixed the issue locally and will commit the patch after some more testing.

from dvisvgm.

mgieseki avatar mgieseki commented on August 17, 2024

Sorry, I can't help with Asymptote issues here. Please upload the corresponding DVI file demo-unitcircle_.dvi.

from dvisvgm.

kiryph avatar kiryph commented on August 17, 2024

How should I upload the dvi file?
Is following fine:

÷����À�;�����è� TeX output 2023.04.27:1504�����������������������������������������ÿÿÿÿ�ï�header=l3backend-dvips.pro��h�®��´lR�-�®��÷lR�����8�ôï>dvisvgm:bbox f 57.659449bp 64.563436bp 60.159449bp 67.063436bpï®dvisvgm:raw{?nl}<g transform='matrix(0.996264 0 0 0.996264 57.6594 64.5634)'>{?nl}<path d='M 0 2.50937L 2.50937 2.50937L 2.50937 0L 0 0L 0 2.50937Z' fill='#ffffff'/>{?nl}</g>ò���Çdvisvgm:raw{?nl}<g transform='matrix(0.996264 0 0 0.996264 57.6594 64.5634)'>{?nl}<path d='M 2.25844 1.25469C 2.25844 0.700332 1.80904 0.250938 1.25469 0.250937C 0.700332 0.250937 0.250937 0.700332 0.250937 1.25469C 0.250937 1.80904 0.700332 2.25844 1.25469 2.25844C 1.80904 2.25844 2.25844 1.80904 2.25844 1.25469Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='0.501875'/>{?nl}</g>�����������ø���*���À�;�����è�h�®�;�®����ù���V�ßßßßßßß

ZIP file
demo-unitcircle_.dvi.zip

from dvisvgm.

mgieseki avatar mgieseki commented on August 17, 2024

Thanks for uploading the file. Unfortunately, I can't reproduce the error. The file converts correctly on my machines (Linux and Windows). Maybe someone needs to take a closer look at this on a Mac (which I don't have access to).

from dvisvgm.

kiryph avatar kiryph commented on August 17, 2024

Currently, I am little bit lost:

  1. I have already tried three different Ghostscript versions

based on recent issues on macOS


  1. A rectangle compiles fine on macOS for SVG/WebGL output:
draw(box((0,0), (2,1)));

A diff between both intermediate tex files containing special commands:

 \special{dvisvgm:raw{?nl}%
-<g transform='matrix(0.996264 0 0 0.996264 56.6594 65.5634)'>{?nl}%
-<path d='M 0 1.50562L 2.50937 1.50562L 2.50937 0L 0 0L 0 1.50562Z' fill='#ffffff'/>{?nl}%
+<g transform='matrix(0.996264 0 0 0.996264 57.6594 64.5634)'>{?nl}%
+<path d='M 0 2.50937L 2.50937 2.50937L 2.50937 0L 0 0L 0 2.50937Z' fill='#ffffff'/>{?nl}%
 </g>}\catcode`\#=6%
 \catcode`\#=11%
 \special{dvisvgm:raw{?nl}%
-<g transform='matrix(0.996264 0 0 0.996264 56.6594 65.5634)'>{?nl}%
-<path d='M 0.250937 1.25469L 2.25844 1.25469L 2.25844 0.250937L 0.250937 0.250937L 0.250937 1.25469Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='0.501875'/>{?nl}%
+<g transform='matrix(0.996264 0 0 0.996264 57.6594 64.5634)'>{?nl}%
+<path d='M 2.25844 1.25469C 2.25844 0.700332, 1.80904 0.250938, 1.25469 0.250937C 0.700332 0.250937, 0.250937 0.700332, 0.250937 1.25469C 0.250937 1.80904, 0.700332 2.25844, 1.25469 2.25844C 1.80904 2.25844, 2.25844 1.80904, 2.25844 1.25469Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='0.501875'/>{?nl}%

shows that the most outstanding difference is the cubic Bézier curve.

The error XML error: error in path data: number expected (premature end of data)
comes from GraphicsPathParser.hpp.

  1. I have already raised an issue at asymptote.

vectorgraphics/asymptote#375

As you say, it seems to be that the generated dvi file is fine. So it might not be an issue on the side of asymptote but a platform-specific one.


Do you have an idea in which direction I could look? Is there anything platform-dependent regarding the GraphsPathParser.hpp?

My current assumption is that I have to compile dvisvgm myself with debug symbols to see what is going on in GraphsPathParser which I would really like to avoid.

from dvisvgm.

kiryph avatar kiryph commented on August 17, 2024

Thanks for pointing out this difference between the two implementations of the STL regarding the operator >>. This sounds like the reason, even though the rectangle example works.

What baffles me in particular is that this issue is 10 years old (llvm/llvm-project#18156).

Writing correct parsers is IMHO always challenging, and something like SVG might be one of the even more complicated ones (xml+properties like paths). However, finding a license-compatible lightweight ready to use, actively maintained third-party library is also not a simple story.

Anyhow, I hope you find a workaround in the parser of dvisvgm and can fix it in one of the next releases of dvisvgm.

from dvisvgm.

kiryph avatar kiryph commented on August 17, 2024

I did a little bit of further digging:

I took the test example from llvm/llvm-project#18156 and added a few lines related to SVG path parsing:

demo-double-stream.cpp
#include <sstream>
#include <iostream>

using namespace std;

void extract_double(const string & s)
{
  stringstream ss;
  double d;
  
  // testing number only
  ss << s;
  ss >> d;
  if(!ss.fail())
    cout << "'" << ss.str() << "' converted to " << d << endl;
  else
    cout << "'" << ss.str() << "' failed to convert to double" << endl;
}

int main()
{
  cout << "local is " << setlocale(LC_ALL, NULL) << endl;
  
  extract_double("-4.9");
  extract_double("-4.9 X");
  extract_double("-4.9_");

  cout << endl << "SVG Path parsing:" << endl;
  extract_double("2.50937L");
  extract_double("0L");
  extract_double("2.50937Z");

  cout << endl << "Issue between libc++ (llvm) and libstdc++ (gcc):" << endl;
  extract_double("-4.9d");
  extract_double("-4.9X");

  cout << "SVG Path parsing:" << endl;
  extract_double("1.25469C");
}

The results are

libc++ (llvm)

❯ clang++ -o parse_double-libc++ demo-double-stream.cpp
❯ ./parse_double-libc++
local is C
'-4.9' converted to -4.9
'-4.9 X' converted to -4.9
'-4.9_' converted to -4.9

SVG Path parsing:
'2.50937L' converted to 2.50937
'0L' converted to 0
'2.50937Z' converted to 2.50937

Issue between libc++ (llvm) and libstdc++ (gcc):
'-4.9d' failed to convert to double
'-4.9X' failed to convert to double
SVG Path parsing:
'1.25469C' failed to convert to double

libstdc++ (gcc)

❯ g++-12 -o parse_double-libstdc++ demo-double-stream.cpp
❯ ./parse_double-libstdc++
local is C
'-4.9' converted to -4.9
'-4.9 X' converted to -4.9
'-4.9_' converted to -4.9

SVG Path parsing:
'2.50937L' converted to 2.50937
'0L' converted to 0
'2.50937Z' converted to 2.50937

Issue between libc++ (llvm) and libstdc++ (gcc):
'-4.9d' converted to -4.9
'-4.9X' converted to -4.9
SVG Path parsing:
'1.25469C' converted to 1.25469

This confirms that libc++ throws an error for 1.25469C where libstdc++ does not.

Since this issue for libc++ is quite old and shows no sign of an upstream change, IMHO
dvisvgm should take this into account.

As a first step it should be specifically mentioned that libc++ (LLVM) cannot be used for dvisvgm and suggest to use libstdc++ (GCC). However, libstdc++ is not by default available on macOS and makes installation on macOS more complicated. There might also be other reasons why someone would like to use libc++.

Possible options to allow libc++

All of them sound like a major change in the code (new dependencies or a rewrite of the path parser).

I will try to compile dvisvgm myself using libstdc++ on macOS for now.

from dvisvgm.

muzimuzhi avatar muzimuzhi commented on August 17, 2024

I will try to compile dvisvgm myself using libstdc++ on macOS for now.

I hardly know anything about how to compile either dvisvgm or Asymptote on macOS (though I'm on macOS), but if it's a litter bit easier to compile Asymptote on macOS using default settings, for a workaround it seems you can patch Asymptote to always insert a space before M, L, C, and Z.

Relevant lines in Asymptote https://github.com/vectorgraphics/asymptote/blob/494e8120ee967aa9c71ae26e2476b5632211b6e2/texfile.h#L419-L436

Or, does Asymptote allow executing user scripts after it writes to a tex file and before it runs latex command?

from dvisvgm.

kiryph avatar kiryph commented on August 17, 2024

I hardly know anything about how to compile either dvisvgm or Asymptote on macOS (though I'm on macOS), but if it's a litter bit easier to compile Asymptote on macOS using default settings, for a workaround it seems you can patch Asymptote to always insert a space before M, L, C, and Z.

That's actually a suggestion I consider now. I am already struggling compiling dvisvgm since the kpathsea dependency is not easy to fulfil:

Thanks.

Or, does Asymptote allow executing user scripts after it writes to a tex file and before it runs latex command?

Not that I am aware of. I could add a workaround with the --keep option of asy. After the dvisvgm command fails, I could run a script to insert the spaces and run dvisvgm once again. Not a fan and the whole story becomes a little bit of a nightmare.

from dvisvgm.

kiryph avatar kiryph commented on August 17, 2024

I have now patched Asymptote and compiled it myself:

--- a/texfile.h
+++ b/texfile.h
@@ -417,22 +417,22 @@ public:
   }

   void moveto(pair z) {
-    *out << "M";
+    *out << " M";
     writeshifted(z);
   }

   void lineto(pair z) {
-    *out << "L";
+    *out << " L";
     writeshifted(z);
   }

   void curveto(pair zp, pair zm, pair z1) {
-    *out << "C";
+    *out << " C";
     writeshifted(zp); writeshifted(zm); writeshifted(z1);
   }

   void closepath() {
-    *out << "Z";
+    *out << " Z";
   }
❯ asy --version
Asymptote version 2.86-8 [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]

ENABLED OPTIONS:
V3D      3D vector graphics output
WebGL    3D HTML rendering
OpenGL   3D OpenGL rendering
SSBO     GLSL shader storage buffer objects
GSL      GNU Scientific Library (special functions)
FFTW3    Fast Fourier transforms
XDR      External Data Representation (portable binary file format for V3D)
CURL     URL support
LSP      Language Server Protocol
Readline Interactive history and editing
GC       Boehm garbage collector
threads  Render OpenGL in separate thread

DISABLED OPTIONS:
Eigen    Eigenvalue library
Sigsegv  Distinguish stack overflows from segmentation faults

Now I get a webgl output for draw(unitcircle);

However, I leave this issue open, since dvisvgm should handle all valid svg input correctly. Either dvisvgm should not compile with libc++ or find a workaround to deal with the difference between libc++ and libstdc++.

from dvisvgm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.