skia 1.0.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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/LICENSE +21 -0
  4. data/README.md +205 -0
  5. data/Rakefile +8 -0
  6. data/examples/advanced_features.rb +50 -0
  7. data/examples/avatar_generator.rb +74 -0
  8. data/examples/bar_chart.rb +89 -0
  9. data/examples/basic_drawing.rb +43 -0
  10. data/examples/gradient.rb +32 -0
  11. data/examples/pdf_output.rb +48 -0
  12. data/examples/pdf_stream.rb +23 -0
  13. data/examples/picture_recording.rb +62 -0
  14. data/examples/progress_gauge.rb +103 -0
  15. data/examples/runtime_effect.rb +26 -0
  16. data/examples/social_card.rb +121 -0
  17. data/examples/text_drawing.rb +40 -0
  18. data/lib/skia/base.rb +40 -0
  19. data/lib/skia/bitmap.rb +140 -0
  20. data/lib/skia/canvas.rb +239 -0
  21. data/lib/skia/color.rb +82 -0
  22. data/lib/skia/color_filter.rb +23 -0
  23. data/lib/skia/color_space.rb +44 -0
  24. data/lib/skia/data.rb +47 -0
  25. data/lib/skia/document.rb +222 -0
  26. data/lib/skia/font.rb +118 -0
  27. data/lib/skia/image.rb +216 -0
  28. data/lib/skia/image_filter.rb +29 -0
  29. data/lib/skia/image_info.rb +59 -0
  30. data/lib/skia/mask_filter.rb +26 -0
  31. data/lib/skia/matrix.rb +163 -0
  32. data/lib/skia/native/callbacks.rb +6 -0
  33. data/lib/skia/native/functions.rb +384 -0
  34. data/lib/skia/native/types.rb +400 -0
  35. data/lib/skia/native.rb +67 -0
  36. data/lib/skia/paint.rb +144 -0
  37. data/lib/skia/path.rb +166 -0
  38. data/lib/skia/path_effect.rb +30 -0
  39. data/lib/skia/picture.rb +120 -0
  40. data/lib/skia/pixmap.rb +109 -0
  41. data/lib/skia/point.rb +94 -0
  42. data/lib/skia/rect.rb +179 -0
  43. data/lib/skia/rrect.rb +139 -0
  44. data/lib/skia/runtime_effect.rb +88 -0
  45. data/lib/skia/shader.rb +145 -0
  46. data/lib/skia/surface.rb +272 -0
  47. data/lib/skia/text_blob.rb +47 -0
  48. data/lib/skia/typeface.rb +175 -0
  49. data/lib/skia/version.rb +5 -0
  50. data/lib/skia.rb +42 -0
  51. data/skia-ruby.gemspec +30 -0
  52. metadata +107 -0
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skia
4
+ class Typeface < Base
5
+ WEIGHT_NORMAL = 400
6
+ WEIGHT_BOLD = 700
7
+ WIDTH_NORMAL = 5
8
+
9
+ def initialize(ptr)
10
+ super(ptr, :sk_typeface_unref)
11
+ end
12
+
13
+ def self.from_name(name, weight: WEIGHT_NORMAL, width: WIDTH_NORMAL, slant: :upright)
14
+ style = Native.sk_fontstyle_new(weight, width, slant)
15
+ begin
16
+ ptr = Native.sk_typeface_create_from_name(name, style)
17
+ return nil if ptr.nil? || ptr.null?
18
+
19
+ new(ptr)
20
+ ensure
21
+ Native.sk_fontstyle_delete(style) if style && !style.null?
22
+ end
23
+ end
24
+
25
+ def self.from_file(path, index = 0)
26
+ ptr = Native.sk_typeface_create_from_file(path, index)
27
+ raise FileNotFoundError, "Failed to load typeface: #{path}" if ptr.nil? || ptr.null?
28
+
29
+ new(ptr)
30
+ end
31
+
32
+ def self.default
33
+ ptr = Native.sk_typeface_create_default
34
+ return nil if ptr.nil? || ptr.null?
35
+
36
+ new(ptr)
37
+ end
38
+
39
+ def family_name
40
+ read_native_string(:sk_typeface_get_family_name)
41
+ end
42
+
43
+ def post_script_name
44
+ return nil unless Native.function_available?(:sk_typeface_get_post_script_name)
45
+
46
+ read_native_string(:sk_typeface_get_post_script_name)
47
+ end
48
+
49
+ def weight
50
+ Native.sk_typeface_get_font_weight(@ptr)
51
+ end
52
+
53
+ def width
54
+ Native.sk_typeface_get_font_width(@ptr)
55
+ end
56
+
57
+ def slant
58
+ Native.sk_typeface_get_font_slant(@ptr)
59
+ end
60
+
61
+ def fixed_pitch?
62
+ Native.sk_typeface_is_fixed_pitch(@ptr)
63
+ end
64
+
65
+ def units_per_em
66
+ Native.sk_typeface_get_units_per_em(@ptr)
67
+ end
68
+
69
+ def glyph_count
70
+ Native.sk_typeface_count_glyphs(@ptr)
71
+ end
72
+
73
+ def style
74
+ {
75
+ weight: weight,
76
+ width: width,
77
+ slant: slant,
78
+ fixed_pitch: fixed_pitch?,
79
+ units_per_em: units_per_em
80
+ }
81
+ end
82
+
83
+ def table_count
84
+ Native.sk_typeface_count_tables(@ptr)
85
+ end
86
+
87
+ def table_tags
88
+ count = table_count
89
+ return [] if count <= 0
90
+
91
+ tags_ptr = FFI::MemoryPointer.new(:uint32, count)
92
+ read_count = Native.sk_typeface_get_table_tags(@ptr, tags_ptr)
93
+ tags_ptr.read_array_of_uint32(read_count).map { |tag| self.class.tag_to_string(tag) }
94
+ end
95
+
96
+ def table_data(tag)
97
+ tag_u32 = self.class.tag_to_uint32(tag)
98
+ size = Native.sk_typeface_get_table_size(@ptr, tag_u32)
99
+ return nil if size <= 0
100
+
101
+ data_ptr = FFI::MemoryPointer.new(:uint8, size)
102
+ bytes_read = Native.sk_typeface_get_table_data(@ptr, tag_u32, 0, size, data_ptr)
103
+ return nil if bytes_read <= 0
104
+
105
+ data_ptr.read_bytes(bytes_read)
106
+ end
107
+
108
+ def variation_axes
109
+ fvar = table_data('fvar')
110
+ return [] if fvar.nil? || fvar.bytesize < 16
111
+
112
+ version, offset_to_data, = fvar.unpack('Nn')
113
+ return [] unless version == 0x0001_0000
114
+
115
+ axis_count = fvar.byteslice(8, 2).unpack1('n')
116
+ axis_size = fvar.byteslice(10, 2).unpack1('n')
117
+ return [] if axis_count <= 0 || axis_size < 20
118
+
119
+ axes = []
120
+ axis_count.times do |index|
121
+ offset = offset_to_data + (index * axis_size)
122
+ break if offset + 20 > fvar.bytesize
123
+
124
+ record = fvar.byteslice(offset, 20)
125
+ tag = record.byteslice(0, 4)
126
+ min_raw, default_raw, max_raw, flags, name_id = record.byteslice(4, 16).unpack('N3n2')
127
+
128
+ axes << {
129
+ tag: tag,
130
+ min_value: self.class.fixed_16_16_to_float(min_raw),
131
+ default_value: self.class.fixed_16_16_to_float(default_raw),
132
+ max_value: self.class.fixed_16_16_to_float(max_raw),
133
+ hidden: (flags & 0x0001) != 0,
134
+ name_id: name_id
135
+ }
136
+ end
137
+
138
+ axes
139
+ end
140
+
141
+ private
142
+
143
+ def read_native_string(function_name)
144
+ string_ptr = Native.send(function_name, @ptr)
145
+ return nil if string_ptr.nil? || string_ptr.null?
146
+
147
+ begin
148
+ cstr = Native.sk_string_get_c_str(string_ptr)
149
+ size = Native.sk_string_get_size(string_ptr)
150
+ cstr.read_string(size)
151
+ ensure
152
+ Native.sk_string_destructor(string_ptr)
153
+ end
154
+ end
155
+
156
+ def self.tag_to_string(tag_u32)
157
+ big_endian = [tag_u32].pack('N')
158
+ return big_endian if big_endian.match?(/\A[\x20-\x7E]{4}\z/)
159
+
160
+ [tag_u32].pack('V')
161
+ end
162
+
163
+ def self.tag_to_uint32(tag)
164
+ return tag if tag.is_a?(Integer)
165
+ raise ArgumentError, 'tag must be a 4-character String or Integer' unless tag.is_a?(String) && tag.bytesize == 4
166
+
167
+ tag.unpack1('N')
168
+ end
169
+
170
+ def self.fixed_16_16_to_float(raw)
171
+ signed = raw >= 0x8000_0000 ? raw - 0x1_0000_0000 : raw
172
+ signed / 65_536.0
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skia
4
+ VERSION = '1.0.0'
5
+ end
data/lib/skia.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ require_relative 'skia/version'
6
+ require_relative 'skia/native'
7
+ require_relative 'skia/base'
8
+ require_relative 'skia/color'
9
+ require_relative 'skia/color_space'
10
+ require_relative 'skia/point'
11
+ require_relative 'skia/rect'
12
+ require_relative 'skia/rrect'
13
+ require_relative 'skia/image_info'
14
+ require_relative 'skia/matrix'
15
+ require_relative 'skia/paint'
16
+ require_relative 'skia/path'
17
+ require_relative 'skia/mask_filter'
18
+ require_relative 'skia/color_filter'
19
+ require_relative 'skia/image_filter'
20
+ require_relative 'skia/path_effect'
21
+ require_relative 'skia/data'
22
+ require_relative 'skia/pixmap'
23
+ require_relative 'skia/bitmap'
24
+ require_relative 'skia/image'
25
+ require_relative 'skia/surface'
26
+ require_relative 'skia/canvas'
27
+ require_relative 'skia/typeface'
28
+ require_relative 'skia/font'
29
+ require_relative 'skia/text_blob'
30
+ require_relative 'skia/runtime_effect'
31
+ require_relative 'skia/shader'
32
+ require_relative 'skia/document'
33
+ require_relative 'skia/picture'
34
+
35
+ module Skia
36
+ class Error < StandardError; end
37
+ class NullPointerError < Error; end
38
+ class EncodingError < Error; end
39
+ class DecodingError < Error; end
40
+ class FileNotFoundError < Error; end
41
+ class UnsupportedOperationError < Error; end
42
+ end
data/skia-ruby.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/skia/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'skia'
7
+ spec.version = Skia::VERSION
8
+ spec.authors = ['Yudai Takada']
9
+ spec.email = ['t.yudai92@gmail.com']
10
+
11
+ spec.summary = 'Ruby bindings for Google Skia 2D graphics library'
12
+ spec.description = 'Ruby bindings for Skia, providing high-performance 2D graphics capabilities'
13
+ spec.homepage = 'https://github.com/ydah/skia-ruby'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.0.0'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = "#{spec.homepage}/tree/v#{spec.version}"
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
20
+
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (File.expand_path(f) == __FILE__) ||
24
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile Dockerfile])
25
+ end
26
+ end
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'ffi', '~> 1.15'
30
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skia
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yudai Takada
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ffi
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.15'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.15'
26
+ description: Ruby bindings for Skia, providing high-performance 2D graphics capabilities
27
+ email:
28
+ - t.yudai92@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - CHANGELOG.md
34
+ - LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - examples/advanced_features.rb
38
+ - examples/avatar_generator.rb
39
+ - examples/bar_chart.rb
40
+ - examples/basic_drawing.rb
41
+ - examples/gradient.rb
42
+ - examples/pdf_output.rb
43
+ - examples/pdf_stream.rb
44
+ - examples/picture_recording.rb
45
+ - examples/progress_gauge.rb
46
+ - examples/runtime_effect.rb
47
+ - examples/social_card.rb
48
+ - examples/text_drawing.rb
49
+ - lib/skia.rb
50
+ - lib/skia/base.rb
51
+ - lib/skia/bitmap.rb
52
+ - lib/skia/canvas.rb
53
+ - lib/skia/color.rb
54
+ - lib/skia/color_filter.rb
55
+ - lib/skia/color_space.rb
56
+ - lib/skia/data.rb
57
+ - lib/skia/document.rb
58
+ - lib/skia/font.rb
59
+ - lib/skia/image.rb
60
+ - lib/skia/image_filter.rb
61
+ - lib/skia/image_info.rb
62
+ - lib/skia/mask_filter.rb
63
+ - lib/skia/matrix.rb
64
+ - lib/skia/native.rb
65
+ - lib/skia/native/callbacks.rb
66
+ - lib/skia/native/functions.rb
67
+ - lib/skia/native/types.rb
68
+ - lib/skia/paint.rb
69
+ - lib/skia/path.rb
70
+ - lib/skia/path_effect.rb
71
+ - lib/skia/picture.rb
72
+ - lib/skia/pixmap.rb
73
+ - lib/skia/point.rb
74
+ - lib/skia/rect.rb
75
+ - lib/skia/rrect.rb
76
+ - lib/skia/runtime_effect.rb
77
+ - lib/skia/shader.rb
78
+ - lib/skia/surface.rb
79
+ - lib/skia/text_blob.rb
80
+ - lib/skia/typeface.rb
81
+ - lib/skia/version.rb
82
+ - skia-ruby.gemspec
83
+ homepage: https://github.com/ydah/skia-ruby
84
+ licenses:
85
+ - MIT
86
+ metadata:
87
+ homepage_uri: https://github.com/ydah/skia-ruby
88
+ source_code_uri: https://github.com/ydah/skia-ruby/tree/v1.0.0
89
+ changelog_uri: https://github.com/ydah/skia-ruby/blob/v1.0.0/CHANGELOG.md
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 3.0.0
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubygems_version: 4.0.6
105
+ specification_version: 4
106
+ summary: Ruby bindings for Google Skia 2D graphics library
107
+ test_files: []