ruby-bitmap-fonts 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/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +77 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/fixtures/ter-u12b.bdf +23608 -0
- data/fixtures/ter-u20b.bdf +83 -0
- data/lib/bdf.rb +5 -0
- data/lib/bdf/canvas.rb +44 -0
- data/lib/bdf/char.rb +51 -0
- data/lib/bdf/font.rb +141 -0
- data/lib/bdf/renderer.rb +22 -0
- data/lib/bdf/version.rb +3 -0
- data/ruby-bitmap-fonts.gemspec +27 -0
- metadata +116 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
STARTFONT 2.1
|
2
|
+
COMMENT ter-u20b
|
3
|
+
FONT -xos4-Terminus-Bold-R-Normal--20-200-72-72-C-100-ISO10646-1
|
4
|
+
SIZE 20 72 72
|
5
|
+
FONTBOUNDINGBOX 10 20 0 -4
|
6
|
+
STARTPROPERTIES 20
|
7
|
+
FAMILY_NAME "Terminus"
|
8
|
+
FOUNDRY "xos4"
|
9
|
+
SETWIDTH_NAME "Normal"
|
10
|
+
ADD_STYLE_NAME ""
|
11
|
+
COPYRIGHT "Copyright (C) 2015 Dimitar Toshkov Zhekov - Modified for testing purposes by Markus Fenske"
|
12
|
+
NOTICE "Licensed under the SIL Open Font License, Version 1.1"
|
13
|
+
WEIGHT_NAME "Bold"
|
14
|
+
SLANT "R"
|
15
|
+
PIXEL_SIZE 20
|
16
|
+
POINT_SIZE 200
|
17
|
+
RESOLUTION_X 72
|
18
|
+
RESOLUTION_Y 72
|
19
|
+
SPACING "C"
|
20
|
+
AVERAGE_WIDTH 100
|
21
|
+
CHARSET_REGISTRY "ISO10646"
|
22
|
+
CHARSET_ENCODING "1"
|
23
|
+
MIN_SPACE 10
|
24
|
+
FONT_ASCENT 16
|
25
|
+
FONT_DESCENT 4
|
26
|
+
DEFAULT_CHAR 65533
|
27
|
+
ENDPROPERTIES
|
28
|
+
CHARS 2
|
29
|
+
STARTCHAR exclam
|
30
|
+
ENCODING 33
|
31
|
+
SWIDTH 500 0
|
32
|
+
DWIDTH 10 0
|
33
|
+
BBX 10 20 0 -4
|
34
|
+
BITMAP
|
35
|
+
0000
|
36
|
+
0000
|
37
|
+
0000
|
38
|
+
0C00
|
39
|
+
0C00
|
40
|
+
0C00
|
41
|
+
0C00
|
42
|
+
0C00
|
43
|
+
0C00
|
44
|
+
0C00
|
45
|
+
0C00
|
46
|
+
0C00
|
47
|
+
0000
|
48
|
+
0000
|
49
|
+
0C00
|
50
|
+
0C00
|
51
|
+
0000
|
52
|
+
0000
|
53
|
+
0000
|
54
|
+
0000
|
55
|
+
ENDCHAR
|
56
|
+
STARTCHAR X
|
57
|
+
ENCODING 88
|
58
|
+
SWIDTH 500 0
|
59
|
+
DWIDTH 10 0
|
60
|
+
BBX 10 20 0 -4
|
61
|
+
BITMAP
|
62
|
+
0000
|
63
|
+
0000
|
64
|
+
0000
|
65
|
+
6180
|
66
|
+
6180
|
67
|
+
6180
|
68
|
+
3300
|
69
|
+
3300
|
70
|
+
1E00
|
71
|
+
0C00
|
72
|
+
1E00
|
73
|
+
3300
|
74
|
+
3300
|
75
|
+
6180
|
76
|
+
6180
|
77
|
+
6180
|
78
|
+
0000
|
79
|
+
0000
|
80
|
+
0000
|
81
|
+
0000
|
82
|
+
ENDCHAR
|
83
|
+
ENDFONT
|
data/lib/bdf.rb
ADDED
data/lib/bdf/canvas.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module BDF
|
2
|
+
class Canvas
|
3
|
+
def initialize(width, height)
|
4
|
+
@width = width
|
5
|
+
@height = height
|
6
|
+
@array = Array.new(height){Array.new(width, 0)}
|
7
|
+
end
|
8
|
+
|
9
|
+
def set(x, y)
|
10
|
+
unless x < @width && y < @height
|
11
|
+
# TODO: Maybe resize to other size to improve speed.
|
12
|
+
resize(x+1, y+1)
|
13
|
+
end
|
14
|
+
|
15
|
+
@array[y][x] = 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def resize(width, height)
|
19
|
+
@array.map! do |line|
|
20
|
+
if width > line.size
|
21
|
+
line + [0]*(width - line.size)
|
22
|
+
else
|
23
|
+
line
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@width = width
|
28
|
+
|
29
|
+
if height > @array.size
|
30
|
+
# This is a loop, because the multiplication op on arrays does not work
|
31
|
+
# with non-scalars. You have been warned.
|
32
|
+
(height - @array.size).times do
|
33
|
+
@array += [[0]*@width]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@height = height
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_a
|
41
|
+
@array.dup
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/bdf/char.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module BDF
|
2
|
+
class Char
|
3
|
+
def initialize(opts = {})
|
4
|
+
@encoding = opts[:encoding]
|
5
|
+
@swidth = opts[:swidth]
|
6
|
+
@dwidth = opts[:dwidth]
|
7
|
+
@bbx = opts[:bbx]
|
8
|
+
@bitmap = parse(opts[:bitmap])
|
9
|
+
end
|
10
|
+
|
11
|
+
def render(canvas, cursor)
|
12
|
+
@bitmap.each_with_index do |line, y|
|
13
|
+
line.each_with_index do |val, x|
|
14
|
+
if val == 1
|
15
|
+
canvas.set(x+cursor[0]+@bbx[:off_x], y+cursor[1]+@bbx[:off_y])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
[cursor[0]+@dwidth[:x], cursor[1]+@dwidth[:y]]
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def parse(bitmap)
|
25
|
+
lookup = {
|
26
|
+
"0" => [0, 0, 0, 0],
|
27
|
+
"1" => [0, 0, 0, 1],
|
28
|
+
"2" => [0, 0, 1, 0],
|
29
|
+
"3" => [0, 0, 1, 1],
|
30
|
+
"4" => [0, 1, 0, 0],
|
31
|
+
"5" => [0, 1, 0, 1],
|
32
|
+
"6" => [0, 1, 1, 0],
|
33
|
+
"7" => [0, 1, 1, 1],
|
34
|
+
"8" => [1, 0, 0, 0],
|
35
|
+
"9" => [1, 0, 0, 1],
|
36
|
+
"A" => [1, 0, 1, 0],
|
37
|
+
"B" => [1, 0, 1, 1],
|
38
|
+
"C" => [1, 1, 0, 0],
|
39
|
+
"D" => [1, 1, 0, 1],
|
40
|
+
"E" => [1, 1, 1, 0],
|
41
|
+
"F" => [1, 1, 1, 1]
|
42
|
+
}
|
43
|
+
|
44
|
+
bitmap = bitmap.each.map do |line|
|
45
|
+
line.chars.map do |char|
|
46
|
+
lookup.fetch(char)
|
47
|
+
end.flatten[0...@bbx[:w]] # Shorten to bounding box width
|
48
|
+
end[0...@bbx[:h]] # Shorten to bounding box height
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/bdf/font.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
module BDF
|
2
|
+
class Font
|
3
|
+
class ParseError < Exception; end
|
4
|
+
|
5
|
+
def self.from_file(filename)
|
6
|
+
self.new(filename)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(filename)
|
10
|
+
@file = File.open(filename)
|
11
|
+
parse
|
12
|
+
end
|
13
|
+
|
14
|
+
def char(name)
|
15
|
+
Char.new(@chars[name])
|
16
|
+
end
|
17
|
+
|
18
|
+
def glyph(char)
|
19
|
+
# TODO: We could use a glyph list here to get the name from unicode point
|
20
|
+
name, _ = @chars.find do |name, char_|
|
21
|
+
char_[:encoding] == char.ord
|
22
|
+
end
|
23
|
+
char(name)
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :version, :name, :size, :x_resolution, :y_resolution,
|
27
|
+
:bounding_box_x, :bounding_box_y, :displacement_x, :displacement_y,
|
28
|
+
:properties
|
29
|
+
|
30
|
+
private
|
31
|
+
# Specification:
|
32
|
+
# https://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5005.BDF_Spec.pdf
|
33
|
+
def parse
|
34
|
+
@state = :start
|
35
|
+
|
36
|
+
@file.each_line.each_with_index do |line, line_no|
|
37
|
+
case @state
|
38
|
+
when :start
|
39
|
+
case line
|
40
|
+
when /^STARTFONT (.*)$/
|
41
|
+
@version = $1
|
42
|
+
@state = :body
|
43
|
+
else
|
44
|
+
raise ParseError, "Expected 'STARTFONT' command"
|
45
|
+
end
|
46
|
+
when :body
|
47
|
+
case line
|
48
|
+
when /^COMMENT /
|
49
|
+
# Ignore
|
50
|
+
when /^FONT (.*)$/
|
51
|
+
@name = $1
|
52
|
+
when /^SIZE (\d+) (\d+) (\d+)$/
|
53
|
+
@size = $1.to_i
|
54
|
+
@x_resolution = $2.to_i
|
55
|
+
@y_resolution = $3.to_i
|
56
|
+
when /^FONTBOUNDINGBOX (-?\d+) (-?\d+) (-?\d+) (-?\d+)$/
|
57
|
+
@bounding_box_x = $1.to_i
|
58
|
+
@bounding_box_y = $2.to_i
|
59
|
+
@displacement_x = $3.to_i
|
60
|
+
@displacement_y = $4.to_i
|
61
|
+
when /^STARTPROPERTIES (\d+)$/
|
62
|
+
@state = :properties
|
63
|
+
@properties_count = $1.to_i
|
64
|
+
when /^CHARS (\d+)$/
|
65
|
+
@chars_count = $1.to_i
|
66
|
+
when /^STARTCHAR (.+)$/
|
67
|
+
@current_glyph_name = $1
|
68
|
+
@state = :char
|
69
|
+
when /^ENDFONT$/
|
70
|
+
if @chars.size != @chars_count
|
71
|
+
raise ParseError, "Expected #{@chars_count} chars, but got #{@chars.size}"
|
72
|
+
end
|
73
|
+
@state = :end
|
74
|
+
else
|
75
|
+
raise ParseError, "Unknown error in line #{line_no+1}: #{line}"
|
76
|
+
end
|
77
|
+
when :properties
|
78
|
+
case line
|
79
|
+
when /^ENDPROPERTIES$/
|
80
|
+
@state = :body
|
81
|
+
# They lied :(
|
82
|
+
if @properties.size != @properties_count
|
83
|
+
raise ParseError, "Expected #{@properties_count} properties, but got #{@properties.size}"
|
84
|
+
end
|
85
|
+
else
|
86
|
+
@properties ||= {}
|
87
|
+
key, value = line.split(" ", 2)
|
88
|
+
@properties[key] = parse_value(value)
|
89
|
+
end
|
90
|
+
when :char
|
91
|
+
@chars ||= {}
|
92
|
+
@chars[@current_glyph_name] ||= {}
|
93
|
+
|
94
|
+
case line
|
95
|
+
when /^ENCODING (\d+)$/
|
96
|
+
@chars[@current_glyph_name][:encoding] = $1.to_i
|
97
|
+
when /^SWIDTH (\d+) (\d+)$/
|
98
|
+
@chars[@current_glyph_name][:swidth] = {:x => $1.to_i, :y => $2.to_i}
|
99
|
+
when /^DWIDTH (\d+) (\d+)$/
|
100
|
+
@chars[@current_glyph_name][:dwidth] = {:x => $1.to_i, :y => $2.to_i}
|
101
|
+
when /^BBX (-?\d+) (-?\d+) (-?\d+) (-?\d+)$/
|
102
|
+
@chars[@current_glyph_name][:bbx] = {:w => $1.to_i, :h => $2.to_i, :off_x => $3.to_i, :off_y => $4.to_i}
|
103
|
+
when /^BITMAP$/
|
104
|
+
@state = :bitmap
|
105
|
+
else
|
106
|
+
raise ParseError, "Unknown error in line #{line_no+1}: #{line}"
|
107
|
+
end
|
108
|
+
when :bitmap
|
109
|
+
case line
|
110
|
+
when /^([A-F0-9]+)$/
|
111
|
+
@chars[@current_glyph_name][:bitmap] ||= []
|
112
|
+
@chars[@current_glyph_name][:bitmap] << $1
|
113
|
+
when /^ENDCHAR$/
|
114
|
+
@chars[@current_glyph_name][:bitmap] = parse_bitmap(@chars[@current_glyph_name][:bitmap])
|
115
|
+
@state = :body
|
116
|
+
else
|
117
|
+
raise ParseError, "Expected bitmap or ENDCHAR line #{line_no+1}: #{line}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
if @state != :end
|
123
|
+
raise ParseError, "Premature EOF"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def parse_bitmap(bitmap)
|
128
|
+
# FIXME
|
129
|
+
bitmap
|
130
|
+
end
|
131
|
+
|
132
|
+
def parse_value(value)
|
133
|
+
# That's not correct parsing, but it will work for most things.
|
134
|
+
if value[0] == "\""
|
135
|
+
value[1...-2].gsub('""','"')
|
136
|
+
else
|
137
|
+
value.to_i
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/bdf/renderer.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module BDF
|
2
|
+
class Renderer
|
3
|
+
def self.render(text, opts = {})
|
4
|
+
font = opts[:font]
|
5
|
+
|
6
|
+
# Get baseline for initial cursor
|
7
|
+
cursor = [0, -font.displacement_y]
|
8
|
+
|
9
|
+
# Initial size of one char. resizes automatically
|
10
|
+
canvas = Canvas.new(font.bounding_box_x, font.bounding_box_y)
|
11
|
+
|
12
|
+
text.chars.each do |char|
|
13
|
+
# Lookup glyph
|
14
|
+
glyph = font.glyph(char)
|
15
|
+
|
16
|
+
cursor = glyph.render(canvas, cursor)
|
17
|
+
end
|
18
|
+
|
19
|
+
canvas
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/bdf/version.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bdf.rb'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ruby-bitmap-fonts"
|
8
|
+
spec.version = BDF::VERSION
|
9
|
+
spec.authors = ["Markus Fenske"]
|
10
|
+
spec.email = ["iblue@gmx.net"]
|
11
|
+
|
12
|
+
spec.summary = %q{A BDF (Glyph Bitmap Distribution Format) renderer}
|
13
|
+
spec.description = %q{This gem allows you to render bitmap fonts in the BDF format}
|
14
|
+
spec.homepage = "https://github.com/iblue/ruby-bitmap-fonts"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
26
|
+
spec.add_development_dependency "byebug"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-bitmap-fonts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Markus Fenske
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-02-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: This gem allows you to render bitmap fonts in the BDF format
|
70
|
+
email:
|
71
|
+
- iblue@gmx.net
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
79
|
+
- Gemfile
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/console
|
83
|
+
- bin/setup
|
84
|
+
- fixtures/ter-u12b.bdf
|
85
|
+
- fixtures/ter-u20b.bdf
|
86
|
+
- lib/bdf.rb
|
87
|
+
- lib/bdf/canvas.rb
|
88
|
+
- lib/bdf/char.rb
|
89
|
+
- lib/bdf/font.rb
|
90
|
+
- lib/bdf/renderer.rb
|
91
|
+
- lib/bdf/version.rb
|
92
|
+
- ruby-bitmap-fonts.gemspec
|
93
|
+
homepage: https://github.com/iblue/ruby-bitmap-fonts
|
94
|
+
licenses: []
|
95
|
+
metadata: {}
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 2.6.10
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: A BDF (Glyph Bitmap Distribution Format) renderer
|
116
|
+
test_files: []
|