tui-td 0.2.6 → 0.2.8

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: 2716bc85090a6430068ad8820f9736657a3f122571999e34c39529060f59d487
4
- data.tar.gz: b73ff229c0396a87a5121b43ff81edf65be1f13de1aed58a7404cd263a0ba84e
3
+ metadata.gz: ebeda13c1510dfd65ec0dd5e45a330ed9100c3dd5a0919dfcedb13340e01a280
4
+ data.tar.gz: fe33d4368ae7b516f18b7cc30974124408214dbd116f6e300986b05a967e4835
5
5
  SHA512:
6
- metadata.gz: be25c3cfca1b280dacc7a2b968c887de55fce953e1c9903dd725d1291b34918375771eec7324522407ef783c2fc9010f0ef69b2e7c5fccc142bf6b2bd1396f40
7
- data.tar.gz: 0ee80ad5882c21763241f39c781a03a30180baf04707f7af5652bd913254b69c647efa59b06c57ff534b8b797a188adfaf40068f37956cad08b33a4cbc28cae0
6
+ metadata.gz: f1c7051f157319f46d96f371654d276ada570e2aea06d4871659cf989734f5c3d65c0da163a23d56ebb844d3c3cb3b5087b6fcc60f8dcebfdbec0d35ab317720
7
+ data.tar.gz: 2f74615955a3434efe4d06427099ae18eca2c43bdefe93b6c8b2465ebb2eb28f84024ecbcfcbda39cedec4e5ac0373141d6f6ec0ac31aff6a64f7cf8b9ebb781
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.2.7
4
+
5
+ - Screenshot rendering for 23 special characters: blocks (▀ ▄ █), triangles (▲ ▼), arrows (↑ ↓ → ←), half blocks (▌ ▐)
6
+ - Screenshot rendering for symbols: checkmarks (✓ ✗ ✖), checkboxes (☐ ☑ ☒), gear (⚙), warning (⚠), info (ℹ)
7
+ - Screenshot rendering for punctuation: ellipsis (…), em dash (—)
8
+ - Cursor drawing support in screenshot renderer
9
+ - Braille character rendering in screenshot
10
+ - Rounded corner box-drawing characters (╭ ╮ ╯ ╰) in screenshot
11
+ - `page_up` / `page_down` key support in test runner and driver
12
+ - Fixed junction pixels in rounded corner box-drawing characters
13
+
3
14
  ## 0.2.6
4
15
 
5
16
  - ISO-2022 charset switching support (G0/G1 designators, Shift Out/In) with DEC Special Character & Line Drawing mapping
data/README.md CHANGED
@@ -417,10 +417,14 @@ Top-level structure returned by `state_data` / `--json`:
417
417
 
418
418
  ```json
419
419
  {
420
- "size": {"rows": 40, "cols": 120},
421
- "cursor": {"row": 5, "col": 12},
422
- "rows": [[{"char": "A", "fg": "cyan", ...}]],
423
- "raw": "\e[31mred\e[0m\n..."
420
+ "size": {"rows": 40, "cols": 120},
421
+ "cursor": {"row": 5, "col": 12},
422
+ "cursor_visible": true,
423
+ "cursor_style": "block",
424
+ "mouse_mode": null,
425
+ "mouse_format": null,
426
+ "rows": [[{"char": "A", "fg": "cyan", ...}]],
427
+ "raw": "\e[31mred\e[0m\n..."
424
428
  }
425
429
  ```
