distorted 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/bin/console +14 -0
  4. data/bin/distorted +6 -0
  5. data/bin/setup +8 -0
  6. data/lib/distorted.rb +2 -0
  7. data/lib/distorted/checking_you_out.rb +116 -13
  8. data/lib/distorted/{types → checking_you_out}/README +0 -0
  9. data/lib/distorted/checking_you_out/application.yaml +33 -0
  10. data/lib/distorted/{types → checking_you_out}/font.yaml +0 -0
  11. data/lib/distorted/checking_you_out/image.yaml +108 -0
  12. data/lib/distorted/click_again.rb +333 -0
  13. data/lib/distorted/element_of_media.rb +2 -0
  14. data/lib/distorted/element_of_media/change.rb +119 -0
  15. data/lib/distorted/element_of_media/compound.rb +120 -0
  16. data/lib/distorted/floor.rb +17 -0
  17. data/lib/distorted/invoker.rb +97 -0
  18. data/lib/distorted/media_molecule.rb +58 -0
  19. data/lib/distorted/media_molecule/font.rb +195 -0
  20. data/lib/distorted/media_molecule/image.rb +33 -0
  21. data/lib/distorted/media_molecule/pdf.rb +44 -0
  22. data/lib/distorted/media_molecule/svg.rb +45 -0
  23. data/lib/distorted/media_molecule/text.rb +203 -0
  24. data/lib/distorted/media_molecule/video.rb +18 -0
  25. data/lib/distorted/modular_technology/gstreamer.rb +174 -0
  26. data/lib/distorted/modular_technology/vips.rb +4 -4
  27. data/lib/distorted/modular_technology/vips/foreign.rb +489 -0
  28. data/lib/distorted/modular_technology/vips/load.rb +133 -0
  29. data/lib/distorted/modular_technology/{vips_save.rb → vips/save.rb} +23 -34
  30. data/lib/distorted/monkey_business/encoding.rb +317 -0
  31. data/lib/distorted/monkey_business/hash.rb +0 -15
  32. data/lib/distorted/{modular_technology/triple_counter.rb → triple_counter.rb} +8 -1
  33. data/lib/distorted/version.rb +16 -16
  34. metadata +59 -46
  35. data/lib/distorted/injection_of_love.rb +0 -247
  36. data/lib/distorted/modular_technology/vips_load.rb +0 -77
  37. data/lib/distorted/molecule/C18H27NO3.rb +0 -10
  38. data/lib/distorted/molecule/font.rb +0 -198
  39. data/lib/distorted/molecule/image.rb +0 -36
  40. data/lib/distorted/molecule/pdf.rb +0 -119
  41. data/lib/distorted/molecule/svg.rb +0 -60
  42. data/lib/distorted/molecule/text.rb +0 -225
  43. data/lib/distorted/molecule/video.rb +0 -195
  44. data/lib/distorted/monkey_business/mnemoniq.rb +0 -8
  45. data/lib/distorted/types/application.yaml +0 -8
