mgieseki / dvisvgm

A fast DVI, EPS, and PDF to SVG converter
https://dvisvgm.de
GNU General Public License v3.0
306 stars 33 forks source link

file size optimization: defs/use for letters #190

Closed nschloe closed 2 years ago

nschloe commented 2 years ago

From this LaTeX,

\documentclass{standalone}

\begin{document}
a a a a a a a
\end{document}

I'm getting the SVG

<?xml version='1.0' encoding='UTF-8'?>
<!-- This file was generated by dvisvgm 2.13.4 -->
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='54.77pt' height='4.57pt' viewBox='0 -4.57 54.77 4.57'>
<g id='page1'>
<g transform='matrix(1 0 0 -1 0 0)'>
<path d='M4.81125 .996139V1.553951H4.56219V.996139C4.56219 .418327 4.31313 .358639 4.20375 .358639C3.875 .358639 3.835 .806764 3.835 .856764V2.848951C3.835 3.267391 3.835 3.655831 3.47656 4.024261C3.08812 4.412701 2.59 4.572081 2.11188 4.572081C1.295 4.572081 .6075 4.103951 .6075 3.446451C.6075 3.147701 .806875 2.978331 1.06594 2.978331C1.34469 2.978331 1.52406 3.177701 1.52406 3.436761C1.52406 3.556141 1.47438 3.884891 1.01594 3.894891C1.285 4.243331 1.77313 4.353011 2.09188 4.353011C2.58 4.353011 3.14781 3.964581 3.14781 3.078011V2.709581C2.63969 2.679581 1.9425 2.649581 1.315 2.350831C.567813 2.012081 .31875 1.494261 .31875 1.055827C.31875 .248952 1.285-.000111 1.9125-.000111C2.57-.000111 3.02813 .398327 3.2175 .866764C3.25719 .468327 3.52625 .049889 3.99437 .049889C4.20375 .049889 4.81125 .189264 4.81125 .996139ZM3.14781 1.504261C3.14781 .557702 2.43062 .219264 1.98219 .219264C1.49406 .219264 1.08563 .567702 1.08563 1.065827C1.08563 1.613641 1.50406 2.440511 3.14781 2.500201V1.504261Z'/>
<path d='M13.1093 .996139V1.553951H12.8602V.996139C12.8602 .418327 12.6112 .358639 12.5018 .358639C12.173 .358639 12.133 .806764 12.133 .856764V2.848951C12.133 3.267391 12.133 3.655831 11.7746 4.024261C11.3862 4.412701 10.888 4.572081 10.4099 4.572081C9.59305 4.572081 8.90555 4.103951 8.90555 3.446451C8.90555 3.147701 9.10492 2.978331 9.36398 2.978331C9.64273 2.978331 9.82211 3.177701 9.82211 3.436761C9.82211 3.556141 9.77242 3.884891 9.31398 3.894891C9.58305 4.243331 10.0712 4.353011 10.3899 4.353011C10.878 4.353011 11.4459 3.964581 11.4459 3.078011V2.709581C10.9377 2.679581 10.2405 2.649581 9.61305 2.350831C8.86586 2.012081 8.6168 1.494261 8.6168 1.055827C8.6168 .248952 9.58305-.000111 10.2105-.000111C10.868-.000111 11.3262 .398327 11.5155 .866764C11.5552 .468327 11.8243 .049889 12.2924 .049889C12.5018 .049889 13.1093 .189264 13.1093 .996139ZM11.4459 1.504261C11.4459 .557702 10.7287 .219264 10.2802 .219264C9.79211 .219264 9.38367 .567702 9.38367 1.065827C9.38367 1.613641 9.80211 2.440511 11.4459 2.500201V1.504261Z'/>
<path d='M21.4073 .996139V1.553951H21.1583V.996139C21.1583 .418327 20.9092 .358639 20.7998 .358639C20.4711 .358639 20.4311 .806764 20.4311 .856764V2.848951C20.4311 3.267391 20.4311 3.655831 20.0727 4.024261C19.6842 4.412701 19.1861 4.572081 18.708 4.572081C17.8911 4.572081 17.2036 4.103951 17.2036 3.446451C17.2036 3.147701 17.403 2.978331 17.662 2.978331C17.9408 2.978331 18.1202 3.177701 18.1202 3.436761C18.1202 3.556141 18.0705 3.884891 17.612 3.894891C17.8811 4.243331 18.3692 4.353011 18.688 4.353011C19.1761 4.353011 19.7439 3.964581 19.7439 3.078011V2.709581C19.2358 2.679581 18.5386 2.649581 17.9111 2.350831C17.1639 2.012081 16.9148 1.494261 16.9148 1.055827C16.9148 .248952 17.8811-.000111 18.5086-.000111C19.1661-.000111 19.6242 .398327 19.8136 .866764C19.8533 .468327 20.1223 .049889 20.5905 .049889C20.7998 .049889 21.4073 .189264 21.4073 .996139ZM19.7439 1.504261C19.7439 .557702 19.0267 .219264 18.5783 .219264C18.0902 .219264 17.6817 .567702 17.6817 1.065827C17.6817 1.613641 18.1002 2.440511 19.7439 2.500201V1.504261Z'/>
<path d='M29.7053 .996139V1.553951H29.4562V.996139C29.4562 .418327 29.2072 .358639 29.0978 .358639C28.7691 .358639 28.7291 .806764 28.7291 .856764V2.848951C28.7291 3.267391 28.7291 3.655831 28.3706 4.024261C27.9822 4.412701 27.4841 4.572081 27.0059 4.572081C26.1891 4.572081 25.5016 4.103951 25.5016 3.446451C25.5016 3.147701 25.7009 2.978331 25.96 2.978331C26.2388 2.978331 26.4181 3.177701 26.4181 3.436761C26.4181 3.556141 26.3684 3.884891 25.91 3.894891C26.1791 4.243331 26.6672 4.353011 26.9859 4.353011C27.4741 4.353011 28.0419 3.964581 28.0419 3.078011V2.709581C27.5338 2.679581 26.8366 2.649581 26.2091 2.350831C25.4619 2.012081 25.2128 1.494261 25.2128 1.055827C25.2128 .248952 26.1791-.000111 26.8066-.000111C27.4641-.000111 27.9222 .398327 28.1116 .866764C28.1513 .468327 28.4203 .049889 28.8884 .049889C29.0978 .049889 29.7053 .189264 29.7053 .996139ZM28.0419 1.504261C28.0419 .557702 27.3247 .219264 26.8762 .219264C26.3881 .219264 25.9797 .567702 25.9797 1.065827C25.9797 1.613641 26.3981 2.440511 28.0419 2.500201V1.504261Z'/>
<path d='M38.0034 .996139V1.553951H37.7543V.996139C37.7543 .418327 37.5052 .358639 37.3959 .358639C37.0671 .358639 37.0271 .806764 37.0271 .856764V2.848951C37.0271 3.267391 37.0271 3.655831 36.6687 4.024261C36.2802 4.412701 35.7821 4.572081 35.304 4.572081C34.4871 4.572081 33.7996 4.103951 33.7996 3.446451C33.7996 3.147701 33.999 2.978331 34.258 2.978331C34.5368 2.978331 34.7162 3.177701 34.7162 3.436761C34.7162 3.556141 34.6665 3.884891 34.208 3.894891C34.4771 4.243331 34.9652 4.353011 35.284 4.353011C35.7721 4.353011 36.3399 3.964581 36.3399 3.078011V2.709581C35.8318 2.679581 35.1346 2.649581 34.5071 2.350831C33.7599 2.012081 33.5109 1.494261 33.5109 1.055827C33.5109 .248952 34.4771-.000111 35.1046-.000111C35.7621-.000111 36.2202 .398327 36.4096 .866764C36.4493 .468327 36.7184 .049889 37.1865 .049889C37.3959 .049889 38.0034 .189264 38.0034 .996139ZM36.3399 1.504261C36.3399 .557702 35.6227 .219264 35.1743 .219264C34.6862 .219264 34.2777 .567702 34.2777 1.065827C34.2777 1.613641 34.6962 2.440511 36.3399 2.500201V1.504261Z'/>
<path d='M46.3014 .996139V1.553951H46.0523V.996139C46.0523 .418327 45.8033 .358639 45.6939 .358639C45.3652 .358639 45.3252 .806764 45.3252 .856764V2.848951C45.3252 3.267391 45.3252 3.655831 44.9667 4.024261C44.5783 4.412701 44.0802 4.572081 43.602 4.572081C42.7852 4.572081 42.0977 4.103951 42.0977 3.446451C42.0977 3.147701 42.297 2.978331 42.5561 2.978331C42.8348 2.978331 43.0142 3.177701 43.0142 3.436761C43.0142 3.556141 42.9645 3.884891 42.5061 3.894891C42.7752 4.243331 43.2633 4.353011 43.582 4.353011C44.0702 4.353011 44.638 3.964581 44.638 3.078011V2.709581C44.1298 2.679581 43.4327 2.649581 42.8052 2.350831C42.058 2.012081 41.8089 1.494261 41.8089 1.055827C41.8089 .248952 42.7752-.000111 43.4027-.000111C44.0602-.000111 44.5183 .398327 44.7077 .866764C44.7473 .468327 45.0164 .049889 45.4845 .049889C45.6939 .049889 46.3014 .189264 46.3014 .996139ZM44.638 1.504261C44.638 .557702 43.9208 .219264 43.4723 .219264C42.9842 .219264 42.5758 .567702 42.5758 1.065827C42.5758 1.613641 42.9942 2.440511 44.638 2.500201V1.504261Z'/>
<path d='M54.5995 .996139V1.553951H54.3504V.996139C54.3504 .418327 54.1013 .358639 53.992 .358639C53.6632 .358639 53.6232 .806764 53.6232 .856764V2.848951C53.6232 3.267391 53.6232 3.655831 53.2648 4.024261C52.8763 4.412701 52.3782 4.572081 51.9001 4.572081C51.0832 4.572081 50.3957 4.103951 50.3957 3.446451C50.3957 3.147701 50.5951 2.978331 50.8541 2.978331C51.1329 2.978331 51.3123 3.177701 51.3123 3.436761C51.3123 3.556141 51.2626 3.884891 50.8041 3.894891C51.0732 4.243331 51.5613 4.353011 51.8801 4.353011C52.3682 4.353011 52.936 3.964581 52.936 3.078011V2.709581C52.4279 2.679581 51.7307 2.649581 51.1032 2.350831C50.356 2.012081 50.107 1.494261 50.107 1.055827C50.107 .248952 51.0732-.000111 51.7007-.000111C52.3582-.000111 52.8163 .398327 53.0057 .866764C53.0454 .468327 53.3145 .049889 53.7826 .049889C53.992 .049889 54.5995 .189264 54.5995 .996139ZM52.936 1.504261C52.936 .557702 52.2188 .219264 51.7704 .219264C51.2823 .219264 50.8738 .567702 50.8738 1.065827C50.8738 1.613641 51.2923 2.440511 52.936 2.500201V1.504261Z'/>
</g>
</g>
</svg>

