himg 0.0.8 → 0.0.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 625354e25f75ba2a83205c62b3cf2cc6fbe883d48c701a09703e863cc647cea3
4
- data.tar.gz: 775eac3d3644b056adadea5c2075698c8c9bdce680cdca4478edf7add902c51b
3
+ metadata.gz: d65ada02141e4fdd397d4c58def4e7fd658202563a2bbc31b548801b08198d4b
4
+ data.tar.gz: b7c9cc37243b8f790dfb977a6d6e5c215104e4a6a0f03cbc63308191d7ba7e73
5
5
  SHA512:
6
- metadata.gz: 8e5d7496bc2008a8864b0b53412fbe1455e4761124cf5870d5ee271ac4e0c241828129a29dfbce83c2c1747d5c4e5914017da644c64cf4dff0cc9a6f90817e76
7
- data.tar.gz: dbb75e11cf3b155287b5af1b2cefb5f305c56ba1001c212df6beaa862d48f09888ee6a48b40c111aaddfd3fdaf3645651d764a9d33a33e45c8cbfb8bf0c09ace
6
+ metadata.gz: d21cb8a714e462c08b36a000275eb9b4c840ab2bb049f8c7bcacb5b978a4404f36d0431b867b019fee864130b1895ef026b81257d6ce0199dec0adef8ecf5578
7
+ data.tar.gz: a96a262c6dc6e4a42bb8b6bcdacb47f24203d3e5d74673880b6851f76a01421e373c2a3e074f2cbb697e58c69b1e9eb1a3284824853821601c3e694c5bd127a3
data/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
3
 
4
+ ## [0.0.10] - 2025-08-01
5
+
6
+ - Fixed himg require from native extension
7
+ - Catch rust panics and wrap with ruby Error
8
+ - GpuNotFound error extending Himg::Error
9
+
10
+ ## [0.0.9] - 2025-07-31
11
+
12
+ - Returned to CPU-only rendering by default
13
+ - Added `gpu` option to enable GPU rendering
14
+ - Updated to latest blitz to fix blue/green colour swap on images
15
+
4
16
  ## [0.0.8] - 2025-07-31
5
17
 
6
18
  - Return to GPU rendering by default: quality is low with CPU rendering.
data/Cargo.lock CHANGED
@@ -89,6 +89,18 @@ dependencies = [
89
89
  "wgpu",
90
90
  ]
91
91
 
92
+ [[package]]
93
+ name = "anyrender_vello_cpu"
94
+ version = "0.5.1"
95
+ source = "registry+https://github.com/rust-lang/crates.io-index"
96
+ checksum = "e83dfa407bbe89c99cf990a933aeab4e1d499c38a465c3f316066a1dd3eb5614"
97
+ dependencies = [
98
+ "anyrender",
99
+ "kurbo",
100
+ "peniko",
101
+ "vello_cpu",
102
+ ]
103
+
92
104
  [[package]]
93
105
  name = "app_units"
94
106
  version = "0.7.8"
