dompdf / php-svg-lib

SVG file parsing / rendering library
GNU Lesser General Public License v3.0
1.41k stars 77 forks source link

"transparent" color keyword not correctly parsed #103

Closed bsweeney closed 9 months ago

bsweeney commented 1 year ago

This is the SVG which is converted incorrect.

<svg id="canvas" width="2987" height="2762" version="1.1" xmlns="http://www.w3.org/2000/svg">
            <defs id="defs"><pattern id="smallGrid" width="30" height="30" patternUnits="userSpaceOnUse"><path d="M 30 0 L 0 0 0 30" fill="none" stroke="gray" stroke-width="0.5"></path></pattern><pattern id="grid" width="300" height="300" patternUnits="userSpaceOnUse"><rect width="300" height="300" fill="url(#smallGrid)"></rect><path d="M 300 0 L 0 0 0 300" fill="none" stroke="gray" stroke-width="1"></path></pattern><pattern id="dots" width="30" height="30" x="-10" y="-10" patternUnits="userSpaceOnUse"><circle fill="gray" cx="10" cy="10" r="2"></circle></pattern></defs>
            <rect id="gridContainer" width="100%" height="100%" fill="none"></rect><g id="drawingArea"><line id="slakvcrzth" stroke="#90468b" stroke-width="4" opacity="1" y2="214" x1="277" y1="188" x2="776"></line><line id="slakvcsizf" stroke="#90468b" stroke-width="4" opacity="1" y2="480" x1="875" y1="283" x2="1039"></line><line id="slakvcsw17" stroke="#90468b" stroke-width="4" opacity="1" y2="703" x1="987" y1="551" x2="656"></line><line id="slakvct7wc" stroke="#90468b" stroke-width="4" opacity="1" y2="484" x1="497" y1="647" x2="336"></line><line id="slakvctj9w" stroke="#90468b" stroke-width="4" opacity="1" y2="347" x1="321" y1="457" x2="287"></line><path id="llakvcuvvu" stroke="#90468b" stroke-width="4" opacity="1" d="M 358 349 L 358 349 C 358 349 353.9163858130365 380.27287055249275 360 394 C 367.6614974321865 411.28748138544637 382.0121624415033 425.4708941857718 397 437 C 408.7267879118474 446.0206060860365 423.8879014298708 449.55730230199634 438 454 C 459.9776655883055 460.9188947222443 483.05089111870757 463.99104086143603 505 471 C 522.8075488778773 476.6864441794902 540.869747537985 482.5522807008198 557 492 C 564.7392722245595 496.5330023029563 571.2885671718665 503.8348477781062 575 512 C 581.5573224665243 526.4261094263535 580.7103531005582 543.4551915450407 587 558 C 596.8306202254535 580.733309271361 608.3865808342131 603.0026895626073 623 623 C 633.987271402031 638.0352134975161 647.335599416262 651.9300281961683 663 662 C 680.6000948106698 673.314346664002 700.8641186743674 680.3145746845273 721 686 C 729.6613641133521 688.4455616320053 739.3614899889209 688.5251029263154 748 686 C 761.592948761949 682.026676515738 774.9415203169817 675.8467837464146 786 667 C 795.4746845697615 659.4202523441908 803.5527687150998 649.2891255693621 808 638 C 812.54680850545 626.4581014861654 814.1355338661426 613.2199993451492 812 601 C 808.0078738431542 578.1561669913824 801.1289570239396 555.3451245593897 790 535 C 779.4312430988958 515.678991290169 765.1968516687524 497.75748133500196 748 484 C 727.8498186038412 467.879854883073 704.0039581153947 456.47094946049583 680 447 C 654.653735822485 436.9994331816608 627.6827251154558 431.52056381699083 601 426 C 579.25689010693 421.5014255393648 557.0981162270472 419.16177223960244 535 417 C 526.3745077942061 416.1562018494332 517.3332075462205 414.6190835582227 509 417 C 500.3700584599127 419.4656975828821 491.841031335203 424.18546344226314 486 431 C 477.3608279263782 441.0790340858921 472.37717769318095 453.86294177824874 467 466 C 460.67845735913767 480.2686248179464 456.87810158945155 495.5430474421598 451 510 C 444.5369167559013 525.8956912219726 437.35424079704023 541.49646534678 430 557 C 425.0162046809823 567.5063793211724 418.7861399176821 577.402118753704 414 588 C 409.43940779630105 598.0984541653334 406.261735932973 608.7718337608649 402 619 C 397.92557728664855 628.7786145120435 396.2281377402027 640.2555667069256 389 648 C 381.4669812774584 656.0710914884374 370.93275952177885 662.4625806922498 360 664 C 348.21821222242954 665.6568139062208 335.9426135814714 661.670627748189 325 657 C 308.2278125479118 649.8411395021575 293.4109470822821 638.7497828479744 278 629 C 276.9843416416014 628.3574406304009 275.3333333333333 627 276 626 C 277.8490006540841 623.2264990188738 280.7074567822364 619.48012475509 284 620 C 300.872477010815 622.6640753174971 316.9543642149753 629.1420694753084 333 635 C 358.9907720395888 644.4886945541356 384.834246442804 654.5004172486985 410 666 C 435.2204816107209 677.5245909347003 459.08196092886726 691.8352880125178 484 704 C 501.4277030638454 712.5080125193576 518.6210682944396 721.8092019518112 537 728 C 550.506070835946 732.5494133342135 564.7824003108327 736.9853781962789 579 736 C 599.2437466673734 734.5969680527563 621.5188965724942 732.8385390817294 638 721 C 648.2734147953436 713.6205048653165 650 697.6491106406735 650 685 C 650 668.8307562191535 644.5669518663973 652.7756416993939 638 638 C 623.1002586951738 604.475582064141 605.0554557453105 572.3492981616399 586 541 C 573.9833944722415 521.2307457446553 560.3798100601588 502.2824669748176 545 485 C 527.9140717486702 465.80034866603137 507.63810983638973 449.69679115778416 489 432 C 474.63805398375985 418.36340479266084 459.0576314606871 405.8902814902572 446 391 C 439.8935936026023 384.0365541082307 434.40777794574484 375.94317522705234 432 367 C 429.5735809144865 357.9875862538071 428.8503612389241 347.78583443879063 432 339 C 435.53216654345624 329.14711437878 441.95224098633577 319.26247207937615 451 314 C 475.55954838678326 299.7153647138097 502.63399759278724 289.63702392759427 530 282 C 546.1045602275112 277.505704122555 563.3501499398071 276.4709321373292 580 278 C 596.5069587734429 279.51594519347947 614.0562703241793 282.03617377982954 628 291 C 643.2987628914506 300.83491900164677 655.3437596170465 316.00477320541205 664 332 C 671.1586112360908 345.22786858842863 675.628464853892 361.0477317960832 674 376 C 671.8076863589008 396.12942525009225 662.7913986461834 415.27632903285786 653 433 C 636.2799456297996 463.2654148726413 613.5907712857211 489.8462904837555 595 519 C 584.2407087601765 535.8725248988142 568.3811531567367 551.276606585703 565 571 C 561.939416899746 588.8534014181486 568.7006739745873 607.8993075106995 577 624 C 585.879110322832 641.2254740262941 601.6464984338387 653.9558000769683 615 668 C 621.0290158069463 674.3408614521331 628.3780990154207 679.2810855133179 635 685 C 635.7135395746021 685.61623872352 636.8726140489402 686.0658363588956 637 687 C 637.9018799387585 693.6137862175625 637.0410993555848 700.3942400051397 638 707 C 640.047337870672 721.103883109074 641.1295784908069 735.6063408497192 646 749 C 648.0153506594676 754.5422143135359 658 762 658 762"></path></g>
            <g id="cursors"><circle class="opcursor" id="cursor-me" cx="0" cy="0" r="2" fill="#e65194" style="transform: translate(71px, 267px);"></circle></g>
        <rect id="selectionRect" stroke="black" stroke-width="1" vector-effect="non-scaling-stroke" fill="none" stroke-dasharray="5 5" opacity="1" x="0" height="0" width="0" y="0"></rect><image href="tools/hand/delete.svg" width="24" height="24" style="display: none;"></image><image href="tools/hand/duplicate.svg" width="24" height="24" style="display: none;"></image><image href="tools/hand/handle.svg" width="14" height="14" style="display: none;"></image><style>html, body, svg { padding: 0px; margin: 0px; font-family: "Liberation sans", sans-serif; },#canvas { transform-origin: 0px 0px; },#loadingMessage { font-size: 1.5em; background: linear-gradient(rgb(238, 238, 238), rgb(204, 204, 204)) rgb(238, 238, 238); padding: 20px; width: 40%; line-height: 50px; text-align: center; border-radius: 10px; position: fixed; top: 40%; left: 30%; z-index: 1; box-shadow: rgb(51, 51, 51) 0px 0px 2px; transition: all 1s ease 0s; },#loadingMessage.hidden { display: none; opacity: 0; z-index: -1; },#loadingMessage::after { content: "..."; },#menu::-webkit-scrollbar { display: none; },#menu { font-size: 16px; border-radius: 0px; overflow-y: scroll; position: fixed; margin-bottom: 30px; left: 0px; top: 0px; color: black; max-height: 100%; transition-duration: 1s; cursor: default; padding: 10px; },#menu.closed { border-radius: 3px; left: 10px; top: 10px; background-color: rgba(100, 200, 255, 0.7); width: 6vw; height: 2em; transition-duration: 1s; },#menu h2 { display: none; font-size: 4vh; text-align: center; letter-spacing: 0.5vw; text-shadow: white 0px 0px 5px; color: black; padding: 0px; margin: 0px; },#menu .tools { list-style-type: none; padding: 0px; },#settings { margin-bottom: 20px; },#menu .tool { position: relative; user-select: none; pointer-events: auto; white-space: nowrap; list-style-position: inside; border: 1px solid rgb(238, 238, 238); text-decoration: none; cursor: pointer; background: rgb(255, 255, 255); margin-top: 10px; height: 40px; line-height: 40px; border-radius: 0px; max-width: 40px; transition-duration: 0.2s; overflow: hidden; width: max-content; box-shadow: rgb(143, 162, 188) 0px 0px 3px inset; },#menu .tool:hover { max-width: 100%; },@media (hover: none), (pointer: coarse) {
  #menu .tool:hover { max-width: 40px; }
  #menu .tool:focus { max-width: 100%; }
  #menu { pointer-events: auto; }
  #menu:focus-within { pointer-events: none; }
},#menu .oneTouch:active { border-radius: 3px; background-color: rgb(238, 238, 255); },#menu .tool:active { box-shadow: rgb(221, 238, 255) 0px 0px 1px inset; background-color: rgb(238, 238, 255); },#menu .tool.curTool { box-shadow: rgb(0, 116, 217) 0px 0px 5px; background: linear-gradient(rgb(150, 225, 255), rgb(54, 162, 255)); },#menu .tool-icon { display: inline-block; text-align: center; width: 35px; height: 35px; margin: 2.5px; font-family: mono, monospace; overflow: hidden; },#menu img.tool-icon { pointer-events: none; },#menu .tool-icon > * { display: block; margin: auto; },#menu .tool-name { text-align: center; font-size: 23px; margin-right: 20px; margin-left: 20px; margin-bottom: 2.5px; display: inline-block; vertical-align: text-bottom; },#menu .tool-name.slider { display: inline-block; width: 150px; height: 30px; font-size: 0.9em; line-height: 15px; vertical-align: top; padding: 6px; },#menu .tool.hasSecondary .tool-icon { margin-top: 0px; margin-left: 0px; },#menu .tool .tool-icon.secondaryIcon { display: none; },#menu .tool.hasSecondary .tool-icon.secondaryIcon { display: block; position: absolute; bottom: 0px; left: 26px; width: 12px; height: 12px; },input { font-size: 16px; },#chooseColor { width: 100%; height: 100%; border: 0px; border-radius: 0px; color: black; display: block; margin: 0px; padding: 0px; },.colorPresets { margin-right: 20px; vertical-align: top; display: inline-block; },.colorPresetButton { width: 30px; height: 30px; border: 1px solid black; border-radius: 3px; display: inline-block; margin-right: 6px; padding: 0px; vertical-align: middle; },.rangeChooser { display: block; border: 0px; width: 100%; margin: 0px; background: transparent; },line { fill: none; stroke-linecap: round; stroke-linejoin: round; },path { fill: none; stroke-linecap: round; stroke-linejoin: round; },text { font-family: Arial, Helvetica, sans-serif; user-select: none; },circle.opcursor { pointer-events: none; transition: all 0.1s ease 0s; },#cursor-me { transition: all 0s ease 0s; },@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
  #chooseColor { color: transparent; }
  label.tool-name[for="chooseColor"] { line-height: 10px; }
}
path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
line { fill: none; stroke-linecap: round; stroke-linejoin: round; }
#drawingArea rect { fill: none; }
#canvas ellipse { fill: none; }
#textToolInput { position: fixed; top: -1000px; left: 80px; width: 500px; },#textToolInput:focus { top: 5px; },text { font-family: Arial, Helvetica, sans-serif; user-select: none; }</style>
</svg>