For reducing the file size, would it be possible to <defs>, <use> to define letters, and use them with a given offset? Something like

<defs>
    <path id="B" d="some path" />
</defs>
<use xlink:href="#B" x="16.597" />

Minifiers could perhaps also do the job, but I guess it's easier on a PDF level to identify individual characters. (Perhaps I'm wrong.)

mgieseki commented 2 years ago

dvisvgm already does this when converting DVI files and if option --no-fonts is given. It's currently not possible with PS/PDF input files because Ghostscript does the font processing of these files and dvisvgm only receives the resulting paths with no information of their origin. The processing of PS/PDF files is more or less a by-product of dvisvgm's PS/PDF \special handlers. The main functionality is still the conversion of DVI files which provides the most flexibility.

<?xml version='1.0' encoding='UTF-8'?>
<!-- This file was generated by dvisvgm 2.13.4 -->
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='54.79pt' height='4.29pt' viewBox='-72 -72 54.79 4.29'>
<defs>
<path id='g0-97' d='M3.32-.76C3.36-.36 3.63 .06 4.09 .06C4.3 .06 4.91-.08 4.91-.89V-1.44H4.66V-.89C4.66-.31 4.41-.25 4.3-.25C3.98-.25 3.94-.7 3.94-.75V-2.74C3.94-3.16 3.94-3.55 3.58-3.92C3.19-4.3 2.69-4.46 2.21-4.46C1.39-4.46 .71-4 .71-3.34C.71-3.04 .91-2.87 1.17-2.87C1.44-2.87 1.62-3.07 1.62-3.33C1.62-3.45 1.57-3.78 1.12-3.79C1.38-4.13 1.87-4.24 2.19-4.24C2.68-4.24 3.25-3.86 3.25-2.97V-2.6C2.74-2.57 2.04-2.54 1.41-2.24C.67-1.9 .42-1.38 .42-.95C.42-.14 1.38 .11 2.01 .11C2.67 .11 3.13-.29 3.32-.76ZM3.25-2.39V-1.39C3.25-.45 2.53-.11 2.08-.11C1.59-.11 1.19-.46 1.19-.96C1.19-1.5 1.6-2.33 3.25-2.39Z'/>
</defs>
<g id='page1'>
<use x='-72' y='-67.71' xlink:href='#g0-97'/>
<use x='-63.7' y='-67.71' xlink:href='#g0-97'/>
<use x='-55.4' y='-67.71' xlink:href='#g0-97'/>
<use x='-47.09' y='-67.71' xlink:href='#g0-97'/>
<use x='-38.79' y='-67.71' xlink:href='#g0-97'/>
<use x='-30.49' y='-67.71' xlink:href='#g0-97'/>
<use x='-22.19' y='-67.71' xlink:href='#g0-97'/>
</g>
</svg>
nschloe commented 2 years ago

That's great! Does this apply to "extended DVI" (XDV) as well?

mgieseki commented 2 years ago

Yes, it works with all DVI variants supported by dvisvgm.

nschloe commented 2 years ago

When converting from XDV, I'm getting

WARNING: font file 'lmroman10-regular' not found

again, but I guess this is the same issue as https://github.com/mgieseki/dvisvgm/issues/187#issuecomment-1165742252.

mgieseki commented 2 years ago

Yes, that's the same issue. The latest changes in the Git repo fix it.

nschloe commented 2 years ago

Alright, lets close this then.