skrift-x11 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +32 -0
- data/Rakefile +4 -0
- data/example.png +0 -0
- data/example.rb +85 -0
- data/lib/skrift/x11/glyphs.rb +129 -0
- data/lib/skrift/x11/version.rb +7 -0
- data/lib/skrift/x11.rb +10 -0
- data/resources/FiraGO-Regular_extended_with_NotoSansEgyptianHieroglyphs-Regular.ttf +0 -0
- data/sig/skrift/x11.rbs +6 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a086ab34c955c628b9b32640d98e26415a2e6766e9a784797893b6c8ef7473b0
|
4
|
+
data.tar.gz: 89a0ea4e3ee0cf221037e6c951d746c63f00140dd775f1b332cb0d7afdc52c67
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8cf85e533b7d29eb13e993842a83a09bd3eaf7322fe41d93d5290637788d5bd944a90dd96f3f21f618edf2d03998f9667f7c403621470622fd552d72f6d039be
|
7
|
+
data.tar.gz: e07c349839802875a8d73f13a0dd2daa3beb76c12f52677f34a7a5f5bdd76aab8acdb38dc5c5c59e5612aad1ae2716ba7ffe223a86b4ca63eebae5fde1eae21d
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 Vidar Hokstad
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Skrift::X11
|
2
|
+
|
3
|
+
Skrift::X11 is a binding for the pure-Ruby pure-x11 gem for the pure-
|
4
|
+
Ruby [Skrift TrueType engine](https://github.com/vidarh/skrift)
|
5
|
+
|
6
|
+
It can produce output like this (see `example.rb`):
|
7
|
+
|
8
|
+
![Example image](https://raw.githubusercontent.com/vidarh/skrift-x11/master/example.png)
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install the gem and add to the application's Gemfile by executing:
|
14
|
+
|
15
|
+
$ bundle add skrift-x11
|
16
|
+
|
17
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
18
|
+
|
19
|
+
$ gem install skrift-x11
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
See `example.rb`
|
24
|
+
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/vidarh/skrift-x11.
|
29
|
+
|
30
|
+
## License
|
31
|
+
|
32
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/example.png
ADDED
Binary file
|
data/example.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#require 'rubygems'
|
2
|
+
require 'skrift'
|
3
|
+
require 'X11'
|
4
|
+
require 'bundler'
|
5
|
+
require 'chunky_png'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
Bundler.setup(:default, :development)
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
12
|
+
|
13
|
+
require 'skrift/x11'
|
14
|
+
|
15
|
+
$dpy = dpy = display = X11::Display.new
|
16
|
+
screen = dpy.screens.first
|
17
|
+
|
18
|
+
# Transparency: Check
|
19
|
+
# https://stackoverflow.com/questions/13395179/empty-or-transparent-window-with-xlib-showing-border-lines-only/13397150#13397150
|
20
|
+
|
21
|
+
# FIXME: Hack; see XFindVisualMatch
|
22
|
+
visual = 123
|
23
|
+
|
24
|
+
cmap = $dpy.create_colormap(0, screen.root, visual)
|
25
|
+
|
26
|
+
wid = display.new_id
|
27
|
+
$dpy.create_window(
|
28
|
+
32,
|
29
|
+
wid, screen.root,
|
30
|
+
0, 0, # x,y
|
31
|
+
1000, 600, # w,h
|
32
|
+
0,
|
33
|
+
X11::Form::InputOutput,
|
34
|
+
visual, #X11::Form::CopyFromParent -- Must be provided if e.g. depth is different than root.
|
35
|
+
X11::Form::CWBackPixel | X11::Form::CWBorderPixel |
|
36
|
+
X11::Form::CWEventMask | X11::Form::CWColorMap,
|
37
|
+
[0x00000000, # ARGB background
|
38
|
+
0x0, # Border pixel; Necessary when depth != screen.root_depth
|
39
|
+
X11::Form::SubstructureNotifyMask |
|
40
|
+
X11::Form::StructureNotifyMask | ## Move
|
41
|
+
X11::Form::ExposureMask |
|
42
|
+
X11::Form::KeyPressMask |
|
43
|
+
X11::Form::ButtonPressMask,
|
44
|
+
cmap # Colormap. Necessary when depth != screen.root_depth
|
45
|
+
]
|
46
|
+
)
|
47
|
+
|
48
|
+
dpy.map_window(wid) # Window won't be visible until this
|
49
|
+
|
50
|
+
# A "picture" object for us to draw in the window with.
|
51
|
+
fmt = dpy.render_find_visual_format(visual)
|
52
|
+
$pic = dpy.render_create_picture(wid, fmt)
|
53
|
+
|
54
|
+
# The easy way
|
55
|
+
#$fgpic = dpy.render_create_solid_fill(0xffff,0xffff,0,0)
|
56
|
+
|
57
|
+
|
58
|
+
$gc = dpy.create_gc(wid, foreground: 0xffff0000)
|
59
|
+
|
60
|
+
puts "Main loop"
|
61
|
+
|
62
|
+
$f = Font.load("resources/FiraGO-Regular_extended_with_NotoSansEgyptianHieroglyphs-Regular.ttf")
|
63
|
+
|
64
|
+
$skrift = Skrift::X11::Glyphs.new($dpy, $f, x_scale: 40, y_scale: 40)
|
65
|
+
|
66
|
+
def redraw(dpy, wid, gc)
|
67
|
+
dpy.poly_fill_rectangle(wid, gc, [X11::Form::Rectangle.new(20,45, 400, 400)])
|
68
|
+
$skrift.render_str($pic, 0xffffff, 50,90, 'Pure Ruby w/Skrift!')
|
69
|
+
$skrift.render_str($pic, 0xffffff, 50,140, "And unicode:")
|
70
|
+
$skrift.render_str($pic, 0xff00ff, 50,200, "Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.")
|
71
|
+
$skrift.render_str($pic, 0x00ffff, 50,250, "Я можу їсти шкло, й воно мені не пошкодить.")
|
72
|
+
end
|
73
|
+
|
74
|
+
loop do
|
75
|
+
pkt = display.next_packet
|
76
|
+
if pkt
|
77
|
+
#puts pkt.inspect[0..200]
|
78
|
+
#raise "Error" if pkt.is_a?(X11::Form::Error)
|
79
|
+
redraw(display, wid, $gc) if pkt.is_a?(X11::Form::Expose)
|
80
|
+
|
81
|
+
if pkt.is_a?(X11::Form::KeyPress)
|
82
|
+
# lookup_keysym(dpy,pkt)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
|
2
|
+
require 'skrift'
|
3
|
+
module Skrift
|
4
|
+
module X11
|
5
|
+
# XRender constants currently not defined in pure-x11.
|
6
|
+
# FIXME.
|
7
|
+
PictOpSrc=1
|
8
|
+
PictOpOver=3
|
9
|
+
CPRepeat = 1
|
10
|
+
|
11
|
+
class Glyphs
|
12
|
+
|
13
|
+
def initialize dpy, font, x_scale:, y_scale:, pic: nil, fixed: nil
|
14
|
+
@dpy = dpy
|
15
|
+
@sft = SFT.new(font)
|
16
|
+
@sft.x_scale = x_scale
|
17
|
+
@sft.y_scale = y_scale
|
18
|
+
@pic = pic
|
19
|
+
@fixed = fixed
|
20
|
+
|
21
|
+
@glyphcache = {}
|
22
|
+
@colcache = {}
|
23
|
+
|
24
|
+
@lm = @sft.lmetrics
|
25
|
+
|
26
|
+
# The glyph set
|
27
|
+
@gfmt = @dpy.render_find_standard_format(:a8).id
|
28
|
+
@glyphset = @dpy.render_create_glyph_set(@gfmt)
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_accessor :lm
|
32
|
+
def gm(ch)
|
33
|
+
gid = @sft.lookup(ch.ord)
|
34
|
+
@sft.gmetrics(gid)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def fill_for_col(col)
|
39
|
+
return @colcache[col] if @colcache[col]
|
40
|
+
r = col >> 16
|
41
|
+
r |= r << 8
|
42
|
+
g = (col >> 8) & 0xff
|
43
|
+
g |= g << 8
|
44
|
+
b = col & 0xff
|
45
|
+
b |= b << 8
|
46
|
+
|
47
|
+
@colcache[col] ||= @dpy.render_create_solid_fill(r,g,b,0xffff)
|
48
|
+
end
|
49
|
+
|
50
|
+
def fixed_width
|
51
|
+
return @fixed_width if @fixed_width
|
52
|
+
if @fixed
|
53
|
+
# *Ensure* that the glyphs are equal width.
|
54
|
+
g = gm("M")
|
55
|
+
@fixed_width = g.advance_width.ceil
|
56
|
+
else
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def cache_glyph(gid, baseline)
|
63
|
+
mtx = @sft.gmetrics(gid)
|
64
|
+
|
65
|
+
# FIXME: Not sure what to do if mtx.nil? here.
|
66
|
+
# Maybe use x/y scale?
|
67
|
+
w = fixed_width || mtx.min_width || 0
|
68
|
+
h = mtx.min_height || 1
|
69
|
+
#p [w,h]
|
70
|
+
img = Image.new((w+3)&~3, h)
|
71
|
+
if !@sft.render(gid, img)
|
72
|
+
#STDERR.puts "Unable to render #{gid}\n"
|
73
|
+
data = "\0"*(w*h)
|
74
|
+
else
|
75
|
+
data = img.pixels.pack("C*")
|
76
|
+
end
|
77
|
+
|
78
|
+
yoff = mtx.y_offset || baseline
|
79
|
+
|
80
|
+
info = ::X11::Form::GlyphInfo.new(
|
81
|
+
img.width, # w
|
82
|
+
img.height, # h
|
83
|
+
-mtx.left_side_bearing, # x
|
84
|
+
yoff-baseline, # y
|
85
|
+
fixed_width || mtx.advance_width, # || mtx.advance_width, # x_off
|
86
|
+
0
|
87
|
+
)
|
88
|
+
|
89
|
+
@dpy.render_add_glyphs(@glyphset, gid, info, data)
|
90
|
+
@glyphcache[gid] = mtx.advance_width#-mtx.left_side_bearing
|
91
|
+
end
|
92
|
+
|
93
|
+
def text_width(str)
|
94
|
+
gl = map_glyphs(str)
|
95
|
+
# We *presume* that if you call text_width, you intend
|
96
|
+
# to render the string. Maybe we shouldn't?
|
97
|
+
cache_glyphs(gl)
|
98
|
+
gl.inject(0) {|sum,gl|
|
99
|
+
@glyphcache[gl].to_i + sum
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def map_glyphs(str)
|
104
|
+
# FIXME: Should probably cache by character rather than
|
105
|
+
# glyph
|
106
|
+
str.to_s.each_char.map { |ch| @sft.lookup(ch.ord) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def cache_glyphs(gl)
|
110
|
+
gl.each do |gid|
|
111
|
+
data = @glyphcache[gid]
|
112
|
+
if !data
|
113
|
+
data = cache_glyph(gid, @lm.ascender)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def render_str(pic, col, x,y, str)
|
119
|
+
fill = fill_for_col(col)
|
120
|
+
gl = map_glyphs(str)
|
121
|
+
cache_glyphs(gl)
|
122
|
+
@dpy.render_composite_glyphs32(
|
123
|
+
PictOpOver, fill, pic, @gfmt,
|
124
|
+
@glyphset, 0,0, [x, y, gl]
|
125
|
+
)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/skrift/x11.rb
ADDED
Binary file
|
data/sig/skrift/x11.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: skrift-x11
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vidar Hokstad
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-09-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: skrift
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pure-x11
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- vidar@hokstad.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- LICENSE.txt
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- example.png
|
52
|
+
- example.rb
|
53
|
+
- lib/skrift/x11.rb
|
54
|
+
- lib/skrift/x11/glyphs.rb
|
55
|
+
- lib/skrift/x11/version.rb
|
56
|
+
- resources/FiraGO-Regular_extended_with_NotoSansEgyptianHieroglyphs-Regular.ttf
|
57
|
+
- sig/skrift/x11.rbs
|
58
|
+
homepage:
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 2.6.0
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubygems_version: 3.4.10
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Helpers to use the pure-Ruvy TrueType engine Skrift with pure Pure-X11 X
|
81
|
+
bindings
|
82
|
+
test_files: []
|