Expected: 103-expected

Actual: 103-actual

Originally posted by @holema in https://github.com/dompdf/dompdf/issues/3069#issuecomment-1319131855

bsweeney commented 1 year ago

Also:

<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="200" height="80">
<path d="M30 62 L30 62 L35.161290322581 62 L40.322580645161 62 L45.483870967742 62 L50.645161290323 62 L55.806451612903 62 L60.967741935484 62 L66.129032258065 62 L71.290322580645 62 L76.451612903226 62 L81.612903225806 62 L86.774193548387 62 L91.935483870968 62 L97.096774193548 62 L102.25806451613 62 L107.41935483871 62 L112.58064516129 62 L117.74193548387 62 L122.90322580645 62 L128.06451612903 62 L133.22580645161 62 L138.38709677419 62 L143.54838709677 62 L148.70967741935 62 L153.87096774194 62 L159.03225806452 62 L164.1935483871 62 L169.35483870968 62 L174.51612903226 62 L179.67741935484 10 L184.83870967742 62" stroke="#FF8126" stroke-width="1" fill="transparent"/>
</svg>
bsweeney commented 1 year ago

The issue appears to be that "transparent" is not a recognized keyword. You can work around the issue temporarily by setting the fill to an explicitly transparent value (e.g. #00000000) or to "none".

bsweeney commented 9 months ago

Note that while the next release will address the issue with the "transparent" keyword, there's a separate issue impacting the original sample. Element ordering is important. Styling should be defined before anything else in the document, and reference elements must come before any element that refers to it. This issue is tracked in #115.