andymeneely / squib

A Ruby DSL for prototyping card games.
http://squib.rocks
MIT License
918 stars 67 forks source link

Cairo::InvalidMatrixError when trying to svg and embedding icons #256

Closed ak47training closed 3 years ago

ak47training commented 6 years ago

Reposting this from BGG thread. Please be gentle, I'm new to this whole GitHub thing. I have a Squib project that was in hiatus for almost a year. I did a clean install of Ruby 2.4 and Squib 0.14.2, and the project no longer works. I am very sad about this, Squib has been good for me so far, I don't want to give up on it, but am out of ideas on what to do =(

I'm on Windows 10. Console feedback looks like this:

D:\Work\Journey\Waltzing Dino>Artifacts.rb
C:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `scale': invalid matrix (not invertible) (Cairo::InvalidMatrixError)
        from C:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `scale'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/image.rb:86:in `block in svg'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/card.rb:51:in `use_cairo'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/image.rb:82:in `svg'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/image.rb:40:in `block (3 levels) in svg'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/args/card_range.rb:13:in `block in each'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/args/card_range.rb:13:in `each'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/args/card_range.rb:13:in `each'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/image.rb:38:in `block (2 levels) in svg'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/progress.rb:32:in `start'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/image.rb:37:in `block in svg'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/image.rb:30:in `chdir'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/image.rb:30:in `svg'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:111:in `block in <main>'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/deck.rb:74:in `instance_eval'
        from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/deck.rb:74:in `initialize'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:33:in `new'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:33:in `<main>'

Line 111 in Artifacts.rb looks like this: svg file: illustration_filename, layout: 'Art', crop_corner_radius: 20

Line 33 in Artifacts.rb looks like this:

Squib::Deck.new cards: artifacts_data['Name'].size, layout: ['skills_layout.yml'] do

andymeneely commented 6 years ago

Interesting - I'll take a look right away.

andymeneely commented 6 years ago

So my SVG tests still work. I'm wondering if it's some weirdness in your SVG file that Cairo recently broke. A few things to try:

Some interesting theories:

ak47training commented 6 years ago

It's run of the mill .svg from game-icons.net. It opens in Chrome and Inkscape.

Had to zip it since Github is being stingy about .svg and .rar (in 2018, really? >_> ) A01.zip

I played with Squib versions a bit. Script works as intended both with squib 0.14 and 0.14.1 !

I realized I might as well show you what happens if I comment the svg line. It starts complaining about the next best thing, my attempts to embed icons in text:

D:\Work\Journey\Waltzing Dino>Artifacts.rb
c:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `scale': invalid matrix (not invertible) (Cairo::InvalidMatrixError)
        from c:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `scale'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/image.rb:86:in `block in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/card.rb:51:in `use_cairo'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/image.rb:82:in `svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/text_embed.rb:43:in `block (2 levels) in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/text_embed.rb:42:in `chdir'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/text_embed.rb:42:in `block in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/text.rb:103:in `block in embed_images!'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/gobject-introspection-3.2.7-x64-mingw32/lib/gobject-introspection/loader.rb:585:in `invoke'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/gobject-introspection-3.2.7-x64-mingw32/lib/gobject-introspection/loader.rb:585:in `block in define_method'
        from c:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `show_pango_layout'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/text.rb:163:in `block in text'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/card.rb:51:in `use_cairo'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/graphics/text.rb:129:in `text'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/text.rb:20:in `block in text'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/args/card_range.rb:13:in `block in each'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/args/card_range.rb:13:in `each'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/args/card_range.rb:13:in `each'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/api/text.rb:20:in `text'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:144:in `block in <main>'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/deck.rb:74:in `instance_eval'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.2/lib/squib/deck.rb:74:in `initialize'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:33:in `new'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:33:in `<main>'

A snippet of code from Artifacts.rb line 144 and down:

  text str: artifacts_data['Text1'], ellipsize: false, layout: 'Text1', font_size:  text1sizes do |embed|
    embed.svg key: '(ATK)', dy: icon_in_text_dy, width: text_icon_width, height: text_icon_height, file: 'icons\attack.svg'
    embed.svg key: '(DEF)', dy: icon_in_text_dy, width: text_icon_width, height: text_icon_height, file: 'icons\defend.svg'
    embed.svg key: '(SUB)', width: text_icon_width, height: text_icon_height, dy: icon_in_text_dy, file: 'icons\sub.svg'
  end
andymeneely commented 6 years ago

Ah... are either text_icon_width or text_icon_height set to zero? Because I get this error from that

andymeneely commented 6 years ago

I (a) bumped the versions up for librsvg and its peers in case they've improved this, and (b) I've added a safeguard so that it doesn't render zero-width or zero-height graphics.

It needs some documentation and automated tests, but I've pushed a pre-release version 0.14.3.pre1 to RubyGems if you want to try it out.

ak47training commented 6 years ago

No, they are not zero.

text_icon_width = 35
text_icon_height = 35

Uninstalled squib, then went ahead and did gem -install squib -v 0.14.3.pre1

Looks like the issue persists, same line, same error:

D:\Work\Journey\Waltzing Dino>artifacts.rb
c:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `scale': invalid matrix (not invertible) (Cairo::InvalidMatrixError)
        from c:/Ruby24-x64/lib/ruby/2.4.0/forwardable.rb:229:in `scale'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/graphics/image.rb:107:in `block in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/card.rb:51:in `use_cairo'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/graphics/image.rb:103:in `svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/api/image.rb:40:in `block (3 levels) in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/args/card_range.rb:13:in `block in each'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/args/card_range.rb:13:in `each'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/args/card_range.rb:13:in `each'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/api/image.rb:38:in `block (2 levels) in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/progress.rb:32:in `start'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/api/image.rb:37:in `block in svg'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/api/image.rb:30:in `chdir'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/api/image.rb:30:in `svg'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:111:in `block in <main>'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/deck.rb:74:in `instance_eval'
        from c:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/squib-0.14.3.pre1/lib/squib/deck.rb:74:in `initialize'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:33:in `new'
        from D:/Work/Journey/Waltzing Dino/Artifacts.rb:33:in `<main>'

I think I did everything correct with installing:

c:\Ruby24-x64\bin>gem list squib

*** LOCAL GEMS ***

squib (0.14.3.pre1)

c:\Ruby24-x64\bin>

I dont mind just giving you the script file, if it helps.

P.S. Oh, and... I'm not sure if you understood me. It works on squib 0.14.1 without any errors. So it can't be anything about missing safeguards. It's something that has to do with difference between 0.14.1 and 0.14.2.

andymeneely commented 5 years ago

Yeah the difference between 0.14.1 and 0.14.2 was upgrading Cairo. It looks like this was some sort of regression in Cairo.

I still can't reproduce this on my end. Can you come up with a minimal example?

ak47training commented 5 years ago

That's the minimal example I slapped together.

K4 cell in datafile Artifact_cards.xlsx has a pattern (STA), which calls for icon embedding in the script and conjures the Cairo invalid matrix (not invertible) error.

If you change (STA) to something like _STA) in .xlsx file it no longer calls for embedding and script resolves successfully.

Minimal example.zip

andymeneely commented 3 years ago

2 years later and I finally figured it out. It is an invalid SVG!! It works in Inkscape and other previews, but librsvg doesn't like having <div> at the root element.

Here's stamina.svg:

<div id="canvas" style="background-color: rgba(0, 0, 0, 0);"><svg
    style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 512 512">
    <path d="M0 0h512v512H0z" fill="#ffffff" fill-opacity="1"></path>
    <g class="" style="touch-action: none;" transform="translate(0,0)">
      <path
        d="M480.25 156.355c0 161.24-224.25 324.43-224.25 324.43S31.75 317.595 31.75 156.355c0-91.41 70.63-125.13 107.77-125.13 77.65 0 116.48 65.72 116.48 65.72s38.83-65.73 116.48-65.73c37.14.01 107.77 33.72 107.77 125.14z"
        fill="#e7de0f" fill-opacity="1"></path>
    </g>
  </svg></div>

If you rip out the surrounding <div> tag it all works great. Had nothing to do with embedding, text rendering, or anything like that. In fact you can reproduce this with just a straight svg file: icons/stamina.svg call.

The error message I now have told me exactly what went wrong, so I'm going to close this now. Better late than never :)