Skip to content

Commit

Permalink
Command-line parameters check, Ruby 3.0 tests, libemf2svg 1.7.1 (#32)
Browse files Browse the repository at this point in the history
* libemf2svg 1.7.1

* Command-line consistency checks

* Ruby 3.0 tests and CI refactoring

* Expose width and height parameters for target image
  • Loading branch information
maxirmx authored Apr 29, 2022
1 parent c79cef5 commit e511329
Show file tree
Hide file tree
Showing 10 changed files with 261 additions and 159 deletions.
143 changes: 60 additions & 83 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-18.04, ubuntu-latest, windows-latest, macos-latest ]
ruby-version: [ '2.7' ]
include:
- os: windows-latest
ruby-version: '3.1'
ruby-version: [ '2.7', '3.0', '3.1' ]

steps:
- uses: actions/checkout@v3

Expand Down Expand Up @@ -47,27 +45,23 @@ jobs:
- os: ubuntu-18.04
platform: any
ruby-version: '2.7'
file: 'skip'
- os: ubuntu-18.04
platform: x86_64-linux
ruby-version: '2.7'
file: 'ELF 64-bit LSB shared object, x86-64'
- os: windows-latest
platform: x64-mingw32
ruby-version: '2.7'
file: 'skip'
- os: windows-latest
platform: x64-mingw-ucrt
ruby-version: '3.1'
file: 'skip'
- os: macos-latest
platform: x86_64-darwin
ruby-version: '2.7'
file: 'Mach-O 64-bit dynamically linked shared library x86_64'
steps:
- uses: actions/checkout@v3

- uses: ruby/setup-ruby@v1
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
Expand All @@ -85,48 +79,50 @@ jobs:
name: pkg
path: pkg/*.gem

- name: Install gem
run: gem install -b pkg/emf2svg-*.gem

- name: Test conversion
run: |
ruby -remf2svg -e "puts File.write('output.svg', Emf2svg.from_file('spec/examples/image1.emf'), mode: 'wb')"
- name: Check file format
if: matrix.file != 'skip'
run: file $(ls pkg/*/lib/emf2svg/libemf2svg.*) | grep "${{ matrix.file }}"

