Comments (11)
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.
I've fixed the issue locally and will commit the patch after some more testing.
from dvisvgm.
Sorry, I can't help with Asymptote issues here. Please upload the corresponding DVI file demo-unitcircle_.dvi
.
from dvisvgm.
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.
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.
Currently, I am little bit lost:
- I have already tried three different Ghostscript versions
- 10.00.0 from https://www.tug.org/mactex/morepackages.html
- 10.01.1 from https://pages.uoregon.edu/koch/
- 9.56.1 from https://pages.uoregon.edu/koch/
based on recent issues on macOS
- 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
.
- I have already raised an issue at asymptote.
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.
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.
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++
- use a different method to read in doubles, e.g.
- Two step parsing: 1) split path string on
M
,L
,C
, ... or insert spaces beforeM
,L
,C
(https://www.w3.org/TR/SVG2/paths.html) and 2) read numbers - use svg parser from lib2geom (used by Inkscape). However, lib2geom comes with heavy dependencies Boost, glib, GSL, Cairo, C++17 and the test file https://gitlab.com/inkscape/lib2geom/-/blob/master/tests/path-test.cpp is using spaces between path commands and numbers which begs the question if lib2geom can handle missing spaces. However, since Inkscape is a popular program, I suspect someone would have run into this issue already.
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.
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.
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:
- https://tobywf.com/2017/04/build-dvisvgm-kpathsea-on-macos/
- https://gist.github.com/tobywf/aeeeee63053aaaa841b4032963406684
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.
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)
- Baseline incorrect with Chinese characters HOT 15
- Ghostscript 10.01.0+ support HOT 6
- Hyphen character missing when using luatex with DVI output HOT 5
- PDF -> SVG: Pixels cut-off on right border HOT 4
- pstricks: PostScript error: undefined in NodeScale HOT 7
- Request for reduced information verbosity level/flag HOT 6
- TL build patch: potrace HOT 2
- TL build patch: main src/Makefile.am HOT 1
- InvalidDVIFileException in upTeX DVI only on Solaris HOT 2
- Deferred initialization of PS doesn't work HOT 4
- color gradient missing in svg file HOT 4
- Breakage with libgs-10.02 creating svg file from asy. HOT 15
- 3D plots in PDFs generated with `interp` shading disappear from SVG HOT 1
- Unable to convert Japanese characters to SVG from DVI HOT 13
- Ghostscript sill not found (macOS) HOT 4
- Wrong clipping and viewport with multiple pages converted at once HOT 2
- element id overlap HOT 3
- [feature request] id and class attributes for nodes and paths HOT 3
- dvisvgm hangs when converting pdf with tikz pattern to svg HOT 10
- `transparency group=knockout` does not work HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dvisvgm.