hokusai-zero 0.1.4 → 0.1.6

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: 83cc0a077934960a9cfec3c52388de538b6816b6b4b9eb606ef449dac6f90608
4
- data.tar.gz: 514429bc54c1b49743a425e1f6fb1056dd8f564658b4ff8d46905a595c2a0fd9
3
+ metadata.gz: f58887af318a4986f8526a3868146766c62dbc6fa72e1a6a6f1a52cf1b4623e2
4
+ data.tar.gz: 76df215d1555e0930643485c626aa7d1ab8511d4430095f10f79b3ceff041c50
5
5
  SHA512:
6
- metadata.gz: 337549e39f52146323156c2c9f9deb4e2efd6ee03dfdce73eb6ccaee7416acc59924a3641d36e48c14425e9e1066c6f3c3c32736cfb20afe557c0927bf1572c2
7
- data.tar.gz: d29d8c032605dba3a48e930029a3e8ef588950ae2a4aaae70da6849b00a3243ff9505e5cdfce8edfc8635c2ff4b96d6aeab6d207ae0e81a8a0d70e9931b18e37
6
+ metadata.gz: 53552edadd8e5d20f770e6b9331963296bc406c629084fb781c4a5307cfca514c71a23d89db38a48abc87794ef6950738b6a19315373a68dcf8e751ed32030f5
7
+ data.tar.gz: d2172018d5129c5be0078ab04dd4d611ddb9bbca61296d8786fbb14c1f57c21fc28bb1de55c3ed05e2f6afc2fb9fd043704417f0c1c18f62bd61528fff8af04e
data/README.md CHANGED
@@ -9,13 +9,13 @@ A Ruby library for authoring GUI applications
9
9
 
10
10
  ## Getting started
11
11
 
