Class: Tea::Font
- Inherits:
-
Object
- Object
- Tea::Font
- Defined in:
- lib/tea/c_font.rb
Overview
Fonts are used to draw text. They do this by mapping characters to images that are loaded when the Font is created.
Tea supports bitmap fonts, and Karl Bartel’s SFont format.
Bitmap fonts (Tea::Font::BITMAP_FONT) are a single row of 256 characters in a BMP or PNG image. If the image has intrinsic transparency, it will be used by default. Otherwise, loading the font with the color transparency option will consider one color as the ‘transparent color’ and no such pixels will be drawn.
SFont fonts (Tea::Font::SFONT) are also a single row of character images, but ranging from ASCII 33 to ASCII 127:
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ `
a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
SFont uses variable width characters. Characters are separated by magenta (255, 0, 255) in the top pixel row, so the pixels directly under the magenta strips would be the gaps between characters, e.g.:
____ ____ ____ ____ <-- magenta strips
.... # .... #### .... ### ....
.... # # .... # # .... # # ....
.... ##### .... #### .... # .... <-- gaps between characters
.... # # .... # # .... # # .... (can be any color)
.... # # .... #### .... ### ....
The width of a space is not defined in the SFont format, so Tea uses the width of the first character, ‘!’.
Defined Under Namespace
Classes: WrappedLines
Constant Summary collapse
- BITMAP_FONT =
font_type
constant for bitmap fonts. :BITMAP_FONT
- SFONT =
:SFONT
- BITMAP_FONT_START =
0
- BITMAP_FONT_LENGTH =
256
- SFONT_START =
33
- SFONT_LENGTH =
94
- CODE_POINT_SPACE =
32
Instance Method Summary collapse
-
#draw_to(bitmap, x, y, string) ⇒ Object
Write the given string onto the bitmap at (x, y).
-
#h ⇒ Object
Get the height of the font’s characters.
-
#initialize(path, font_type, options = nil) ⇒ Font
constructor
Create a new font from a font file given by
path
. -
#string_w(string) ⇒ Object
Calculate the pixel width of a string rendered with this font.
-
#word_wrap(string, width, initial_left_margin = 0) ⇒ Object
Split a string into an array of lines such that each line, when rendered using this font, is no wider than width.
Constructor Details
#initialize(path, font_type, options = nil) ⇒ Font
Create a new font from a font file given by path
.
font_type
is one of Tea::Font::BITMAP_FONT or Tea::Font::SFONT. See Tea::Font for font format details.
Optional hash arguments:
+:transparent_color+:: If +font_type+ is Tea::Font::BITMAP_FONT, this
is the color that should not be drawn when
rendering text. Default: Tea::Color::MAGENTA.
May raise Tea::Error on failure.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/tea/c_font.rb', line 68 def initialize(path, font_type, =nil) font = SDL::Surface.load(path) transparent_color = ? [:transparent_color] : nil @font_type = font_type case font_type when BITMAP_FONT @glyphs = letters_from_bitmap_font(font, transparent_color) when SFONT @glyphs = letters_from_sfont(font, transparent_color) end rescue SDL::Error => e raise Tea::Error, e., e.backtrace end |
Instance Method Details
#draw_to(bitmap, x, y, string) ⇒ Object
Write the given string onto the bitmap at (x, y).
184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/tea/c_font.rb', line 184 def draw_to(bitmap, x, y, string) draw_x = x each_code_point(string) do |pt| glyph = get_glyph(pt) if glyph bitmap.blit glyph, draw_x, y draw_x += glyph.w else draw_x += get_glyph_w(pt) end end string end |
#h ⇒ Object
Get the height of the font’s characters.
91 92 93 94 |
# File 'lib/tea/c_font.rb', line 91 def h # Nothing special about 0, all chars are the same height. @glyphs[0].h end |
#string_w(string) ⇒ Object
Calculate the pixel width of a string rendered with this font.
84 85 86 87 88 |
# File 'lib/tea/c_font.rb', line 84 def string_w(string) w = 0 each_code_point(string) { |pt| w += get_glyph_w(pt) } w end |
#word_wrap(string, width, initial_left_margin = 0) ⇒ Object
Split a string into an array of lines such that each line, when rendered using this font, is no wider than width.
initial_left_margin
sets the starting position for the first line of wrapping.
Returns an array of strings, representing the split lines.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/tea/c_font.rb', line 109 def word_wrap(string, width, initial_left_margin=0) # This is adapted from the Sphere RPG Engine's font word wrapping code. # Rickety, but battle-tested. space_w = string_w(" ") tab = " " * 4 tab_w = string_w(tab) x = initial_left_margin lines = WrappedLines.new lines.push "" word = "" word_w = 0 # No good string character iterators for Ruby 1.8, hence crappy O(n) access. string.length.times do |i| # Crappy O(n) access here. char = string[i, 1] case char when " ", "\t" if char == " " spacing = " " spacing_w = space_w elsif char == "\t" spacing = tab spacing_w = tab_w end if x + word_w + spacing_w > width lines.push word + spacing x = word_w + spacing_w else lines[-1] += word + spacing x += word_w + spacing_w end word = "" word_w = 0 when "\n" lines[-1] += word lines.push "" x = 0 word = "" word_w = 0 else char_w = string_w(char) if word_w + char_w > width && x == 0 # Word is too long for a single line, so split it. lines[-1] += word lines.push "" word = "" word_w = 0 elsif x + word_w + char_w > width # Start a new line. x = 0 lines.push "" end word += char word_w += char_w end end lines[-1] += word lines.end_x = x + word_w lines end |