test-build:
needs: build
cross-build:
name: build ${{ matrix.os }}, ${{ matrix.ruby-version }}, ${{ matrix.platform }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: any
ruby-version: '2.7'
- os: windows-latest
platform: any
ruby-version: '2.7'
- os: macos-latest
platform: any
ruby-version: '2.7'
- os: ubuntu-18.04
platform: x86_64-linux
ruby-version: '2.7'
- os: ubuntu-latest
platform: x86_64-linux
ruby-version: '2.7'
- os: windows-latest
platform: x64-mingw32
platform: aarch64-linux
ruby-version: '2.7'
- os: windows-latest
platform: x64-mingw-ucrt
ruby-version: '3.1'
- os: macos-latest
platform: x86_64-darwin
platform: arm64-darwin
ruby-version: '2.7'
steps:
- uses: actions/checkout@v3

- name: Install Ubuntu packages
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu gperf
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true

- name: Build native extension
run: bundle exec rake gem:native:${{ matrix.platform }}

- uses: actions/upload-artifact@v2
with:
name: pkg
path: pkg/*.gem

test-build:
needs: [ build, cross-build ]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-18.04, ubuntu-latest, windows-latest, macos-latest ]
ruby-version: [ '2.7', '3.0', '3.1' ]

steps:
- uses: actions/checkout@v2
Expand All @@ -140,62 +136,43 @@ jobs:
name: pkg
path: pkg

- name: Workaround for vcpkg
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install gperf
- name: Install native gem
if: matrix.platform == 'any'
run: gem install -b pkg/emf2svg-$(ruby -I lib -r emf2svg/version -e "puts Emf2svg::VERSION").gem

- name: Install binary gem
if: matrix.platform != 'any'
run: gem install -b pkg/emf2svg-*-${{ matrix.platform }}.gem

run: gem install -b pkg/emf2svg-$(ruby -I lib -r emf2svg/version -e "puts Emf2svg::VERSION")-$(ruby -e "puts RUBY_PLATFORM.sub(/darwin\d{2}$/, 'darwin')").gem
# MacOS with have something like arm64-darwin19, others just aarch64-linux
- name: Test conversion
run: |
ruby -remf2svg -e "puts File.write('output.svg', Emf2svg.from_file('spec/examples/image1.emf'), mode: 'wb')"
cross:
name: build ${{ matrix.os }}, ${{ matrix.ruby-version }}, ${{ matrix.platform }}
test-build-any:
needs: [ build, cross-build ]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: aarch64-linux
ruby-version: '2.7'
file: 'ELF 64-bit LSB shared object, ARM aarch64'
- os: macos-latest
platform: arm64-darwin
ruby-version: '2.7'
file: 'Mach-O 64-bit dynamically linked shared library arm64'
steps:
- uses: actions/checkout@v3
os: [ ubuntu-18.04, ubuntu-latest, windows-latest, macos-latest ]
ruby-version: [ '2.7', '3.0', '3.1' ]

- name: Install packages
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu gperf
steps:
- uses: actions/checkout@v2

- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true

- run: bundle exec rake gem:native:${{ matrix.platform }}

- uses: actions/upload-artifact@v2
- uses: actions/download-artifact@v2
with:
name: pkg
path: pkg/*.gem
path: pkg

- name: Workaround for vcpkg
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install gperf
- name: Install gem
run: gem install -b pkg/emf2svg-*.gem
- name: Install native gem
run: gem install -b pkg/emf2svg-$(ruby -I lib -r emf2svg/version -e "puts Emf2svg::VERSION").gem

- name: Check file format
run: file $(ls pkg/*/lib/emf2svg/libemf2svg.*) | grep "${{ matrix.file }}"
- name: Test conversion
run: |
ruby -remf2svg -e "puts File.write('output.svg', Emf2svg.from_file('spec/examples/image1.emf'), mode: 'wb')"
12 changes: 10 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ There are two ways to provide EMF data to `emf2svg`.
----
require "emf2svg"
data = Emf2svg.from_file("example.emf")
data = Emf2svg.from_file("example.emf", 800, 600)
File.write("output.svg", data, mode: "wb")
----
800, 600 - optional width and height of the bounding rectangle for svg file
The image will be scaled to fit into this rectangle
These parameters are optional. If skipped or set to 0 SVG image will have the
same size as EMF (in pixels)
====

=== Loading binary data
Expand All @@ -71,9 +75,13 @@ File.write("output.svg", data, mode: "wb")
require "emf2svg"
emf_content = File.read("example.emf", mode: "rb")
svg_data = Emf2svg.from_binary_string(emf_content)
svg_data = Emf2svg.from_binary_string(emf_content, 800, 600)
File.write("output.svg", svg_data, mode: "wb")
----
800, 600 - optional width and height of the bounding rectangle for svg file
The image will be scaled to fit into this rectangle
These parameters are optional. If skipped or set to 0 SVG image will have the
same size as EMF (in pixels)
====


Expand Down
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ task default: %i[spec rubocop]
task :compile do
require_relative "ext/extconf"
end

task spec: :compile

desc "Build install-compilation gem"
Expand Down
36 changes: 33 additions & 3 deletions bin/emf2svg
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/setup"
require "emf2svg"

svg = Emf2svg.from_file(ARGV[0])
File.write(ARGV[1], svg, mode: "wb")
def print_usage
usage = %{Usage: emf2svg <input> <output> [<width>] [<height>]
<input> -- emf file to convert
<output> -- svg file to save
<width> -- svg image width, defaults to source width in px if not set or 0
<height> -- svg image height, defaults to source height in px if not set or 0
Note: width and height specify bounding rectangle, the image will be scaled
propotionally to fit into it.
}
puts usage
end