12
- The build tooling of this project is [xmake](https://xmake.io/#/). You will need it to compile dependencies and run demos.
13
-
14
- Hokusai contains a tree-sitter grammar to parse templates, and uses `md4c` to parse markdown.
12
+ In your Gemfile
15
13
 
16
- When compiling the C portion of hokusai, tree-sitter will be statically linked.
14
+ ```ruby
15
+ gem "hokusai-zero", "0.1.4"
16
+ ```
17
17
 
18
- ## In order to run an application, you will also need to install a backend
18
+ ## In order to run an application, you will need to install a backend
19
19
 
20
20
  ### Raylib
21
21
 
@@ -23,7 +23,7 @@ When compiling the C portion of hokusai, tree-sitter will be statically linked.
23
23
  * Write your app
24
24
  * Run app with `RAYLIB_PATH=/libpath/for/libraylib.(so|dylib) ruby <your app>.rb`
25
25
 
26
- ### SDL
26
+ ### SDL2
27
27
 
28
28
  * Install the following deps
29
29
 
@@ -35,13 +35,6 @@ When compiling the C portion of hokusai, tree-sitter will be statically linked.
35
35
  * Write your app
36
36
  * Run app with `SDL_PATH=/libpath/for/libsdl.(so|dylib) ruby <your app>.rb`
37
37
 
38
-
39
- ## Gemfile
40
-
41
- ```ruby
42
- gem "hokusai-zero"
43
- ```
44
-
45
38
  ## Example counter application
46
39
 
47
40
  ```ruby
@@ -49,86 +42,35 @@ require "hokusai"
49
42
  require "hokusai/backends/raylib"
50
43
 
51
44
  class Counter < Hokusai::Block
52
- style <<~EOF
53
- [style]
54
- additionStyles {
55
- background: rgb(214, 49, 24);
56
- rounding: 0.0;
57
- outline: outline(1,4,4,1);
58
- outline_color: rgb(216, 26, 137);
59
- }
60
-
61
- additionLabel {
62
- size: 40;
63
- color: rgb(255,255,255);
64
- }
65
-
66
- subtractStyles {
67
- background: rgb(0, 85, 170);
68
- rounding: 0.0;
69
- }
70
-
71
- subtractLabel {
72
- size: 50;
73
- color: rgb(255,255,255);
74
- }
75
-
76
- scrollbar {
77
- width: 25;
78
- control_height: 100;
79
- control_padding: 5;
80
- control_rounding: 5;
81
- }
82
- EOF
83
-
84
45
  template <<-EOF
85
46
  [template]
86
- hblock { @keypress="update_keys"}
87
- vblock
88
- hblock
89
- label#count {
90
- :content="count"
91
- size="130"
92
- :color="count_color"
47
+ vblock
48
+ hblock
49
+ label {
50
+ :content="count"
51
+ size="130"
52
+ :color="count_color"
53
+ }
54
+ hblock
55
+ vblock
56
+ label {
57
+ content="Add"
58
+ @click="increment"
59
+ }
60
+ vblock
61
+ label {
62
+ content="Subtract"
63
+ @click="decrement"
93
64
  }
94
- hblock
95
- vblock#add { ...additionStyles }
96
- label {
97
- content="Add"
98
- @click="increment"
99
- ...additionLabel
100
- }
101
- vblock#subtract { ...subtractStyles }
102
- label {
103
- content="Subtract"
104
- @click="decrement"
105
- ...subtractLabel
106
- }
107
- [if="count_positive"]
108
- scrollbar { ...scrollbar }
109
65
  EOF
110
66
 
111
67
  uses(
112
68
  vblock: Hokusai::Blocks::Vblock,
113
69
  hblock: Hokusai::Blocks::Hblock,
114
70
  label: Hokusai::Blocks::Label,
115
- scrollbar: Hokusai::Blocks::Scrollbar,
116
- image: Hokusai::Blocks::Image
117
71
  )
118
72
 
119
- attr_accessor :count, :keys
120
-
121
- def count_positive
122
- count > 0
123
- end
124
-
125
- def modal
126
- !keys.empty?
127
- end
128
-
129
- def update_keys(event)
130
- @keys << event.char
131
- end
73
+ attr_accessor :count
132
74
 
133
75
  def increment(event)
134
76
  self.count += 1
@@ -144,7 +86,7 @@ class Counter < Hokusai::Block
144
86
 
145
87
  def initialize(**args)
146
88
  @count = 0
147
- @keys = ""
89
+
148
90
  super(**args)
149
91
  end
150
92
  end
@@ -158,6 +100,12 @@ end
158
100
 
159
101
  ## Development
160
102
 
103
+ The build tooling of this project is [xmake](https://xmake.io/#/). You will need it to compile dependencies and run demos.
104
+
105
+ Hokusai contains a tree-sitter grammar to parse templates, and uses `md4c` to parse markdown.
106
+
107
+ When compiling the C portion of hokusai, tree-sitter will be statically linked.
108
+
161
109
  Requirements:
162
110
  * [xmake](https://xmake.io/#/) to build dependencies
163
111
  * Ruby to run applications
data/ast/src/core/text.c CHANGED
@@ -3,6 +3,26 @@
3
3
 
4
4
  #include "text.h"
5
5
 
6
+ #ifdef _WIN32
7
+ size_t my_strnlen(const char* src, size_t n) {
8
+ size_t len = 0;
9
+ while (len < n && src[len]) len++;
10
+ return len;
11
+ }
12
+
13
+ char* strndup(const char* s, size_t n) {
14
+ size_t len = my_strnlen(s, n);
15
+ char* p = malloc(len + 1);
16
+ if (p)
17
+ {
18
+ memcpy(p, s, len);
19
+ p[len] = '\0';
20
+ }
21
+
22
+ return p;
23
+ }
24
+ #endif
25
+
6
26
  int hoku_text_char_init(hoku_char** character, int offset, int width)
7
27
  {
8
28
  hoku_char* init = malloc(sizeof(hoku_char));
data/ext/extconf.rb CHANGED
@@ -3,14 +3,19 @@ require "mini_portile2"
3
3
 
4
4
  if MiniPortile.darwin?
5
5
  suffix = "dylib"
6
+ ext = "zip"
6
7
  elsif MiniPortile.linux?
7
8
  suffix = "so"
9
+ ext = "tar.gz"
10
+ elsif MiniPortile.windows?
11
+ suffix = "dll"
12
+ ext = "zip"
8
13
  else
9
14
  raise "Currently only supporting darwin and linux"
10
15
  end
11
16
 
12
- tree_sitter = MiniPortile.new("libtree-sitter", "0.22.2", make_command: "make all")
13
- tree_sitter.files = ["https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.22.2.zip"]
17
+ tree_sitter = MiniPortile.new("libtree-sitter", "master", make_command: "make")
18
+ tree_sitter.files = ["https://github.com/tree-sitter/tree-sitter/archive/refs/heads/master.#{ext}"]
14
19
  tree_sitter.tap do |t|
15
20
  if t.source_directory
16
21
  t.prepare_build_directory
@@ -23,7 +28,7 @@ tree_sitter.tap do |t|
23
28
  def t.install
24
29
  return if installed?
25
30
 
26
- execute('install', %Q(PREFIX=#{File.expand_path(port_path)} #{make_cmd} all install))
31
+ execute('install', %Q(#{make_cmd} all install CC=gcc AR=ar PREFIX=#{File.expand_path(port_path)}), { env: { "PREFIX" => File.expand_path(port_path) }})
27
32
  end
28
33
 
29
34
  t.install
@@ -32,7 +37,7 @@ end
32
37
  tree_sitter.activate
33
38
 
34
39
  md4c = MiniPortileCMake.new("md4c", "0.5.2")
35
- md4c.files = ["https://github.com/mity/md4c/archive/refs/tags/release-0.5.2.zip"]
40
+ md4c.files = ["https://github.com/mity/md4c/archive/refs/tags/release-0.5.2.#{ext}"]
36
41
 
37
42
  def md4c.cmake_compile_flags
38
43
  [*super, "-DBUILD_SHARED_LIBS=OFF"]
@@ -42,11 +47,27 @@ md4c.cook
42
47
  md4c.activate
43
48
 
44
49
  pre = "#{__dir__}/.."
50
+ cwd = "#{__dir__}"
51
+
52
+ files = %w[ast/src/core/hml.c ast/src/core/ast.c ast/rc/core/style.c ast/src/core/input.c ast/src/core/component.c ast/src/core/util.c ast/src/core/text.c grammar/src/parser.c grammar/src/scanner.c ast/include/hashmap.c]
53
+ objects = %w[hml.o ast.o style.o input.o component.o util.o text.o parser.o scanner.o hashmap.o]
54
+ libraries = [File.expand_path("#{tree_sitter.path}/lib/libtree-sitter.a"), File.expand_path("#{md4c.path}/lib/libmd4c.a")]
55
+ src_files = ["#{tree_sitter.path}/lib/libtree-sitter.a", "#{md4c.path}/lib/libmd4c.a", "#{pre}/ast/src/core/hml.c", "#{pre}/ast/src/core/ast.c", "#{pre}/ast/src/core/style.c", "#{pre}/ast/src/core/input.c", "#{pre}/ast/src/core/component.c", "#{pre}/ast/src/core/util.c", "#{pre}/ast/src/core/text.c", "#{pre}/grammar/src/parser.c", "#{pre}/grammar/src/scanner.c", "#{pre}/ast/include/hashmap.c"]
56
+ if MiniPortile.windows?
57
+ cflags = "-shared -Wall -Wl,--export-all-symbols -Wl,--enable-auto-import"
58
+ mkdir = "mkdir #{pre}\\vendor\\lib"
59
+ else
60
+ cflags = "-fPIC -shared -Wall"
61
+ mkdir = "mkdir -p #{pre}/vendor/lib"
62
+ end
45
63
 
46
64
  File.open("Makefile", "w") do |io|
47
65
  io << <<~EOF
48
- src_files = #{tree_sitter.path}/lib/libtree-sitter.a #{md4c.path}/lib/libmd4c.a #{pre}/ast/src/core/hml.c #{pre}/ast/src/core/ast.c #{pre}/ast/src/core/style.c #{pre}/ast/src/core/input.c #{pre}/ast/src/core/component.c #{pre}/ast/src/core/util.c #{pre}/ast/src/core/text.c #{pre}/grammar/src/parser.c #{pre}/grammar/src/scanner.c #{pre}/ast/include/hashmap.c
49
- includes = -I#{pre}/ast/include -I#{pre}/ast/src -I#{pre}/grammar/src -I#{tree_sitter.path}/include -I#{md4c.path}/include
66
+ src_files = #{files.map {|file| File.expand_path("#{pre}/#{file}")}.join(" ")}
67
+ object_files = #{objects.map {|file| File.expand_path("#{cwd}/#{file}")}.join(" ")}
68
+ libraries = #{libraries.join(" ")}
69
+ src_files = #{src_files.map { |file| File.expand_path(file)}.join(" ")}
70
+ includes = -I#{File.expand_path("#{pre}/ast/include")} -I#{File.expand_path("#{pre}/ast/src")} -I#{File.expand_path("#{pre}/grammar/src")} -I#{File.expand_path("#{tree_sitter.path}/include")} -I#{File.expand_path("#{md4c.path}/include")}
50
71
  all: clean hokusai
51
72
 
52
73
  .PHONY: hokuasi
@@ -55,11 +76,12 @@ File.open("Makefile", "w") do |io|
55
76
  #{"\t"}echo "done"
56
77
 
57
78
  hokusai:
58
- #{"\t"}mkdir -p #{pre}/vendor/lib
59
- #{"\t"}gcc -shared -Wall $(includes) -o #{pre}/vendor/lib/libhokusai.#{suffix} $(src_files)
79
+ #{"\t"}#{mkdir}
80
+ #{"\t"}gcc -c $(includes) $(src_files) $(libraries)
81
+ #{"\t"}gcc #{cflags} $(includes) -o #{File.expand_path("#{pre}/vendor/lib/libhokusai.#{suffix}")} $(object_files) $(libraries)
60
82
 
61
83
  clean:
62
- #{"\t"}rm -f vendor/lib/libhokusai.*
63
- #{"\t"}rm -f vendor/lib/libmd4c.*
84
+ #{"\t"}rm -f #{File.expand_path("vendor/lib/libhokusai.*")}
85
+ #{"\t"}rm -f #{File.expand_path("vendor/lib/libmd4c.*")}
64
86
  EOF
65
87
  end
data/hokusai.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'hokusai-zero'
3
- s.version = '0.1.4'
3
+ s.version = '0.1.6'
4
4
  s.licenses = ['PPL']
5
5
  s.summary = "A Ruby library for writing GUI applications"
6
6
  s.authors = ["skinnyjames"]
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.metadata = { "source_code_uri" => "https://codeberg.org/skinnyjames/hokusai" }
17
17
 
18
18
  s.add_dependency "ffi", "~> 1.16"
19
+ s.add_dependency "colorize"
19
20
  s.add_dependency "concurrent-ruby", "~> 1.3.4"
20
21
  s.add_dependency "raylib-bindings", "~> 0.7.9"
21
22
  s.add_dependency "sdl2-bindings", "~> 0.2.3"
@@ -33,33 +33,38 @@ module Demos
33
33
  control_padding: 5;
34
34
  control_rounding: 5;
35
35
  }
36
+ modalContent {
37
+ width: 300.0;
38
+ height: 300.0;
39
+ background: rgb(255, 255, 255);
40
+ }
36
41
  EOF
37
42
 
38
43
  template <<-EOF
39
44
  [template]
40
- hblock { @keypress="update_keys"}
41
- vblock
42
- hblock
43
- label#count {
44
- :content="count"
45
- size="130"
46
- :color="count_color"
45
+ vblock
46
+ hblock
47
+ label#count {
48
+ :content="count"
49
+ size="130"
50
+ :color="count_color"
51
+ }
52
+ modal { :active="over_20" @close="close_modal" }
53
+ vblock { ...modalContent }
54
+ text { content="okay" }
55
+ hblock
56
+ vblock#add { ...additionStyles }
57
+ label {
58
+ content="Add"
59
+ @click="increment"
60
+ ...additionLabel
61
+ }
62
+ vblock#subtract { ...subtractStyles }
63
+ label {
64
+ content="Subtract"
65
+ @click="decrement"
66
+ ...subtractLabel
47
67
  }
48
- hblock
49
- vblock#add { ...additionStyles }
50
- label {
51
- content="Add"
52
- @click="increment"
53
- ...additionLabel
54
- }
55
- vblock#subtract { ...subtractStyles }
56
- label {
57
- content="Subtract"
58
- @click="decrement"
59
- ...subtractLabel
60
- }
61
- [if="count_positive"]
62
- scrollbar { ...scrollbar }
63
68
  EOF
64
69
 
65
70
  uses(
@@ -67,21 +72,23 @@ module Demos
67
72
  hblock: Hokusai::Blocks::Hblock,
68
73
  label: Hokusai::Blocks::Label,
69
74
  scrollbar: Hokusai::Blocks::Scrollbar,
70
- image: Hokusai::Blocks::Image
75
+ image: Hokusai::Blocks::Image,
76
+ modal: Hokusai::Blocks::Modal,
77
+ text: Hokusai::Blocks::Text
71
78
  )
72
79
 
73
- attr_accessor :count, :keys
80
+ attr_accessor :count, :keys, :modal_open
74
81
 
75
82
  def count_positive
76
83
  count > 0
77
84
  end
78
85
 
79
- def modal
80
- !keys.empty?
86
+ def over_20
87
+ count > 20
81
88
  end
82
89
 
83
- def update_keys(event)
84
- @keys << event.char
90
+ def close_modal
91
+ self.count = 0
85
92
  end
86
93
 
87
94
  def increment(event)
@@ -99,6 +106,7 @@ module Demos
99
106
  def initialize(**args)
100
107
  @count = 0
101
108
  @keys = ""
109
+ @modal_open = false
102
110
  super(**args)
103
111
  end
104
112
  end
data/ui/examples/forum.rb CHANGED
@@ -70,29 +70,29 @@ module Demos
70
70
  label {
71
71
  ...appTitle
72
72
  }
73
- panel#app { ...panelStyle }
74
- vblock { :height="50.0" }
75
- hblock { :height="forum_height" }
76
- hblock { :width="margin_width" }
77
- vblock { :width="panel_width" }
78
- [for="post in posts"]
79
- post {
80
- @height_updated="update_forum_height"
81
- :width="panel_width"
82
- :index="index"
83
- :key="index"
84
- :post="post"
85
- }
86
- vblock.recents
87
- hblock.header { width="100" }
88
- image { ...ernestImage }
89
- vblock { width="20" }
90
- vblock { width="300" }
91
- text { ...recentsLabel }
92
- music { height="50" }
93
- [for="item in files"]
94
- file { height="30" :item="item" :key="index" :index="index" }
95
-
73
+ selectable
74
+ panel#app { ...panelStyle }
75
+ vblock { :height="50.0" }
76
+ hblock { :height="forum_height" }
77
+ hblock { :width="margin_width" }
78
+ vblock { :width="panel_width" }
79
+ [for="post in posts"]
80
+ post {
81
+ @height_updated="update_forum_height"
82
+ :width="panel_width"
83
+ :index="index"
84
+ :key="index"
85
+ :post="post"
86
+ }
87
+ vblock.recents
88
+ hblock.header { width="100" }
89
+ image { ...ernestImage }
90
+ vblock { width="20" }
91
+ vblock { width="300" }
92
+ text { ...recentsLabel }
93
+ music { height="50" }
94
+ [for="item in files"]
95
+ file { height="30" :item="item" :key="index" :index="index" }
96
96
  EOF
97
97
 
98
98
  uses(
@@ -106,7 +106,8 @@ module Demos
106
106
  text: Hokusai::Blocks::Text,
107
107
  label: Hokusai::Blocks::Label,
108
108
  titlebar: Hokusai::Blocks::Titlebar::OSX,
109
- image: Hokusai::Blocks::Image
109
+ image: Hokusai::Blocks::Image,
110
+ selectable: Hokusai::Blocks::Selectable
110
111
  )
111
112
 
112
113
  def update_forum_height(height, index)
@@ -12,6 +12,7 @@ module Demos
12
12
  padding: padding(5.0, 5.0, 5.0, 5.0);
13
13
  size: 20;
14
14
  text_color: rgb(244, 244, 244);
15
+ text_selection_color: rgb(74, 74, 95);
15
16
  }
16
17
  EOF
17
18
 
@@ -181,7 +182,8 @@ module Demos
181
182
  hblock: Hokusai::Blocks::Hblock,
182
183
  panel: Hokusai::Blocks::Panel,
183
184
  row: Spreadsheet::Row,
184
- label: Hokusai::Blocks::Label
185
+ label: Hokusai::Blocks::Label,
186
+ selectable: Hokusai::Blocks::Selectable
185
187
  )
186
188
 
187
189
  computed! :csv
@@ -45,7 +45,8 @@ module Demos
45
45
  label { ...appTitle size="14" content="somecsv.csv" }
46
46
  label { ...appTitle size="14" :content="status" }
47
47
  [if="has_spreadsheet"]
48
- csv { @modified="set_status" :csv="spreadsheet" @keypress="handle_keypress" }
48
+ selectable
49
+ csv { @modified="set_status" :csv="spreadsheet" @keypress="handle_keypress" }
49
50
  EOF
50
51
 
51
52
  uses(
@@ -56,7 +57,8 @@ module Demos
56
57
  label: Hokusai::Blocks::Label,
57
58
  titlebar: Hokusai::Blocks::Titlebar::OSX,
58
59
  image: Hokusai::Blocks::Image,
59
- csv: Spreadsheet::CSV
60
+ csv: Spreadsheet::CSV,
61
+ selectable: Hokusai::Blocks::Selectable
60
62
  )
61
63
 
62
64
  attr_reader :spreadsheet
@@ -9,6 +9,8 @@ module LibHokusai
9
9
  ffi_lib "#{__dir__}/../../vendor/lib/libhokusai.dylib"
10
10
  when /linux/
11
11
  ffi_lib "#{__dir__}/../../vendor/lib/libhokusai.so"
12
+ when /mingw32|mswin|msys/
13
+ ffi_lib "#{__dir__}/../../vendor/lib/libhokusai.dll"
12
14
  else
13
15
  raise "Unsupported platform!"
14
16
  end
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><title>finite-icons</title><path d="M13.60851,6.08611L8.35425,11.339,3.06908,6.05389a0.5,0.5,0,0,1,0-.70711l0.539-.539a0.5,0.5,0,0,1,.70711,0l4.03907,4.039L12.36249,4.8399a0.5,0.5,0,0,1,.70705.00006l0.539,0.539A0.5,0.5,0,0,1,13.60851,6.08611Z" fill="#231f20"/></svg>
@@ -5,7 +5,18 @@ require 'memory_profiler'
5
5
 
6
6
  module Hokusai::Backends
7
7
  class RaylibBackend
8
- RAYLIB_PATH = ENV["RAYLIB_PATH"] || "#{__dir__}/../../../../vendor/lib"
8
+
9
+ RAYLIB_PATH = ENV["RAYLIB_PATH"] || begin
10
+ path = "#{__dir__}/../../../../vendor/lib"
11
+ case RbConfig::CONFIG['host_os']
12
+ when /darwin/
13
+ "#{path}/libraylib.dylib"
14
+ when /mswin|msys|mingw/
15
+ "#{path}/libraylib.dll"
16
+ when /linux/
17
+ "#{path}/libraylib.so"
18
+ end
19
+ end
9
20
 
10
21
  attr_reader :config
11
22
 
@@ -137,14 +148,7 @@ module Hokusai::Backends
137
148
  def run(block)
138
149
  self.class.reset
139
150
 
140
- case RbConfig::CONFIG['host_os']
141
- when /darwin/
142
- Raylib.load_lib("#{RAYLIB_PATH}/libraylib.dylib")
143
- when /mswin|msys|mingw/
144
- Raylib.load_lib("#{RAYLIB_PATH}/libraylib.dll")
145
- when /linux/
146
- Raylib.load_lib("#{RAYLIB_PATH}/libraylib.so")
147
- end
151
+ Raylib.load_lib(RAYLIB_PATH)
148
152
 
149
153
  resize = false
150
154
  initial = true
@@ -237,6 +241,10 @@ module Hokusai::Backends
237
241
  Raylib.UnloadFont(font.raw)
238
242
  end
239
243
 
244
+ self.class.images.each do |_, texture|
245
+ Raylib.UnloadTexture(texture)
246
+ end
247
+
240
248
  LibHokusai.hoku_input_free(input.raw)
241
249
 
242
250
  if ENV["PROFILE"]
@@ -329,7 +337,6 @@ module Hokusai::Backends
329
337
  end
330
338
 
331
339
  Hokusai::Commands::SVG.on_draw do |command|
332
- command = command.as(Hokusai::Commands::SVG)
333
340
  texture = begin
334
341
  if self.class.images[command.source]
335
342
  self.class.images[command.source]
@@ -402,6 +402,33 @@ module Hokusai::Backends
402
402
  SDL.RenderCopy(renderer, texture, nil, rect)
403
403
  end
404
404
 
405
+ Hokusai::Commands::SVG.on_draw do |command|
406
+ next unless inside_scissor(command.x, command.y, command.height)
407
+
408
+ texture = begin
409
+ if self.class.images[command.source]
410
+ self.class.images[command.source]
411
+ else
412
+ file = File.read(command.source)
413
+
414
+ rw = SDL.RWFromConstMem(file, file.size)
415
+ surface_ptr = SDL.IMG_Load_RW(rw, 1)
416
+ if surface_ptr.null?
417
+ raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
418
+ end
419
+
420
+ texture = SDL.CreateTextureFromSurface(renderer, surface_ptr)
421
+ self.class.images[command.source] = texture
422
+ SDL.FreeSurface(surface_ptr)
423
+ texture
424
+ end
425
+ end
426
+
427
+ SDL.SetTextureColorMod(texture, command.color.r, command.color.g, command.color.b)
428
+ rect = sdl_rect(command.x, command.y, command.width, command.height)
429
+ SDL.RenderCopy(renderer, texture, nil, rect)
430
+ end
431
+
405
432
  Hokusai::Commands::Rect.on_draw do |command|
406
433
  next unless inside_scissor(command.x, command.y, command.height)
407
434
  # draw background first