@@ -211,9 +223,9 @@ dependencies = [
211
223
 
212
224
  [[package]]
213
225
  name = "blitz-dom"
214
- version = "0.1.0-rc.1"
226
+ version = "0.1.0-rc.2"
215
227
  source = "registry+https://github.com/rust-lang/crates.io-index"
216
- checksum = "5b715adfa6d85cad5da636aac5785d40e26dcf3f4195403fe8c46be501b77d72"
228
+ checksum = "145a503f45b2284a75ca1e715dbbef4d1ccf1eeace85330e29a2ae12a01d1263"
217
229
  dependencies = [
218
230
  "accesskit",
219
231
  "app_units",
@@ -223,6 +235,7 @@ dependencies = [
223
235
  "color",
224
236
  "cursor-icon",
225
237
  "euclid",
238
+ "fastrand",
226
239
  "html-escape",
227
240
  "image",
228
241
  "keyboard-types",
@@ -248,9 +261,9 @@ dependencies = [
248
261
 
249
262
  [[package]]
250
263
  name = "blitz-html"
251
- version = "0.1.0-rc.1"
264
+ version = "0.1.0-rc.2"
252
265
  source = "registry+https://github.com/rust-lang/crates.io-index"
253
- checksum = "82a31ccea6ee542133f13ef11344c0a8fdcdc99285f30046e97b5b4478720705"
266
+ checksum = "52d34dae2ab4e90c0ccfa6470be7e455f897ae702c85d248fccdc807e375426d"
254
267
  dependencies = [
255
268
  "blitz-dom",
256
269
  "blitz-traits",
@@ -260,9 +273,9 @@ dependencies = [
260
273
 
261
274
  [[package]]
262
275
  name = "blitz-net"
263
- version = "0.1.0-rc.1"
276
+ version = "0.1.0-rc.2"
264
277
  source = "registry+https://github.com/rust-lang/crates.io-index"
265
- checksum = "a4b0b681ed5c32d0c3dafc2288cf10b9aa46e08de1a58350e5842d4d761c33ae"
278
+ checksum = "e2a5ebc8993e3985097716262d4d496c18d3324727109e3c865071776dfe38b1"
266
279
  dependencies = [
267
280
  "blitz-traits",
268
281
  "data-url",
@@ -272,9 +285,9 @@ dependencies = [
272
285
 
273
286
  [[package]]
274
287
  name = "blitz-paint"
275
- version = "0.1.0-rc.1"
288
+ version = "0.1.0-rc.2"
276
289
  source = "registry+https://github.com/rust-lang/crates.io-index"
277
- checksum = "b6b26d3c0645d2b502ec7b3984354b3c42a2af7e4bde92ed5d189ac160e4e1f5"
290
+ checksum = "9d62c7953382622298402412535db1796aaa83c71600bfc77fa7627a39aa722d"
278
291
  dependencies = [
279
292
  "anyrender",
280
293
  "anyrender_svg",
@@ -293,15 +306,16 @@ dependencies = [
293
306
 
294
307
  [[package]]
295
308
  name = "blitz-traits"
296
- version = "0.1.0-rc.1"
309
+ version = "0.1.0-rc.2"
297
310
  source = "registry+https://github.com/rust-lang/crates.io-index"
298
- checksum = "f559ae4a8b1c7dafc09df5e1249f8a27c6b9a20658a15041128d202334e8e2c2"
311
+ checksum = "4cb0235930120526087ce9d69fa2d6828e3fb078c61dde43231acec7968376bf"
299
312
  dependencies = [
300
313
  "bitflags 2.9.1",
301
314
  "bytes",
302
315
  "cursor-icon",
303
316
  "http",
304
317
  "keyboard-types",
318
+ "serde",
305
319
  "smol_str",
306
320
  "url",
307
321
  ]
@@ -412,6 +426,9 @@ name = "color"
412
426
  version = "0.3.1"
413
427
  source = "registry+https://github.com/rust-lang/crates.io-index"
414
428
  checksum = "7ae467d04a8a8aea5d9a49018a6ade2e4221d92968e8ce55a48c0b1164e5f698"
429
+ dependencies = [
430
+ "bytemuck",
431
+ ]
415
432
 
416
433
  [[package]]
417
434
  name = "color_quant"
@@ -1077,10 +1094,11 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
1077
1094
 
1078
1095
  [[package]]
1079
1096
  name = "himg"
1080
- version = "0.0.8"
1097
+ version = "0.0.10"
1081
1098
  dependencies = [
1082
1099
  "anyrender",
1083
1100
  "anyrender_vello",
1101
+ "anyrender_vello_cpu",
1084
1102
  "blitz-dom",
1085
1103
  "blitz-html",
1086
1104
  "blitz-net",
@@ -2065,6 +2083,7 @@ version = "0.4.0"
2065
2083
  source = "registry+https://github.com/rust-lang/crates.io-index"
2066
2084
  checksum = "1f9529efd019889b2a205193c14ffb6e2839b54ed9d2720674f10f4b04d87ac9"
2067
2085
  dependencies = [
2086
+ "bytemuck",
2068
2087
  "color",
2069
2088
  "kurbo",
2070
2089
  "smallvec",
@@ -2951,9 +2970,9 @@ checksum = "500f379645e8a87fd03fe88607a5edcb0d8e4e423baa74ba52db198a06a0c261"
2951
2970
 
2952
2971
  [[package]]
2953
2972
  name = "stylo_taffy"
2954
- version = "0.1.0-rc.1"
2973
+ version = "0.1.0-rc.2"
2955
2974
  source = "registry+https://github.com/rust-lang/crates.io-index"
2956
- checksum = "94014fa36fdc4698a0b36179385d70810b6f0825b90c1df52de2aa5ee670328a"
2975
+ checksum = "dce8876a33e0f3b16916b2b4da1cdbb64b9985d5ae61033d23024d95e45569ac"
2957
2976
  dependencies = [
2958
2977
  "stylo",
2959
2978
  "taffy",
@@ -3539,6 +3558,28 @@ dependencies = [
3539
3558
  "wgpu",
3540
3559
  ]
3541
3560
 
3561
+ [[package]]
3562
+ name = "vello_common"
3563
+ version = "0.0.1"
3564
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3565
+ checksum = "6b5e49f2836e87b6bd3d8f70324696f22b5f7dfdc836caeab463fff05957c1b1"
3566
+ dependencies = [
3567
+ "bytemuck",
3568
+ "peniko",
3569
+ "png",
3570
+ "skrifa",
3571
+ "smallvec",
3572
+ ]
3573
+
3574
+ [[package]]
3575
+ name = "vello_cpu"
3576
+ version = "0.0.1"
3577
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3578
+ checksum = "a45e0a6b777abb4354e15146ecf95bac03aada7a85024fd47762f56095b32896"
3579
+ dependencies = [
3580
+ "vello_common",
3581
+ ]
3582
+
3542
3583
  [[package]]
3543
3584
  name = "vello_encoding"
3544
3585
  version = "0.5.0"
data/Cargo.toml CHANGED
@@ -5,3 +5,7 @@
5
5
  [workspace]
6
6
  members = ["./ext/himg"]
7
7
  resolver = "2"
8
+
9
+ [profile.profiling]
10
+ inherits = "release"
11
+ debug = true
data/README.md CHANGED
@@ -67,6 +67,7 @@ bundle add himg
67
67
  |base_url | Where relative paths are relative to for linked resources (stylesheets, images, fonts, etc) | string | nil |
68
68
  |disable_fetch | Disables fetching linked resources from disk and network| bool | false |
69
69
  |fetch_timeout | Timeout in seconds for fetching resources | float | 10.0 |
70
+ |gpu | Use GPU renderer instead of CPU renderer | bool | false |
70
71
 
71
72
 
72
73
  ### Passing options to a Rails view template
@@ -217,6 +218,7 @@ To play nicely with Rails a template handler is registered, which Rails' `defaul
217
218
  - http://localhost:3000/users/jamedjo.himg will also render the same png
218
219
  - http://localhost:3000/users/jamedjo will render an HTML page with opengraph meta tags
219
220
  6. To install this gem onto your local machine, run `bundle exec rake install`.
221
+ 7. To simulate a headless server environment without a GPU, use `WGPU_BACKEND=empty bundle exec rspec`
220
222
 
221
223
  ### Run cargo example directly generate image in Rust
222
224
 
data/ext/himg/Cargo.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "himg"
3
3
  description = "ruby bindings to expose a blitz html->png pipeline"
4
- version = "0.0.8"
4
+ version = "0.0.10"
5
5
  edition = "2024"
6
6
  authors = ["James Edwards-Jones <git@jamedjo.co.uk>"]
7
7
  license = "MIT"
@@ -14,13 +14,14 @@ crate-type = ["cdylib", "rlib"]
14
14
  [dependencies]
15
15
  magnus = { version = "0.7.1" }
16
16
  rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
17
- blitz-traits = { version = "0.1.0-rc.1" }
18
- blitz-dom = { version = "0.1.0-rc.1" }
19
- blitz-net = { version = "0.1.0-rc.1" }
20
- blitz-paint = { version = "0.1.0-rc.1" }
17
+ blitz-traits = { version = "0.1.0-rc.2" }
18
+ blitz-dom = { version = "0.1.0-rc.2" }
19
+ blitz-net = { version = "0.1.0-rc.2" }
20
+ blitz-paint = { version = "0.1.0-rc.2" }
21
21
  anyrender = { version = "0.5.0" }
22
22
  anyrender_vello = { version = "0.5.0" }
23
- blitz-html = { version = "0.1.0-rc.1" }
23
+ anyrender_vello_cpu = { version = "0.5.1" }
24
+ blitz-html = { version = "0.1.0-rc.2" }
24
25
  tokio = { version = "1.46", features = ["rt-multi-thread", "macros"] }
25
26
  png = "0.17"
26
27
  openssl = { version = "0.10", features = ["vendored"] }
@@ -35,6 +35,7 @@ async fn main() {
35
35
  color_scheme: ColorScheme::Light,
36
36
  disable_fetch: false,
37
37
  fetch_timeout: 10.0,
38
+ gpu: false,
38
39
  base_url: Some(base_url),
39
40
  };
40
41
 
@@ -1,6 +1,7 @@
1
1
  use blitz_html::HtmlDocument;
2
2
  use blitz_dom::DocumentConfig;
3
3
  use anyrender_vello::VelloImageRenderer;
4
+ use anyrender_vello_cpu::VelloCpuImageRenderer;
4
5
  use anyrender::render_to_buffer;
5
6
  use blitz_paint::paint_scene;
6
7
  use blitz_traits::shell::{Viewport};
@@ -79,17 +80,31 @@ pub async fn html_to_image(
79
80
  }
80
81
 
81
82
  // Render document to RGBA buffer
82
- let buffer = render_to_buffer::<VelloImageRenderer, _>(
83
- |scene| paint_scene(
84
- scene,
85
- document.as_ref(),
86
- render_size.hidpi_scale,
83
+ let buffer = if options.gpu {
84
+ render_to_buffer::<VelloImageRenderer, _>(
85
+ |scene| paint_scene(
86
+ scene,
87
+ document.as_ref(),
88
+ render_size.hidpi_scale,
89
+ render_size.scaled_width(),
90
+ render_size.scaled_height(),
91
+ ),
87
92
  render_size.scaled_width(),
88
93
  render_size.scaled_height(),
89
- ),
90
- render_size.scaled_width(),
91
- render_size.scaled_height(),
92
- );
94
+ )
95
+ } else {
96
+ render_to_buffer::<VelloCpuImageRenderer, _>(
97
+ |scene| paint_scene(
98
+ scene,
99
+ document.as_ref(),
100
+ render_size.hidpi_scale,
101
+ render_size.scaled_width(),
102
+ render_size.scaled_height(),
103
+ ),
104
+ render_size.scaled_width(),
105
+ render_size.scaled_height(),
106
+ )
107
+ };
93
108
 
94
109
  logger.log("Rendered to buffer");
95
110
 
data/ext/himg/src/lib.rs CHANGED
@@ -34,6 +34,7 @@ impl Options {
34
34
  base_url: hash.lookup("base_url")?,
35
35
  disable_fetch: hash.lookup2("disable_fetch", defaults.disable_fetch)?,
36
36
  fetch_timeout: hash.lookup2("fetch_timeout", defaults.fetch_timeout)?,
37
+ gpu: hash.lookup2("gpu", defaults.gpu)?,
37
38
  color_scheme: defaults.color_scheme,
38
39
  };
39
40
 
@@ -44,10 +45,30 @@ impl Options {
44
45
  pub fn render_blocking_rb(ruby: &Ruby, html: String, options: Option<RHash>) -> Result<RString, Error> {
45
46
  let options = Options::from_ruby(options)?;
46
47
  let exception_class = ExceptionClass::from_value(magnus::eval("Himg::Error").unwrap()).unwrap();
48
+ let gpu_not_found_class = ExceptionClass::from_value(magnus::eval("Himg::GpuNotFound").unwrap()).unwrap();
47
49
 
48
- match render_blocking(html, options) {
49
- Ok(data) => Ok(ruby.str_from_slice(&data)),
50
- Err(e) => Err(Error::new(exception_class, format!("{}", e))),
50
+ let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
51
+ render_blocking(html, options)
52
+ }));
53
+
54
+ match result {
55
+ Ok(Ok(data)) => Ok(ruby.str_from_slice(&data)),
56
+ Ok(Err(e)) => Err(Error::new(exception_class, format!("{}", e))),
57
+ Err(panic) => {
58
+ let msg = if let Some(s) = panic.downcast_ref::<String>() {
59
+ s.clone()
60
+ } else if let Some(s) = panic.downcast_ref::<&str>() {
61
+ s.to_string()
62
+ } else {
63
+ "Unknown panic".to_string()
64
+ };
65
+
66
+ if msg.contains("No compatible device found") {
67
+ Err(Error::new(gpu_not_found_class, msg))
68
+ } else {
69
+ Err(Error::new(exception_class, format!("Panic: {}", msg)))
70
+ }
71
+ }
51
72
  }
52
73
  }
53
74
 
@@ -8,6 +8,7 @@ pub struct Options {
8
8
  pub color_scheme: ColorScheme,
9
9
  pub disable_fetch: bool,
10
10
  pub fetch_timeout: f64,
11
+ pub gpu: bool,
11
12
  pub base_url: Option<String>,
12
13
  pub truncate: bool,
13
14
  pub verbose: bool,
@@ -26,6 +27,7 @@ impl Options {
26
27
  base_url: None,
27
28
  disable_fetch: false,
28
29
  fetch_timeout: 10.0,
30
+ gpu: false,
29
31
  color_scheme: ColorScheme::Light,
30
32
  }
31
33
  }
data/lib/himg/cli.rb CHANGED
@@ -12,6 +12,7 @@ module Himg
12
12
  option :verbose, type: :boolean, desc: "Enables detailed logging for debugging and profiling.", default: false
13
13
  option :disable_fetch, type: :boolean, desc: "Skip fetching file/http resources (stylesheets, images, fonts, etc)", default: false
14
14
  option :fetch_timeout, type: :numeric, desc: "Timeout in seconds for fetching resources", default: 10
15
+ option :gpu, type: :boolean, desc: "Use GPU renderer instead of CPU renderer", default: false
15
16
  option :http_headers, desc: "HTTP Headers to use when fetching remote resource"
16
17
  option :base_url, desc: "Base URL used to resolve relative URLs"
17
18
 
data/lib/himg/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Himg
4
- VERSION = "0.0.8"
4
+ VERSION = "0.0.10"
5
5
  end
data/lib/himg.rb CHANGED
@@ -8,7 +8,7 @@ require "himg/railtie" if defined?(Rails::Railtie)
8
8
  # Fall back to loading the non-versioned extension if version-specific loading fails.
9
9
  begin
10
10
  RUBY_VERSION =~ /(\d+\.\d+)/
11
- require "#{Regexp.last_match(1)}/himg/himg"
11
+ require "himg/#{Regexp.last_match(1)}/himg"
12
12
  rescue LoadError
13
13
  require "himg/himg"
14
14
  end
@@ -17,10 +17,11 @@ end
17
17
  #
18
18
  # Converts HTML to an Image for a minimal subset of HTML and CSS
19
19
  module Himg
20
- RENDER_OPTIONS = %i[width height truncate verbose].freeze
20
+ RENDER_OPTIONS = %i[width height truncate verbose base_url disable_fetch fetch_timeout gpu].freeze
21
21
  class Error < StandardError; end
22
+ class GpuNotFound < Error; end
22
23
 
23
- def self.render(html, width: 720, height: 405, truncate: true, verbose: false, base_url: nil, disable_fetch: false, fetch_timeout: 10)
24
- render_to_string(html, "width" => width.to_i, "height" => height.to_i, "truncate" => truncate, "verbose" => verbose, "base_url" => BaseUrl.new(base_url).to_s, "disable_fetch" => disable_fetch, "fetch_timeout" => fetch_timeout.to_f)
24
+ def self.render(html, width: 720, height: 405, truncate: true, verbose: false, base_url: nil, disable_fetch: false, fetch_timeout: 10, gpu: false)
25
+ render_to_string(html, "width" => width.to_i, "height" => height.to_i, "truncate" => truncate, "verbose" => verbose, "base_url" => BaseUrl.new(base_url).to_s, "disable_fetch" => disable_fetch, "fetch_timeout" => fetch_timeout.to_f, "gpu" => gpu)
25
26
  end
26
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: himg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Edwards-Jones