def tint(pos)
ARGV.size > pos ? Integer(ARGV[pos]) : 0
rescue ArgumentError, TypeError => e
puts "ERROR: Failed to convert #{ARGV[pos]} to integer: #{e.message}"
print_usage
exit 1
end

if ARGV.size < 2 || ARGV.size > 4 || ARGV[0].casecmp("help").zero?
print_usage
exit 0
end

begin
svg = Emf2svg.from_file(ARGV[0], tint(2), tint(3))
File.write(ARGV[1], svg, mode: "wb")
rescue StandardError => e
puts "ERROR: Failed to process #{ARGV[0]}: #{e.message}"
print_usage
exit 1
end
2 changes: 1 addition & 1 deletion emf2svg.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
spec.authors = ["Ribose"]
spec.email = ["[email protected]"]

spec.summary = "Ruby interface to libemf2svg."
spec.summary = "EMF to SVG conversion in Ruby."
spec.homepage = "https://github.com/metanorma/emf2svg-ruby"
spec.license = "BSD-2-Clause"
spec.required_ruby_version = ">= 2.6.0"
Expand Down
35 changes: 33 additions & 2 deletions exe/emf2svg
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,36 @@

require "emf2svg"

svg = Emf2svg.from_file(ARGV[0])
File.write(ARGV[1], svg, mode: "wb")
def print_usage
usage = %{Usage: emf2svg <input> <output> [<width>] [<height>]
<input> -- emf file to convert
<output> -- svg file to save
<width> -- svg image width, defaults to source width in px if not set or 0
<height> -- svg image height, defaults to source height in px if not set or 0
Note: width and height specify bounding rectangle, the image will be scaled
propotionally to fit into it.
}
puts usage
end

def tint(pos)
ARGV.size > pos ? Integer(ARGV[pos]) : 0
rescue ArgumentError, TypeError => e
puts "ERROR: Failed to convert #{ARGV[pos]} to integer: #{e.message}"
print_usage
exit 1
end

if ARGV.size < 2 || ARGV.size > 4 || ARGV[0].casecmp("help").zero?
print_usage
exit 0
end

begin
svg = Emf2svg.from_file(ARGV[0], tint(2), tint(3))
File.write(ARGV[1], svg, mode: "wb")
rescue StandardError => e
puts "ERROR: Failed to process #{ARGV[0]}: #{e.message}"
print_usage
exit 1
end
15 changes: 8 additions & 7 deletions lib/emf2svg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,32 @@ class GeneratorOptions < FFI::Struct
:int

class << self
def from_file(path)
def from_file(path, width = 0, height = 0)
content = File.read(path, mode: "rb")
from_binary_string(content)
from_binary_string(content, width, height)
end

def from_binary_string(content)
def from_binary_string(content, width = 0, height = 0)
svg_out = FFI::MemoryPointer.new(:pointer)
svg_out_len = FFI::MemoryPointer.new(:pointer)
content_ptr = FFI::MemoryPointer.from_string(content)

ret = emf2svg(content_ptr, content.size, svg_out, svg_out_len, options)
opt = options(width, height)
ret = emf2svg(content_ptr, content.size, svg_out, svg_out_len, opt)
raise Error, "emf2svg failed with error code: #{ret}" unless ret == 1

svg_out.read_pointer.read_bytes(svg_out_len.read_int)
end

private

def options
def options(width, height)
GeneratorOptions.new.tap do |opts|
opts[:verbose] = false
opts[:emfplus] = true
opts[:svgDelimiter] = true
opts[:imgHeight] = 0
opts[:imgWidth] = 0
opts[:imgHeight] = height
opts[:imgWidth] = width
end
end
end
Expand Down
Loading

0 comments on commit e511329

Please sign in to comment.