ruby-bitmap-fonts 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,5 @@
1
+ require "bdf/font"
2
+ require "bdf/char"
3
+ require "bdf/renderer"
4
+ require "bdf/canvas"
5
+ require "bdf/version"
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
@@ -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
@@ -0,0 +1,3 @@
1
+ module BDF
2
+ VERSION = "0.1.0"
3
+ end
@@ -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: []