@@ -1,77 +0,0 @@
1
-
2
- require 'set'
3
-
4
- require 'distorted/checking_you_out'
5
- require 'distorted/modular_technology/vips_save'
6
-
7
-
8
- module Cooltrainer; end
9
- module Cooltrainer::DistorteD; end
10
- module Cooltrainer::DistorteD::Technology; end
11
- module Cooltrainer::DistorteD::Technology::VipsLoad
12
-
13
- # Returns a Set of MIME::Types based on libvips LipsForeignLoad capabilities.
14
- # NOTE: libvips only declares support (via :get_suffixes) for the "saver" types,
15
- # but libvips can use additional external libraries for wider media-types support, e.g.:
16
- #
17
- # - SVG with librsvg2★ / libcairo. [*]
18
- # - PDF with PDFium if available, otherwise with libpoppler-glib / libcairo.
19
- # - OpenEXR/libIlmImf — ILM high dynamic range image format.
20
- # - maybe more: https://github.com/libvips/libvips/blob/master/configure.ac
21
- #
22
- # [FITS]: https://heasarc.gsfc.nasa.gov/docs/heasarc/fits.html
23
- #
24
- # [RSVG2]: This is the normal SVG library for the GNOME/GLib world and is
25
- # probably fine for 95% of use-cases, but I'm pissed off at it because of:
26
- #
27
- # - https://gitlab.gnome.org/GNOME/librsvg/-/issues/56
28
- # - https://gitlab.gnome.org/GNOME/librsvg/-/issues/100
29
- # - https://gitlab.gnome.org/GNOME/librsvg/-/issues/183
30
- # - https://gitlab.gnome.org/GNOME/librsvg/-/issues/494
31
- # - https://bugzilla.gnome.org/show_bug.cgi?id=666477
32
- # - https://phabricator.wikimedia.org/T35245
33
- #
34
- # TLDR: SVG <tspan> elements' [:x, :y, :dy, :dx] attributes can be
35
- # a space-delimited list of position values for individual
36
- # characters in the <tspan>, but librsvg2 only supported reading
37
- # those attributes as a single one-shot numeric value.
38
- # Documents using this totally-common and totally-in-spec feature
39
- # rendered incorrectly with librsvg2. Effected <tspan> elements'
40
- # subsequent children would hug one edge of the rendered output.
41
- #
42
- # And wouldn't you know it but the one (1) SVG on my website
43
- # at the time I built this feature (IIDX-Turntable-parts.svg) used
44
- # this feature for the double-digit parts diagram labels.
45
- # I ended up having to edit my input document to just squash the
46
- # offending <tspan>s down to a single child each.
47
- # I guess that's semantically more correct in my document since they are
48
- # numbers like Eleven and not two separate characters like '1 1'
49
- # but still ugh lol
50
- #
51
- # This was finally fixed in 2019 as of librsvg2 version 2.45.91 :)
52
- # https://gitlab.gnome.org/GNOME/librsvg/-/issues/494#note_579774
53
- #
54
-
55
- # TODO: Figure out how to detect non-Magick non-Saver Loader support,
56
- # by which I mean "everything not included in :get_suffixes".
57
- # NOTE: The Magick-based '.bmp' loader is broken/missing in libvips <= 8.9.1:
58
- # https://github.com/libvips/libvips/issues/1528
59
- # irb> MIME::Types.type_for('.bmp')
60
- # => [#<MIME::Type: image/bmp>, #<MIME::Type: image/x-bmp>, #<MIME::Type: image/x-ms-bmp>]
61
- # irb> MIME::Types.type_for('.bmp').map(&:preferred_extension)
62
- # => ["bmp", "bmp", "bmp"]
63
- LOWER_WORLD = (VIPS_AVAILABLE_VER < TripleCounter.new(8, 9, 1)) ?
64
- Cooltrainer::DistorteD::Technology::VipsSave::OUTER_LIMITS.keep_if { |t| t.preferred_extension != 'bmp'.freeze } :
65
- Cooltrainer::DistorteD::Technology::VipsSave::OUTER_LIMITS
66
-
67
- def to_vips_image
68
- # TODO: Learn more about what VipsAccess means for our use case,
69
- # if the default should be changed, and if it should be
70
- # a user-controllable attr or not.
71
- # https://libvips.github.io/libvips/API/current/VipsImage.html#VipsAccess
72
- # https://libvips.github.io/libvips/API/current/How-it-opens-files.md.html
73
- @vips_image ||= Vips::Image.new_from_file(path)
74
- end
75
-
76
-
77
- end
@@ -1,10 +0,0 @@
1
- require 'distorted/injection_of_love'
2
-
3
- module Cooltrainer; end
4
- module Cooltrainer::DistorteD; end
5
- module Cooltrainer::DistorteD::Molecule; end
6
- module Cooltrainer::DistorteD::Molecule::C18H27NO3
7
-
8
- BOOLEAN_ATTR_VALUES = Set[0, 1, false, true, '0'.freeze, '1'.freeze, 'false'.freeze, 'true'.freeze]
9
-
10
- end
@@ -1,198 +0,0 @@
1
- require 'set'
2
-
3
- # Font metadata extraction
4
- require 'ttfunk'
5
-
6
- require 'distorted/modular_technology/pango'
7
- require 'distorted/modular_technology/ttfunk'
8
- require 'distorted/modular_technology/vips_save'
9
- require 'distorted/checking_you_out'
10
- require 'distorted/injection_of_love'
11
-
12
-
13
- module Cooltrainer
14
- module DistorteD
15
- module Font
16
-
17
-
18
- # TODO: Test OTF, OTB, and others.
19
- # NOTE: Traditional bitmap fonts won't be supported due to Pango 1.44
20
- # and later switching to Harfbuzz from Freetype:
21
- # https://gitlab.gnome.org/GNOME/pango/-/issues/386
22
- # https://blogs.gnome.org/mclasen/2019/05/25/pango-future-directions/
23
- LOWER_WORLD = CHECKING::YOU::IN(/^font\/ttf/)
24
- OUTER_LIMITS = CHECKING::YOU::IN(/^font\/ttf/)
25
-
26
- ATTRIBUTES = Set[
27
- :alt,
28
- ]
29
- ATTRIBUTES_VALUES = {
30
- }
31
- ATTRIBUTES_DEFAULT = {
32
- }
33
-
34
-
35
- # Maybe T0DO: Process output with TTFunk instead of only using it
36
- # to generate images and metadata.
37
- self::OUTER_LIMITS.each { |t|
38
- define_method(t.distorted_method) { |*a, **k, &b|
39
- copy_file(*a, **k, &b)
40
- }
41
- }
42
-
43
- include Cooltrainer::DistorteD::Technology::TTFunk
44
- include Cooltrainer::DistorteD::Technology::Pango
45
- include Cooltrainer::DistorteD::Technology::VipsSave
46
- include Cooltrainer::DistorteD::InjectionOfLove
47
-
48
-
49
- # irb(main):089:0> chars.take(5)
50
- # => [[1, 255], [2, 1], [3, 2], [4, 3], [5, 4]]
51
- # irb(main):090:0> chars.values.take(5)
52
- # => [255, 1, 2, 3, 4]
53
- # irb(main):091:0> chars.values.map(&:chr).take(5)
54
- # => ["\xFF", "\x01", "\x02", "\x03", "\x04"]
55
- def to_pango
56
- output = '' << cr << '<span>' << cr
57
-
58
- output << "<span size='35387'> #{font_name}</span>" << cr << cr
59
-
60
- output << "<span size='24576'> #{font_description}</span>" << cr
61
- output << "<span size='24576'> #{font_copyright}</span>" << cr
62
- output << "<span size='24576'> #{font_version}</span>" << cr << cr
63
-
64
- # Print a preview String in using the loaded font. Or don't.
65
- if abstract(:title)
66
- output << cr << cr << "<span size='24576' foreground='grey'> #{g_markup_escape_text(abstract(:title))}</span>" << cr << cr << cr
67
- end
68
-
69
- # /!\ MANDATORY READING /!\
70
- # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
71
- #
72
- # "The 'cmap' table maps character codes to glyph indices.
73
- # The choice of encoding for a particular font is dependent upon the conventions
74
- # used by the intended platform. A font intended to run on multiple platforms
75
- # with different encoding conventions will require multiple encoding tables.
76
- # As a result, the 'cmap' table may contain multiple subtables,
77
- # one for each supported encoding scheme."
78
- #
79
- # Cmap#unicode is a convenient shortcut to sorting the subtables
80
- # and removing any unusable ones:
81
- # https://github.com/prawnpdf/ttfunk/blob/master/lib/ttfunk/table/cmap.rb
82
- #
83
- # irb(main):174:0> font_meta.cmap.tables.count
84
- # => 3
85
- # irb(main):175:0> font_meta.cmap.unicode.count
86
- # => 2
87
- to_ttfunk.cmap.tables.each do |table|
88
- next if !table.unicode?
89
- # Each subtable's `code_map` is a Hash map of character codes (the Hash keys)
90
- # to the glyph IDs from the original font (the Hash's values).
91
- #
92
- # Subtable::encode takes:
93
- # - a Hash mapping character codes to original font glyph IDs.
94
- # - the desired output encoding — Set[:mac_roman, :unicode, :unicode_ucs4]
95
- # https://github.com/prawnpdf/ttfunk/blob/master/lib/ttfunk/table/cmap/subtable.rb
96
- # …and returns a Hash with keys:
97
- # - :charmap — Hash mapping the characters in the input charmap
98
- # to a another hash containing both the `:old`
99
- # and `:new` glyph ids for each character code.
100
- # - :subtable — String encoded subtable for the given encoding.
101
- encoded = TTFunk::Table::Cmap::Subtable::encode(table&.code_map, :unicode).dig(:charmap)
102
-
103
- output << "<span size='49152'>"
104
-
105
- i = 0
106
- encoded.each_pair { |c, (old, new)|
107
-
108
- begin
109
- if glyph = to_ttfunk.glyph_outlines.for(c)
110
- # Add a space on either side of the character so they aren't
111
- # all smooshed up against each other and unreadable.
112
- output << ' ' << g_markup_escape_char(c) << ' '
113
- if i >= 15
114
- output << cr
115
- i = 0
116
- else
117
- i = i + 1
118
- end
119
- else
120
- end
121
- rescue NoMethodError => nme
122
- # TTFunk's `glyph_outlines.for()` will raise this if we call it
123
- # for a codepoint that does not exist in the font, which we will
124
- # not do because we are enumerating the codepoints in the font,
125
- # but we should still handle the possibility.
126
- # irb(main):060:0> font.glyph_outlines.for(555555)
127
- #
128
- # Traceback (most recent call last):
129
- # 6: from /usr/bin/irb:23:in `<main>'
130
- # 5: from /usr/bin/irb:23:in `load'
131
- # 4: from /home/okeeblow/.gems/gems/irb-1.2.4/exe/irb:11:in `<top (required)>'
132
- # 3: from (irb):60
133
- # 2: from /home/okeeblow/.gems/gems/ttfunk-1.6.2.1/lib/ttfunk/table/glyf.rb:35:in `for'
134
- # 1: from /home/okeeblow/.gems/gems/ttfunk-1.6.2.1/lib/ttfunk/table/loca.rb:35:in `size_of'
135
- # NoMethodError (undefined method `-' for nil:NilClass)
136
- end
137
- }
138
-
139
- output << '</span>' << cr
140
- end
141
-
142
- output << '</span>'
143
- output
144
- end
145
-
146
- # Return the `src` as the font_path since we aren't using
147
- # any of the built-in fonts.
148
- def font_path
149
- path
150
- end
151
-
152
- def to_vips_image
153
- # https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text
154
- Vips::Image.text(
155
- # This string must be well-escaped Pango Markup:
156
- # https://developer.gnome.org/pango/stable/pango-Markup.html
157
- # However the official function for escaping text is
158
- # not implemented in Ruby GLib, so we have to do it ourselves.
159
- to_pango,
160
- **{
161
- # String absolute path to TTF
162
- :fontfile => font_path,
163
- # It's not enough to just specify the TTF path;
164
- # we must also specify a font family, subfamily, and size.
165
- :font => "#{font_name}",
166
- # Space between lines (in Points).
167
- :spacing => to_ttfunk.line_gap,
168
- # Requires libvips 8.8
169
- :justify => false,
170
- :dpi => 144,
171
- },
172
- )
173
- end
174
-
175
- end # Font
176
- end # DistorteD
177
- end # Cooltrainer
178
-
179
-
180
- # Notes on file-format specifics and software-library-specifics
181
- #
182
- # # TTF (via TTFunk)
183
- #
184
- # ## Cmap
185
- #
186
- # Each TTFunk::Table::Cmap::Format<whatever> class responds to `:supported?`
187
- # with its own internal boolean telling us if that Format is usable in TTFunk.
188
- # This has nothing to do with any font file itself, just the library code.
189
- # irb(main)> font.cmap.tables.map{|t| t.supported?}
190
- # => [true, true, true]
191
- #
192
- # Any subclass of TTFunk::Table::Cmap::Subtable responds to `:unicode?`
193
- # with a boolean calculated from the instance `@platform_id` and `@encoding_id`,
194
- # and those numeric IDs are assigned to the symbolic (e.g. `:macroman`) names in:
195
- # https://github.com/prawnpdf/ttfunk/blob/master/lib/ttfunk/table/cmap/subtable.rb
196
- # irb(main)> font.cmap.tables.map{|t| t.unicode?}
197
- # => [true, false, true]
198
- #
@@ -1,36 +0,0 @@
1
-
2
- require 'set'
3
-
4
- require 'distorted/checking_you_out'
5
- require 'distorted/modular_technology/vips'
6
- require 'distorted/injection_of_love'
7
-
8
-
9
- module Cooltrainer
10
- module DistorteD
11
- module Image
12
-
13
-
14
- # Attributes for our <picture>/<img>.
15
- # Automatically enabled as attrs for DD Liquid Tag.
16
- # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture#Attributes
17
- # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes
18
- # https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading
19
- ATTRIBUTES = Set[:alt, :caption, :href, :loading]
20
-
21
- # Defaults for HTML Element attributes.
22
- # Not every attr has to be listed here.
23
- # Many need no default and just won't render.
24
- ATTRIBUTES_DEFAULT = {
25
- :loading => :eager,
26
- }
27
- ATTRIBUTES_VALUES = {
28
- :loading => Set[:eager, :lazy],
29
- }
30
-
31
- include Cooltrainer::DistorteD::Technology::Vips
32
- include Cooltrainer::DistorteD::InjectionOfLove
33
-
34
- end # Image
35
- end # DistorteD
36
- end # Cooltrainer
@@ -1,119 +0,0 @@
1
- require 'set'
2
-
3
- require 'hexapdf'
4
-
5
- require 'distorted/checking_you_out'
6
- require 'distorted/injection_of_love'
7
- require 'distorted/molecule/C18H27NO3'
8
-
9
-
10
- module Cooltrainer
11
- module DistorteD
12
- module PDF
13
-
14
-
15
- include Cooltrainer::DistorteD::Molecule::C18H27NO3
16
-
17
- LOWER_WORLD = CHECKING::YOU::IN("application/pdf")
18
-
19
- # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#Attributes
20
- # https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf
21
- PDF_OPEN_PARAMS = Array[
22
- # Keep the PDF Open Params in the order they are defined
23
- # in the Adobe documentation, since it says they should
24
- # be specified in the URL in that same order.
25
- # Ruby's Set doesn't guarantee order, so use a plain Array here.
26
- :nameddest,
27
- :page,
28
- :comment,
29
- :collab,
30
- :zoom,
31
- :view,
32
- :viewrect,
33
- :pagemode,
34
- :scrollbar,
35
- :search,
36
- :toolbar,
37
- :statusbar,
38
- :messages,
39
- :navpanes,
40
- :highlight,
41
- :fdf,
42
- ]
43
- ATTRIBUTES = Set[
44
- :alt,
45
- :caption,
46
- :height, #<object> viewer container height.
47
- :width, # <object> viewer container width.
48
- ].merge(PDF_OPEN_PARAMS)
49
-
50
- # "You cannot use the reserved characters =, #, and &.
51
- # There is no way to escape these special characters."
52
- RESERVED_CHARACTERS_FRAGMENT = '[^=#&]+'.freeze
53
-
54
- FLOAT_INT_FRAGMENT = '[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)'.freeze
55
- ZERO_TO_ONE_HUNDRED = /^(([1-9]\d?|1\d{1})([.,]\d{0,1})?|100([.,]0{1})?)$/
56
-
57
- ATTRIBUTES_DEFAULT = {
58
- :height => '100%'.freeze,
59
- :width => '100%'.freeze,
60
- # BEGIN PDF Open Parameters
61
- :page => 1,
62
- :view => :Fit,
63
- :pagemode => :none,
64
- :scrollbar => 1,
65
- :toolbar => 1,
66
- :statusbar => 1,
67
- :messages => 0,
68
- :navpanes => 1,
69
- # END PDF Open Parameters
70
- }
71
-
72
- # Adobe's PDF Open Parameters documentation sez:
73
- # "Individual parameters, together with their values (separated by & or #),
74
- # can be no greater then 32 characters in length."
75
- # …but then goes on to show some examples (like `comment`)
76
- # that are clearly longer than 32 characters.
77
- # Dunno. I'll err on the side of giving you a footgun.
78
- ATTRIBUTES_VALUES = {
79
- :nameddest => /^#{RESERVED_CHARACTERS_FRAGMENT}$/,
80
- :page => /\d/,
81
- :comment => /^#{RESERVED_CHARACTERS_FRAGMENT}$/,
82
- :collab => /^(DAVFDF|FSFDF|DB)@#{RESERVED_CHARACTERS_FRAGMENT}$/,
83
- :zoom => /^#{FLOAT_INT_FRAGMENT}(,#{FLOAT_INT_FRAGMENT},#{FLOAT_INT_FRAGMENT})?$/,
84
- :view => /^Fit(H|V|B|BH|BV(,#{FLOAT_INT_FRAGMENT})?)?$/,
85
- :viewrect => /^#{FLOAT_INT_FRAGMENT},#{FLOAT_INT_FRAGMENT},#{FLOAT_INT_FRAGMENT},#{FLOAT_INT_FRAGMENT}$/,
86
- :pagemode => Set[:none, :thumbs, :bookmarks],
87
- :scrollbar => BOOLEAN_ATTR_VALUES,
88
- :search => /^#{RESERVED_CHARACTERS_FRAGMENT}(,\s#{RESERVED_CHARACTERS_FRAGMENT})*$/,
89
- :toolbar => BOOLEAN_ATTR_VALUES,
90
- :statusbar => BOOLEAN_ATTR_VALUES,
91
- :messages => BOOLEAN_ATTR_VALUES,
92
- :navpanes => BOOLEAN_ATTR_VALUES,
93
- :fdf => /^#{RESERVED_CHARACTERS_FRAGMENT}$/,
94
- }
95
-
96
- include Cooltrainer::DistorteD::InjectionOfLove
97
-
98
- # TODO: Use MuPDF instead of libvips magick-based PDF loader.
99
-
100
- def self.optimize(src, dest)
101
- HexaPDF::Document.open(src) do |doc|
102
- doc.task(
103
- :optimize,
104
- compact: true,
105
- object_streams: :generate,
106
- xref_streams: :generate,
107
- compress_pages: false,
108
- )
109
- doc.write(dest)
110
- end
111
- end
112
-
113
- def to_application_pdf(*a, **k, &b)
114
- copy_file(*a, **k, &b)
115
- end
116
-
117
- end # PDF
118
- end # DistorteD
119
- end # Cooltrainer
@@ -1,60 +0,0 @@
1
- require 'set'
2
-
3
- require 'svg_optimizer'
4
-
5
- require 'distorted/checking_you_out'
6
- require 'distorted/injection_of_love'
7
- require 'distorted/molecule/C18H27NO3'
8
-
9
-
10
- module Cooltrainer
11
- module DistorteD
12
- module SVG
13
-
14
- SUB_TYPE = 'svg'.freeze
15
- include Cooltrainer::DistorteD::Molecule::C18H27NO3
16
-
17
- #WISHLIST: Support VML for old IE compatibility.
18
- # Example: RaphaëlJS — https://en.wikipedia.org/wiki/Rapha%C3%ABl_(JavaScript_library)
19
- LOWER_WORLD = CHECKING::YOU::IN(/^image\/svg/)
20
-
21
- ATTRIBUTES = Set[
22
- :alt,
23
- :caption,
24
- :href,
25
- :loading,
26
- :optimize,
27
- ]
28
- ATTRIBUTES_VALUES = {
29
- :optimize => BOOLEAN_ATTR_VALUES,
30
- }
31
- ATTRIBUTES_DEFAULT = {
32
- :optimize => false,
33
- }
34
-
35
- include Cooltrainer::DistorteD::Technology::VipsSave
36
- include Cooltrainer::DistorteD::InjectionOfLove
37
-
38
- def to_vips_image
39
- # TODO: Load-time options for various formats, like SVG's `unlimited`:
40
- # "SVGs larger than 10MB are normally blocked for security. Set unlimited to allow SVGs of any size."
41
- # https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-svgload
42
- @vips_image ||= Vips::Image.new_from_file(path)
43
- end
44
-
45
- def to_image_svg_xml(dest, *a, **k, &b)
46
- if abstract(:optimize)
47
- SvgOptimizer.optimize_file(path, dest, SvgOptimizer::DEFAULT_PLUGINS)
48
- else
49
- copy_file(dest, *a, **k, &b)
50
- end
51
- end
52
-
53
- def self.optimize(src, dest)
54
- # TODO: Make optimizations/plugins configurable
55
- SvgOptimizer.optimize_file(src, dest, SvgOptimizer::DEFAULT_PLUGINS)
56
- end
57
-
58
- end
59
- end
60
- end