skia 0.1.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE +21 -0
- data/README.md +345 -0
- data/Rakefile +8 -0
- data/examples/avatar_generator.rb +74 -0
- data/examples/bar_chart.rb +89 -0
- data/examples/basic_drawing.rb +43 -0
- data/examples/gradient.rb +32 -0
- data/examples/pdf_output.rb +48 -0
- data/examples/picture_recording.rb +62 -0
- data/examples/progress_gauge.rb +103 -0
- data/examples/social_card.rb +121 -0
- data/examples/text_drawing.rb +40 -0
- data/lib/skia/base.rb +40 -0
- data/lib/skia/canvas.rb +177 -0
- data/lib/skia/color.rb +82 -0
- data/lib/skia/data.rb +47 -0
- data/lib/skia/document.rb +76 -0
- data/lib/skia/font.rb +74 -0
- data/lib/skia/image.rb +137 -0
- data/lib/skia/matrix.rb +163 -0
- data/lib/skia/native/callbacks.rb +6 -0
- data/lib/skia/native/functions.rb +223 -0
- data/lib/skia/native/types.rb +284 -0
- data/lib/skia/native.rb +50 -0
- data/lib/skia/paint.rb +100 -0
- data/lib/skia/path.rb +135 -0
- data/lib/skia/picture.rb +120 -0
- data/lib/skia/point.rb +94 -0
- data/lib/skia/rect.rb +179 -0
- data/lib/skia/shader.rb +107 -0
- data/lib/skia/surface.rb +151 -0
- data/lib/skia/typeface.rb +39 -0
- data/lib/skia/version.rb +5 -0
- data/lib/skia.rb +31 -0
- data/skia-ruby.gemspec +30 -0
- metadata +93 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e71b72f2e4a4beeadc80cc96833789db9ee8916ae38287d8b8a2ef2af6569122
|
|
4
|
+
data.tar.gz: a786a9b50ae23c14bafb49354a639244c3efa201c737e86b782b29fb2f1ce889
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3f7d931e61b8f9967f25e14f2fc1cd7782b6869ac2a68f5f84f065fad3eeb8276abc2ff2813c81e6ed23c2ea376da65e2ca9fff7a974f7c0a0aa3c5a6abf4e2d
|
|
7
|
+
data.tar.gz: 8ae82f68f257171a00ca82302e26b9114cf865c13e17fbdec6a2ea920173cd503c42ae426e15872a475b909ad6d67be05cb282f08d14e9c2d2ac979f7d6af5ad
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
## 0.1.0 - 2025-12-31
|
|
11
|
+
|
|
12
|
+
- Initial release
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Yudai Takada
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# Skia Ruby
|
|
2
|
+
|
|
3
|
+
Ruby bindings for the Skia 2D graphics library.
|
|
4
|
+
|
|
5
|
+
<img width="400" alt="Image" src="https://github.com/user-attachments/assets/440971a6-bf10-4cc2-abe6-e5cf28949b95" />
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This gem provides Ruby bindings for Skia, Google's high-performance 2D graphics library. It uses FFI (Foreign Function Interface) to interface with SkiaSharp's C API, enabling hardware-accelerated graphics rendering from Ruby.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- Ruby 3.0 or later
|
|
14
|
+
- SkiaSharp native library (libSkiaSharp)
|
|
15
|
+
|
|
16
|
+
### Installing SkiaSharp
|
|
17
|
+
|
|
18
|
+
**macOS:**
|
|
19
|
+
```bash
|
|
20
|
+
# Download from SkiaSharp releases
|
|
21
|
+
curl -L -o skiasharp.nupkg https://www.nuget.org/api/v2/package/SkiaSharp.NativeAssets.macOS
|
|
22
|
+
unzip skiasharp.nupkg -d skiasharp-extract
|
|
23
|
+
cp skiasharp-extract/runtimes/osx/native/libSkiaSharp.dylib .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Linux:**
|
|
27
|
+
```bash
|
|
28
|
+
curl -L -o skiasharp.nupkg https://www.nuget.org/api/v2/package/SkiaSharp.NativeAssets.Linux.x64
|
|
29
|
+
unzip skiasharp.nupkg -d skiasharp-extract
|
|
30
|
+
cp skiasharp-extract/runtimes/linux-x64/native/libSkiaSharp.so .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Windows:**
|
|
34
|
+
```powershell
|
|
35
|
+
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/SkiaSharp.NativeAssets.Win32 -OutFile skiasharp.nupkg
|
|
36
|
+
Expand-Archive skiasharp.nupkg -DestinationPath skiasharp-extract
|
|
37
|
+
copy skiasharp-extract\runtimes\win-x64\native\libSkiaSharp.dll .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Add this line to your application's Gemfile:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
gem 'skia'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
And then execute:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bundle install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or install it yourself as:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gem install skia
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
### Basic Example
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
require 'skia'
|
|
66
|
+
|
|
67
|
+
surface = Skia::Surface.make_raster(640, 480)
|
|
68
|
+
|
|
69
|
+
surface.draw do |canvas|
|
|
70
|
+
canvas.clear(Skia::Color::WHITE)
|
|
71
|
+
|
|
72
|
+
paint = Skia::Paint.new
|
|
73
|
+
paint.antialias = true
|
|
74
|
+
paint.color = Skia::Color::RED
|
|
75
|
+
|
|
76
|
+
canvas.draw_circle(320, 240, 100, paint)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
surface.save_png('output.png')
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Drawing Shapes
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
surface = Skia::Surface.make_raster(400, 400)
|
|
86
|
+
|
|
87
|
+
surface.draw do |canvas|
|
|
88
|
+
canvas.clear(Skia::Color::WHITE)
|
|
89
|
+
|
|
90
|
+
paint = Skia::Paint.new
|
|
91
|
+
paint.antialias = true
|
|
92
|
+
|
|
93
|
+
# Rectangle
|
|
94
|
+
paint.color = Skia::Color::BLUE
|
|
95
|
+
canvas.draw_rect(Skia::Rect.from_xywh(50, 50, 100, 80), paint)
|
|
96
|
+
|
|
97
|
+
# Circle
|
|
98
|
+
paint.color = Skia::Color::RED
|
|
99
|
+
canvas.draw_circle(250, 100, 50, paint)
|
|
100
|
+
|
|
101
|
+
# Oval
|
|
102
|
+
paint.color = Skia::Color::GREEN
|
|
103
|
+
canvas.draw_oval(Skia::Rect.from_xywh(150, 200, 150, 80), paint)
|
|
104
|
+
|
|
105
|
+
# Rounded rectangle
|
|
106
|
+
paint.color = Skia::Color::MAGENTA
|
|
107
|
+
canvas.draw_round_rect(Skia::Rect.from_xywh(50, 300, 120, 60), 15, paint)
|
|
108
|
+
|
|
109
|
+
# Line
|
|
110
|
+
paint.style = :stroke
|
|
111
|
+
paint.stroke_width = 3
|
|
112
|
+
paint.color = Skia::Color::BLACK
|
|
113
|
+
canvas.draw_line(300, 200, 380, 350, paint)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
surface.save_png('shapes.png')
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Using Paths
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
path = Skia::Path.build do
|
|
123
|
+
move_to 100, 100
|
|
124
|
+
line_to 200, 100
|
|
125
|
+
line_to 200, 200
|
|
126
|
+
quad_to 150, 250, 100, 200
|
|
127
|
+
close
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
surface.draw do |canvas|
|
|
131
|
+
paint = Skia::Paint.new
|
|
132
|
+
paint.color = Skia::Color.rgb(255, 128, 0)
|
|
133
|
+
canvas.draw_path(path, paint)
|
|
134
|
+
end
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Gradients
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
surface.draw do |canvas|
|
|
141
|
+
# Linear gradient
|
|
142
|
+
shader = Skia::Shader.linear_gradient(
|
|
143
|
+
Skia::Point.new(0, 0),
|
|
144
|
+
Skia::Point.new(400, 0),
|
|
145
|
+
[Skia::Color::RED, Skia::Color::YELLOW, Skia::Color::BLUE]
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
paint = Skia::Paint.new
|
|
149
|
+
paint.shader = shader
|
|
150
|
+
canvas.draw_rect(Skia::Rect.from_xywh(0, 0, 400, 200), paint)
|
|
151
|
+
|
|
152
|
+
# Radial gradient
|
|
153
|
+
radial = Skia::Shader.radial_gradient(
|
|
154
|
+
Skia::Point.new(200, 300),
|
|
155
|
+
80,
|
|
156
|
+
[Skia::Color::WHITE, Skia::Color::BLUE]
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
paint.shader = radial
|
|
160
|
+
canvas.draw_circle(200, 300, 80, paint)
|
|
161
|
+
end
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Text Drawing
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
surface.draw do |canvas|
|
|
168
|
+
canvas.clear(Skia::Color::WHITE)
|
|
169
|
+
|
|
170
|
+
font = Skia::Font.new(nil, 48.0)
|
|
171
|
+
paint = Skia::Paint.new
|
|
172
|
+
paint.antialias = true
|
|
173
|
+
paint.color = Skia::Color::BLACK
|
|
174
|
+
|
|
175
|
+
canvas.draw_text('Hello, Skia!', 50, 100, font, paint)
|
|
176
|
+
|
|
177
|
+
# Measure text
|
|
178
|
+
width, bounds = font.measure_text('Hello, Skia!')
|
|
179
|
+
puts "Text width: #{width}"
|
|
180
|
+
end
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Canvas Transformations
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
surface.draw do |canvas|
|
|
187
|
+
canvas.clear(Skia::Color::WHITE)
|
|
188
|
+
|
|
189
|
+
paint = Skia::Paint.new
|
|
190
|
+
paint.color = Skia::Color::BLUE
|
|
191
|
+
|
|
192
|
+
# Save state, transform, draw, restore
|
|
193
|
+
canvas.with_save do
|
|
194
|
+
canvas.translate(200, 200)
|
|
195
|
+
canvas.rotate(45)
|
|
196
|
+
canvas.draw_rect(Skia::Rect.from_xywh(-50, -50, 100, 100), paint)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Scale
|
|
200
|
+
canvas.with_save do
|
|
201
|
+
canvas.translate(100, 100)
|
|
202
|
+
canvas.scale(2.0, 0.5)
|
|
203
|
+
paint.color = Skia::Color::RED
|
|
204
|
+
canvas.draw_circle(0, 0, 30, paint)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### PDF Output
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
Skia::Document.create_pdf('output.pdf') do |doc|
|
|
213
|
+
doc.begin_page(612, 792) do |canvas|
|
|
214
|
+
canvas.clear(Skia::Color::WHITE)
|
|
215
|
+
|
|
216
|
+
font = Skia::Font.new(nil, 24.0)
|
|
217
|
+
paint = Skia::Paint.new
|
|
218
|
+
paint.color = Skia::Color::BLACK
|
|
219
|
+
|
|
220
|
+
canvas.draw_text('Hello, PDF!', 50, 100, font, paint)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
doc.begin_page(612, 792) do |canvas|
|
|
224
|
+
canvas.clear(Skia::Color::WHITE)
|
|
225
|
+
# Second page content
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Picture Recording
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
bounds = Skia::Rect.from_xywh(0, 0, 200, 200)
|
|
234
|
+
|
|
235
|
+
picture = Skia::Picture.record(bounds) do |canvas|
|
|
236
|
+
paint = Skia::Paint.new
|
|
237
|
+
paint.color = Skia::Color::RED
|
|
238
|
+
canvas.draw_circle(100, 100, 80, paint)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Replay on different surfaces
|
|
242
|
+
surface.draw do |canvas|
|
|
243
|
+
canvas.translate(50, 50)
|
|
244
|
+
picture.playback(canvas)
|
|
245
|
+
|
|
246
|
+
canvas.translate(250, 0)
|
|
247
|
+
canvas.scale(0.5, 0.5)
|
|
248
|
+
picture.playback(canvas)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Serialize/deserialize
|
|
252
|
+
data = picture.serialize
|
|
253
|
+
loaded = Skia::Picture.from_data(data)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Image Loading and Saving
|
|
257
|
+
|
|
258
|
+
```ruby
|
|
259
|
+
# Load image
|
|
260
|
+
image = Skia::Image.from_file('input.png')
|
|
261
|
+
puts "Image size: #{image.width}x#{image.height}"
|
|
262
|
+
|
|
263
|
+
# Draw image
|
|
264
|
+
surface.draw do |canvas|
|
|
265
|
+
canvas.draw_image(image, 0, 0)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Save in different formats
|
|
269
|
+
surface.save_png('output.png')
|
|
270
|
+
surface.save_jpeg('output.jpg', quality: 90)
|
|
271
|
+
surface.save_webp('output.webp', quality: 80)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## API Reference
|
|
275
|
+
|
|
276
|
+
### Main Classes
|
|
277
|
+
|
|
278
|
+
- `Skia::Surface` - Drawing surface (raster or GPU-backed)
|
|
279
|
+
- `Skia::Canvas` - Drawing context with transformation and clipping
|
|
280
|
+
- `Skia::Paint` - Style and color settings for drawing
|
|
281
|
+
- `Skia::Path` - Vector path for complex shapes
|
|
282
|
+
- `Skia::Image` - Immutable bitmap image
|
|
283
|
+
- `Skia::Shader` - Gradient and pattern fills
|
|
284
|
+
- `Skia::Font` - Font for text rendering
|
|
285
|
+
- `Skia::Typeface` - Font family and style
|
|
286
|
+
- `Skia::Document` - Multi-page document (PDF)
|
|
287
|
+
- `Skia::Picture` - Recorded drawing commands
|
|
288
|
+
|
|
289
|
+
### Geometry Classes
|
|
290
|
+
|
|
291
|
+
- `Skia::Point` - 2D point (x, y)
|
|
292
|
+
- `Skia::Rect` - Rectangle (left, top, right, bottom)
|
|
293
|
+
- `Skia::Matrix` - 3x3 transformation matrix
|
|
294
|
+
- `Skia::Color` - ARGB color value
|
|
295
|
+
|
|
296
|
+
### Constants
|
|
297
|
+
|
|
298
|
+
Paint styles:
|
|
299
|
+
- `:fill` - Fill shapes
|
|
300
|
+
- `:stroke` - Outline shapes
|
|
301
|
+
- `:stroke_and_fill` - Both fill and outline
|
|
302
|
+
|
|
303
|
+
Stroke caps:
|
|
304
|
+
- `:butt` - Flat cap
|
|
305
|
+
- `:round` - Round cap
|
|
306
|
+
- `:square` - Square cap
|
|
307
|
+
|
|
308
|
+
Stroke joins:
|
|
309
|
+
- `:miter` - Sharp corners
|
|
310
|
+
- `:round` - Rounded corners
|
|
311
|
+
- `:bevel` - Beveled corners
|
|
312
|
+
|
|
313
|
+
Blend modes:
|
|
314
|
+
- `:src_over`, `:multiply`, `:screen`, `:overlay`, etc.
|
|
315
|
+
|
|
316
|
+
## Development
|
|
317
|
+
|
|
318
|
+
After checking out the repo, run:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
bundle install
|
|
322
|
+
bundle exec rspec
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
To run examples:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
ruby examples/basic_drawing.rb
|
|
329
|
+
ruby examples/gradient.rb
|
|
330
|
+
ruby examples/bar_chart.rb
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Contributing
|
|
334
|
+
|
|
335
|
+
Bug reports and pull requests are welcome on GitHub.
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
340
|
+
|
|
341
|
+
## Acknowledgments
|
|
342
|
+
|
|
343
|
+
- [Skia Graphics Library](https://skia.org/)
|
|
344
|
+
- [SkiaSharp](https://github.com/mono/SkiaSharp)
|
|
345
|
+
- [Ruby FFI](https://github.com/ffi/ffi)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/skia'
|
|
5
|
+
|
|
6
|
+
def generate_avatar(name, size: 200, output: nil)
|
|
7
|
+
initials = name.split.map { |n| n[0].upcase }.join[0, 2]
|
|
8
|
+
|
|
9
|
+
hash = name.chars.map(&:ord).sum
|
|
10
|
+
hue = hash % 360
|
|
11
|
+
|
|
12
|
+
c = 0.6
|
|
13
|
+
x = c * (1 - ((hue / 60.0) % 2 - 1).abs)
|
|
14
|
+
m = 0.2
|
|
15
|
+
|
|
16
|
+
r, g, b = case hue / 60
|
|
17
|
+
when 0 then [c, x, 0]
|
|
18
|
+
when 1 then [x, c, 0]
|
|
19
|
+
when 2 then [0, c, x]
|
|
20
|
+
when 3 then [0, x, c]
|
|
21
|
+
when 4 then [x, 0, c]
|
|
22
|
+
else [c, 0, x]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
bg_color = Skia::Color.rgb(
|
|
26
|
+
((r + m) * 255).to_i,
|
|
27
|
+
((g + m) * 255).to_i,
|
|
28
|
+
((b + m) * 255).to_i
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
surface = Skia::Surface.make_raster(size, size)
|
|
32
|
+
|
|
33
|
+
surface.draw do |canvas|
|
|
34
|
+
canvas.clear(Skia::Color::TRANSPARENT)
|
|
35
|
+
|
|
36
|
+
paint = Skia::Paint.new
|
|
37
|
+
paint.antialias = true
|
|
38
|
+
|
|
39
|
+
paint.color = bg_color
|
|
40
|
+
paint.style = :fill
|
|
41
|
+
canvas.draw_circle(size / 2.0, size / 2.0, size / 2.0, paint)
|
|
42
|
+
|
|
43
|
+
font_size = size * 0.4
|
|
44
|
+
font = Skia::Font.new(nil, font_size)
|
|
45
|
+
paint.color = Skia::Color::WHITE
|
|
46
|
+
|
|
47
|
+
text_width, text_bounds = font.measure_text(initials)
|
|
48
|
+
metrics = font.metrics
|
|
49
|
+
x = (size - text_width) / 2.0
|
|
50
|
+
y = (size / 2.0) - (metrics.ascent + metrics.descent) / 2.0
|
|
51
|
+
|
|
52
|
+
canvas.draw_text(initials, x, y, font, paint)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
output_file = output || "avatar_#{name.downcase.gsub(/\s+/, '_')}.png"
|
|
56
|
+
surface.save_png(output_file)
|
|
57
|
+
puts "Generated: #{output_file}"
|
|
58
|
+
output_file
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
names = [
|
|
62
|
+
'John Doe',
|
|
63
|
+
'Alice Smith',
|
|
64
|
+
'Bob Johnson',
|
|
65
|
+
'Emma Wilson',
|
|
66
|
+
'Michael Brown'
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
puts 'Generating avatars...'
|
|
70
|
+
names.each { |name| generate_avatar(name, size: 128) }
|
|
71
|
+
|
|
72
|
+
generate_avatar('Ruby Developer', size: 256, output: 'avatar_large.png')
|
|
73
|
+
|
|
74
|
+
puts "\nAll avatars generated!"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/skia'
|
|
5
|
+
|
|
6
|
+
data = {
|
|
7
|
+
'Maguro' => 92,
|
|
8
|
+
'Salmon' => 88,
|
|
9
|
+
'Ebi' => 75,
|
|
10
|
+
'Tamago' => 68,
|
|
11
|
+
'Ika' => 45
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
WIDTH = 600
|
|
15
|
+
HEIGHT = 400
|
|
16
|
+
MARGIN = { top: 40, right: 30, bottom: 60, left: 80 }.freeze
|
|
17
|
+
CHART_WIDTH = WIDTH - MARGIN[:left] - MARGIN[:right]
|
|
18
|
+
CHART_HEIGHT = HEIGHT - MARGIN[:top] - MARGIN[:bottom]
|
|
19
|
+
|
|
20
|
+
surface = Skia::Surface.make_raster(WIDTH, HEIGHT)
|
|
21
|
+
|
|
22
|
+
surface.draw do |canvas|
|
|
23
|
+
canvas.clear(Skia::Color::WHITE)
|
|
24
|
+
|
|
25
|
+
paint = Skia::Paint.new
|
|
26
|
+
paint.antialias = true
|
|
27
|
+
|
|
28
|
+
font_title = Skia::Font.new(nil, 20.0)
|
|
29
|
+
paint.color = Skia::Color::BLACK
|
|
30
|
+
canvas.draw_text('Sushi Popularity Ranking', 180, 28, font_title, paint)
|
|
31
|
+
|
|
32
|
+
font_axis = Skia::Font.new(nil, 12.0)
|
|
33
|
+
paint.style = :stroke
|
|
34
|
+
paint.stroke_width = 1
|
|
35
|
+
paint.color = Skia::Color.rgb(200, 200, 200)
|
|
36
|
+
|
|
37
|
+
max_value = 100
|
|
38
|
+
5.times do |i|
|
|
39
|
+
value = i * 25
|
|
40
|
+
y = MARGIN[:top] + CHART_HEIGHT - (value.to_f / max_value * CHART_HEIGHT)
|
|
41
|
+
|
|
42
|
+
canvas.draw_line(MARGIN[:left], y, WIDTH - MARGIN[:right], y, paint)
|
|
43
|
+
|
|
44
|
+
paint.style = :fill
|
|
45
|
+
paint.color = Skia::Color::BLACK
|
|
46
|
+
canvas.draw_text(value.to_s, MARGIN[:left] - 35, y + 4, font_axis, paint)
|
|
47
|
+
paint.style = :stroke
|
|
48
|
+
paint.color = Skia::Color.rgb(200, 200, 200)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
bar_width = CHART_WIDTH / data.size * 0.7
|
|
52
|
+
bar_spacing = CHART_WIDTH / data.size
|
|
53
|
+
|
|
54
|
+
colors = [
|
|
55
|
+
Skia::Color.rgb(220, 53, 69),
|
|
56
|
+
Skia::Color.rgb(255, 127, 80),
|
|
57
|
+
Skia::Color.rgb(255, 182, 193),
|
|
58
|
+
Skia::Color.rgb(255, 215, 0),
|
|
59
|
+
Skia::Color.rgb(230, 230, 250)
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
data.each_with_index do |(name, value), i|
|
|
63
|
+
x = MARGIN[:left] + (i * bar_spacing) + (bar_spacing - bar_width) / 2
|
|
64
|
+
bar_height = (value.to_f / max_value) * CHART_HEIGHT
|
|
65
|
+
y = MARGIN[:top] + CHART_HEIGHT - bar_height
|
|
66
|
+
|
|
67
|
+
paint.style = :fill
|
|
68
|
+
paint.color = colors[i]
|
|
69
|
+
canvas.draw_rect(Skia::Rect.from_xywh(x, y, bar_width, bar_height), paint)
|
|
70
|
+
|
|
71
|
+
paint.style = :stroke
|
|
72
|
+
paint.stroke_width = 1
|
|
73
|
+
paint.color = Skia::Color.rgb(100, 100, 100)
|
|
74
|
+
canvas.draw_rect(Skia::Rect.from_xywh(x, y, bar_width, bar_height), paint)
|
|
75
|
+
|
|
76
|
+
paint.style = :fill
|
|
77
|
+
paint.color = Skia::Color::BLACK
|
|
78
|
+
text_width, = font_axis.measure_text(name)
|
|
79
|
+
label_x = x + (bar_width - text_width) / 2
|
|
80
|
+
canvas.draw_text(name, label_x, HEIGHT - MARGIN[:bottom] + 20, font_axis, paint)
|
|
81
|
+
|
|
82
|
+
value_text = "#{value}%"
|
|
83
|
+
value_width, = font_axis.measure_text(value_text)
|
|
84
|
+
canvas.draw_text(value_text, x + (bar_width - value_width) / 2, y - 8, font_axis, paint)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
surface.save_png('bar_chart.png')
|
|
89
|
+
puts 'Saved to bar_chart.png'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/skia'
|
|
5
|
+
|
|
6
|
+
surface = Skia::Surface.make_raster(640, 480)
|
|
7
|
+
|
|
8
|
+
surface.draw do |canvas|
|
|
9
|
+
canvas.clear(Skia::Color::WHITE)
|
|
10
|
+
|
|
11
|
+
paint = Skia::Paint.new
|
|
12
|
+
paint.antialias = true
|
|
13
|
+
|
|
14
|
+
paint.color = Skia::Color::RED
|
|
15
|
+
paint.style = :fill
|
|
16
|
+
canvas.draw_rect(Skia::Rect.from_xywh(50, 50, 150, 100), paint)
|
|
17
|
+
|
|
18
|
+
paint.color = Skia::Color::BLUE
|
|
19
|
+
canvas.draw_circle(400, 200, 80, paint)
|
|
20
|
+
|
|
21
|
+
paint.color = Skia::Color::GREEN
|
|
22
|
+
paint.style = :stroke
|
|
23
|
+
paint.stroke_width = 3
|
|
24
|
+
canvas.draw_oval(Skia::Rect.from_xywh(200, 300, 200, 100), paint)
|
|
25
|
+
|
|
26
|
+
path = Skia::Path.build do
|
|
27
|
+
move_to 100, 300
|
|
28
|
+
line_to 200, 400
|
|
29
|
+
line_to 50, 400
|
|
30
|
+
close
|
|
31
|
+
end
|
|
32
|
+
paint.color = Skia::Color.rgb(255, 165, 0)
|
|
33
|
+
paint.style = :fill
|
|
34
|
+
canvas.draw_path(path, paint)
|
|
35
|
+
|
|
36
|
+
paint.color = Skia::Color::MAGENTA
|
|
37
|
+
paint.style = :stroke
|
|
38
|
+
paint.stroke_width = 2
|
|
39
|
+
canvas.draw_line(500, 50, 600, 150, paint)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
surface.save_png('output.png')
|
|
43
|
+
puts 'Saved to output.png'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/skia'
|
|
5
|
+
|
|
6
|
+
surface = Skia::Surface.make_raster(400, 400)
|
|
7
|
+
|
|
8
|
+
surface.draw do |canvas|
|
|
9
|
+
canvas.clear(Skia::Color::WHITE)
|
|
10
|
+
|
|
11
|
+
colors = [Skia::Color::RED, Skia::Color::YELLOW, Skia::Color::BLUE]
|
|
12
|
+
shader = Skia::Shader.linear_gradient(
|
|
13
|
+
Skia::Point.new(0, 0),
|
|
14
|
+
Skia::Point.new(400, 0),
|
|
15
|
+
colors
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
paint = Skia::Paint.new
|
|
19
|
+
paint.shader = shader
|
|
20
|
+
canvas.draw_rect(Skia::Rect.from_wh(400, 200), paint)
|
|
21
|
+
|
|
22
|
+
radial_shader = Skia::Shader.radial_gradient(
|
|
23
|
+
Skia::Point.new(200, 300),
|
|
24
|
+
100,
|
|
25
|
+
[Skia::Color::WHITE, Skia::Color::BLUE]
|
|
26
|
+
)
|
|
27
|
+
paint.shader = radial_shader
|
|
28
|
+
canvas.draw_circle(200, 300, 100, paint)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
surface.save_png('gradient.png')
|
|
32
|
+
puts 'Saved to gradient.png'
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/skia'
|
|
5
|
+
|
|
6
|
+
Skia::Document.create_pdf('output.pdf') do |doc|
|
|
7
|
+
doc.begin_page(612, 792) do |canvas|
|
|
8
|
+
canvas.clear(Skia::Color::WHITE)
|
|
9
|
+
|
|
10
|
+
font = Skia::Font.new(nil, 36.0)
|
|
11
|
+
paint = Skia::Paint.new
|
|
12
|
+
paint.antialias = true
|
|
13
|
+
paint.color = Skia::Color::BLACK
|
|
14
|
+
|
|
15
|
+
canvas.draw_text('Hello, PDF!', 50, 100, font, paint)
|
|
16
|
+
|
|
17
|
+
paint.color = Skia::Color::RED
|
|
18
|
+
paint.style = :fill
|
|
19
|
+
canvas.draw_rect(Skia::Rect.from_xywh(50, 150, 200, 100), paint)
|
|
20
|
+
|
|
21
|
+
paint.color = Skia::Color::BLUE
|
|
22
|
+
canvas.draw_circle(400, 300, 80, paint)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
doc.begin_page(612, 792) do |canvas|
|
|
26
|
+
canvas.clear(Skia::Color::WHITE)
|
|
27
|
+
|
|
28
|
+
font = Skia::Font.new(nil, 24.0)
|
|
29
|
+
paint = Skia::Paint.new
|
|
30
|
+
paint.antialias = true
|
|
31
|
+
paint.color = Skia::Color::BLACK
|
|
32
|
+
|
|
33
|
+
canvas.draw_text('Page 2', 50, 100, font, paint)
|
|
34
|
+
|
|
35
|
+
path = Skia::Path.build do
|
|
36
|
+
move_to 100, 200
|
|
37
|
+
line_to 200, 400
|
|
38
|
+
line_to 50, 400
|
|
39
|
+
close
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
paint.color = Skia::Color::GREEN
|
|
43
|
+
paint.style = :fill
|
|
44
|
+
canvas.draw_path(path, paint)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
puts 'Saved to output.pdf'
|