Class: SFML::Text

Inherits:
Object
  • Object
show all
Includes:
Graphics::Transformable
Defined in:
lib/sfml/graphics/text.rb

Overview

Drawable rendered text. Like Sprite, requires a Font at construction time in SFML 3, and we hold a Ruby reference to it to keep the GPU resource alive while the Text object is in use.

font = SFML::Font.find("DejaVuSans")
score = SFML::Text.new(font, "0 : 0",
character_size: 48,
fill_color: SFML::Color.white,
position: [400, 30],
style: %i[bold])
window.draw(score)
score.string = "1 : 0"  # mutate freely after construction

Constant Summary collapse

CSFML_PREFIX =
:sfText
STYLES =

Bitmask values for each style symbol.

{
  regular:        0,
  bold:           1 << 0,
  italic:         1 << 1,
  underlined:     1 << 2,
  strike_through: 1 << 3,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Graphics::Transformable

#move, #origin, #origin=, #position, #position=, #rotate, #rotation, #rotation=, #scale, #scale=, #scale_by

Constructor Details

#initialize(font, string = "", **opts) ⇒ Text

Build a Text. font must be an SFML::Font; string defaults to empty. Optional kwargs: :character_size, :fill_color, :outline_color, :outline_thickness, :style, plus the standard transform options.

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/sfml/graphics/text.rb', line 31

def initialize(font, string = "", **opts)
  raise ArgumentError, "Text requires a SFML::Font" unless font.is_a?(Font)

  ptr = C::Graphics.sfText_create(font.handle)
  raise GraphicsError, "sfText_create returned NULL" if ptr.null?
  @handle = FFI::AutoPointer.new(ptr, C::Graphics.method(:sfText_destroy))
  @font   = font # keep alive for GC

  self.string             = string
  self.character_size     = opts[:character_size]    if opts.key?(:character_size)
  self.fill_color         = opts[:fill_color]        if opts.key?(:fill_color)
  self.outline_color      = opts[:outline_color]     if opts.key?(:outline_color)
  self.outline_thickness  = opts[:outline_thickness] if opts.key?(:outline_thickness)
  self.style              = opts[:style]             if opts.key?(:style)
  self.position           = opts[:position]          if opts.key?(:position)
  self.origin             = opts[:origin]            if opts.key?(:origin)
  self.rotation           = opts[:rotation]          if opts.key?(:rotation)
  self.scale              = opts[:scale]             if opts.key?(:scale)
end

Instance Attribute Details

#font ⇒ Object

The font.



52
53
54
# File 'lib/sfml/graphics/text.rb', line 52

def font
  @font
end

#handle ⇒ Object (readonly)

:nodoc:



211
212
213
# File 'lib/sfml/graphics/text.rb', line 211

def handle
  @handle
end

Instance Method Details

#character_size ⇒ Object

Font size in pixels (e.g. 14, 18, 24).



90
# File 'lib/sfml/graphics/text.rb', line 90

def character_size = C::Graphics.sfText_getCharacterSize(@handle)

#character_size=(value) ⇒ Object

Set the font size.



93
94
95
# File 'lib/sfml/graphics/text.rb', line 93

def character_size=(value)
  C::Graphics.sfText_setCharacterSize(@handle, Integer(value))
end

#draw_on(target, states_ptr = nil) ⇒ Object

Returns the draw on.



207
208
209
# File 'lib/sfml/graphics/text.rb', line 207

def draw_on(target, states_ptr = nil) # :nodoc:
  target._draw_native(:Text, @handle, states_ptr)
end

#dup ⇒ Object Also known as: clone

Deep copy. The returned Text holds the same Font reference (Fonts are shareable; each owns its own glyph atlas).

Raises:



183
184
185
186
187
188
189
190
191
# File 'lib/sfml/graphics/text.rb', line 183

def dup
  ptr = C::Graphics.sfText_copy(@handle)
  raise GraphicsError, "sfText_copy returned NULL" if ptr.null?

  copy = self.class.allocate
  copy.instance_variable_set(:@handle, FFI::AutoPointer.new(ptr, C::Graphics.method(:sfText_destroy)))
  copy.instance_variable_set(:@font, @font)
  copy
end

#fill_color ⇒ Object

Body fill color.



98
# File 'lib/sfml/graphics/text.rb', line 98

def fill_color = Color.from_native(C::Graphics.sfText_getFillColor(@handle))

#fill_color=(c) ⇒ Object

Set the fill color.



101
102
103
# File 'lib/sfml/graphics/text.rb', line 101

def fill_color=(c)
  C::Graphics.sfText_setFillColor(@handle, c.to_native)
end

#find_character_pos(index) ⇒ Object

The screen-space position of the character at byte index index in the Text's current string. Returns a Vector2. Useful for positioning a caret in a text field, drawing selection highlights, or anchoring tooltips.



165
166
167
# File 'lib/sfml/graphics/text.rb', line 165

def find_character_pos(index)
  Vector2.from_native(C::Graphics.sfText_findCharacterPos(@handle, Integer(index)))
end

#global_bounds ⇒ Object

Bounding box after applying the Text's transform (position/scale/rotation).



202
203
204
# File 'lib/sfml/graphics/text.rb', line 202

def global_bounds
  Rect.from_native(C::Graphics.sfText_getGlobalBounds(@handle))
end

#inverse_transform ⇒ Object

Inverse of #transform — maps world-space coords back to the Text's local space.



177
178
179
# File 'lib/sfml/graphics/text.rb', line 177

def inverse_transform
  C::Graphics.sfText_getInverseTransform(@handle)
end

#letter_spacing ⇒ Object

The character spacing modifier — a multiplier on the font's natural advance. Read with no args, set with a Float (1.0 = default).



146
# File 'lib/sfml/graphics/text.rb', line 146

def letter_spacing = C::Graphics.sfText_getLetterSpacing(@handle)

#letter_spacing=(value) ⇒ Object

Set the letter-spacing multiplier.



149
150
151
# File 'lib/sfml/graphics/text.rb', line 149

def letter_spacing=(value)
  C::Graphics.sfText_setLetterSpacing(@handle, Float(value))
end

#line_spacing ⇒ Object

The line-spacing multiplier (1.0 = default).



154
# File 'lib/sfml/graphics/text.rb', line 154

def line_spacing = C::Graphics.sfText_getLineSpacing(@handle)

#line_spacing=(value) ⇒ Object

Set the line-spacing multiplier.



157
158
159
# File 'lib/sfml/graphics/text.rb', line 157

def line_spacing=(value)
  C::Graphics.sfText_setLineSpacing(@handle, Float(value))
end

#local_bounds ⇒ Object

Bounding box of the text in its own (untransformed) coordinate system. Use this to centre or align glyphs precisely:

text.origin = [text.local_bounds.width / 2, 0]


197
198
199
# File 'lib/sfml/graphics/text.rb', line 197

def local_bounds
  Rect.from_native(C::Graphics.sfText_getLocalBounds(@handle))
end

#outline_color ⇒ Object

Outline color (only visible when #outline_thickness > 0).



106
# File 'lib/sfml/graphics/text.rb', line 106

def outline_color = Color.from_native(C::Graphics.sfText_getOutlineColor(@handle))

#outline_color=(c) ⇒ Object

Set the outline color.



109
110
111
# File 'lib/sfml/graphics/text.rb', line 109

def outline_color=(c)
  C::Graphics.sfText_setOutlineColor(@handle, c.to_native)
end

#outline_thickness ⇒ Object

Outline thickness in pixels.



114
# File 'lib/sfml/graphics/text.rb', line 114

def outline_thickness = C::Graphics.sfText_getOutlineThickness(@handle)

#outline_thickness=(t) ⇒ Object

Set the outline thickness.



117
118
119
# File 'lib/sfml/graphics/text.rb', line 117

def outline_thickness=(t)
  C::Graphics.sfText_setOutlineThickness(@handle, t.to_f)
end

#string ⇒ Object

Read the current string back as Ruby UTF-8. CSFML returns a pointer to a null-terminated sfChar32 (UTF-32) array; we walk it until the zero terminator and pack the codepoints back into a UTF-8 String.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sfml/graphics/text.rb', line 64

def string
  ptr = C::Graphics.sfText_getUnicodeString(@handle)
  return "" if ptr.null?

  codepoints = []
  offset = 0
  loop do
    cp = ptr.get_uint32(offset)
    break if cp.zero?
    codepoints << cp
    offset += 4
  end
  codepoints.pack("U*")
end

#string=(value) ⇒ Object

Replace the displayed string. Accepts any Ruby String — UTF-8 codepoints are converted to UTF-32 for CSFML internally.



81
82
83
84
85
86
87
# File 'lib/sfml/graphics/text.rb', line 81

def string=(value)
  str = value.to_s.encode("UTF-8")
  cps = str.unpack("U*")  # array of integer codepoints
  buf = FFI::MemoryPointer.new(:uint32, cps.length + 1)
  buf.write_array_of_uint32(cps + [0])
  C::Graphics.sfText_setUnicodeString(@handle, buf)
end

#style ⇒ Object

Returns an Array of style symbols, e.g. [:bold, :italic].



122
123
124
125
126
127
128
# File 'lib/sfml/graphics/text.rb', line 122

def style
  bits = C::Graphics.sfText_getStyle(@handle)
  return [:regular] if bits.zero?
  STYLES.each_with_object([]) do |(name, value), acc|
    acc << name if value != 0 && (bits & value) != 0
  end
end

#style=(value) ⇒ Object

Accepts a single Symbol, an Array of Symbols, or a raw integer bitmask.



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/sfml/graphics/text.rb', line 131

def style=(value)
  bits = case value
         when Integer then value
         when Symbol  then STYLES.fetch(value)
         when Array
           value.reduce(0) { |acc, sym| acc | STYLES.fetch(sym) }
         else
           raise ArgumentError, "Text#style= expects Symbol, Array, or Integer; got #{value.class}"
         end
  C::Graphics.sfText_setStyle(@handle, bits)
end

#transform ⇒ Object

Combined translation/scale/rotation as a SFML::Transform. Same matrix the renderer uses to draw the Text.



171
172
173
# File 'lib/sfml/graphics/text.rb', line 171

def transform
  C::Graphics.sfText_getTransform(@handle)
end