426
430
 
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TUITD
4
+ module CairoRenderer
5
+ CELL_W = 8
6
+ CELL_H = 16
7
+ DEFAULT_FONT = "Arial Unicode MS"
8
+ FONT_SIZE = 12.0
9
+ RENDER_SCALE = 3
10
+
11
+ @available = false
12
+ @cache = {}
13
+
14
+ begin
15
+ require "cairo"
16
+ @available = true
17
+ rescue LoadError
18
+ # Cairo not available; render_glyph_onto is a no-op
19
+ end
20
+
21
+ class << self
22
+ def available?
23
+ @available
24
+ end
25
+
26
+ def render_glyph_onto(cpn_image, px, py, char, fg_rgb, bold:, italic:)
27
+ return unless available?
28
+
29
+ alpha = glyph_alpha(char, bold: bold, italic: italic)
30
+ composite(alpha, cpn_image, px, py, fg_rgb)
31
+ rescue StandardError => e
32
+ warn "CairoRenderer: #{e.message}" if $DEBUG
33
+ end
34
+
35
+ private
36
+
37
+ def glyph_alpha(char, bold:, italic:)
38
+ key = [char.ord, bold, italic]
39
+ @cache[key] ||= render_surface(char, bold, italic)
40
+ end
41
+
42
+ def render_surface(char, bold, italic)
43
+ # Render at higher resolution then box-filter downsample for smoother edges
44
+ scale = RENDER_SCALE
45
+ big_w = CELL_W * scale
46
+ big_h = CELL_H * scale
47
+ surface = Cairo::ImageSurface.new(Cairo::Format::ARGB32, big_w, big_h)
48
+ context = Cairo::Context.new(surface)
49
+
50
+ context.antialias = Cairo::ANTIALIAS_NONE
51
+
52
+ fo = Cairo::FontOptions.new
53
+ fo.hint_style = Cairo::HINT_STYLE_FULL
54
+ fo.hint_metrics = Cairo::HINT_METRICS_ON
55
+ context.font_options = fo
56
+
57
+ slant = italic ? Cairo::FONT_SLANT_ITALIC : Cairo::FONT_SLANT_NORMAL
58
+ weight = bold ? Cairo::FONT_WEIGHT_BOLD : Cairo::FONT_WEIGHT_NORMAL
59
+ context.select_font_face(DEFAULT_FONT, slant, weight)
60
+ context.set_font_size(FONT_SIZE * scale)
61
+
62
+ extents = context.text_extents(char)
63
+ x_off = ((big_w - extents.width) / 2.0) - extents.x_bearing
64
+ y_off = ((big_h - extents.height) / 2.0) - extents.y_bearing
65
+
66
+ context.set_source_rgba(1.0, 1.0, 1.0, 1.0)
67
+ context.move_to(x_off, y_off)
68
+ context.show_text(char)
69
+
70
+ data = surface.data
71
+ stride = surface.stride
72
+ scale_sq = scale * scale
73
+
74
+ alpha_grid = Array.new(CELL_H) { Array.new(CELL_W, 0) }
75
+ CELL_H.times do |dy|
76
+ CELL_W.times do |dx|
77
+ sum = 0
78
+ scale.times do |sy|
79
+ row_off = (dy * scale + sy) * stride
80
+ scale.times do |sx|
81
+ sum += data.getbyte(row_off + (dx * scale + sx) * 4 + 3)
82
+ end
83
+ end
84
+ alpha_grid[dy][dx] = sum / scale_sq
85
+ end
86
+ end
87
+
88
+ alpha_grid
89
+ end
90
+
91
+ def composite(alpha_grid, cpn_image, px, py, fg_rgb)
92
+ fr, fg, fb = fg_rgb
93
+
94
+ CELL_H.times do |dy|
95
+ CELL_W.times do |dx|
96
+ a = alpha_grid[dy][dx]
97
+ next if a < 24
98
+
99
+ factor = [a, 255].min / 255.0
100
+ r = (fr * factor).to_i
101
+ g = (fg * factor).to_i
102
+ b = (fb * factor).to_i
103
+ cpn_image[px + dx, py + dy] = ChunkyPNG::Color.rgb(r, g, b)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
data/lib/tui_td/driver.rb CHANGED
@@ -77,6 +77,8 @@ module TUITD
77
77
  when :backspace then send("\u007f")
78
78
  when :ctrl_c then send("\u0003")
79
79
  when :ctrl_d then send("\u0004")
80
+ when :page_up then send("\e[5~")
81
+ when :page_down then send("\e[6~")
80
82
  else send(keys.to_s)
81
83
  end
82
84
  end