Class: Skrift::Renderer
- Inherits:
-
Object
- Object
- Skrift::Renderer
- Defined in:
- lib/skrift/sft.rb
Overview
The scaling/rendering façade: set a scale, look up glyphs, measure and render them. (Formerly named SFT, after libschrift’s handle struct.)
Constant Summary collapse
- DOWNWARD_Y =
0x01
Instance Attribute Summary collapse
-
#flags ⇒ Object
Returns the value of attribute flags.
-
#font ⇒ Object
Returns the value of attribute font.
-
#x_offset ⇒ Object
Returns the value of attribute x_offset.
-
#x_scale ⇒ Object
Returns the value of attribute x_scale.
-
#y_offset ⇒ Object
Returns the value of attribute y_offset.
-
#y_scale ⇒ Object
Returns the value of attribute y_scale.
Instance Method Summary collapse
- #glyph_bbox(outline) ⇒ Object
-
#gmetrics(glyph) ⇒ Object
149.
-
#initialize(font) ⇒ Renderer
constructor
A new instance of Renderer.
-
#kerning(left_glyph, right_glyph) ⇒ Object
176.
- #lmetrics ⇒ Object
-
#lookup(codepoint, variation: nil) ⇒ Object
Glyph id for
codepoint. -
#render(glyph, image) ⇒ Object
Rasterise
glyphintoimage(mutated in place).
Constructor Details
#initialize(font) ⇒ Renderer
Returns a new instance of Renderer.
9 10 11 12 13 14 15 16 |
# File 'lib/skrift/sft.rb', line 9 def initialize(font) @font = font @x_scale = 32 @y_scale = 32 @x_offset = 0 @y_offset = 0 @flags = DOWNWARD_Y end |
Instance Attribute Details
#flags ⇒ Object
Returns the value of attribute flags.
7 8 9 |
# File 'lib/skrift/sft.rb', line 7 def flags @flags end |
#font ⇒ Object
Returns the value of attribute font.
7 8 9 |
# File 'lib/skrift/sft.rb', line 7 def font @font end |
#x_offset ⇒ Object
Returns the value of attribute x_offset.
7 8 9 |
# File 'lib/skrift/sft.rb', line 7 def x_offset @x_offset end |
#x_scale ⇒ Object
Returns the value of attribute x_scale.
7 8 9 |
# File 'lib/skrift/sft.rb', line 7 def x_scale @x_scale end |
#y_offset ⇒ Object
Returns the value of attribute y_offset.
7 8 9 |
# File 'lib/skrift/sft.rb', line 7 def y_offset @y_offset end |
#y_scale ⇒ Object
Returns the value of attribute y_scale.
7 8 9 |
# File 'lib/skrift/sft.rb', line 7 def y_scale @y_scale end |
Instance Method Details
#glyph_bbox(outline) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/skrift/sft.rb', line 28 def glyph_bbox(outline) box = @font.glyph_bbox(outline) raise if !box # Transform the bounding box into Renderer coordinate space xs = @x_scale.to_f / @font.units_per_em ys = @y_scale.to_f / @font.units_per_em box[0] = (box[0] * xs + @x_offset).floor box[1] = (box[1] * ys + @y_offset).floor box[2] = (box[2] * xs + @x_offset).ceil box[3] = (box[3] * ys + @y_offset).ceil return box end |
#gmetrics(glyph) ⇒ Object
149
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/skrift/sft.rb', line 41 def gmetrics(glyph) # 149 return nil if glyph.nil? raise "out of bounds" if glyph < 0 xs = @x_scale.to_f / @font.units_per_em adv, lsb = @font.hor_metrics(glyph) return nil if adv.nil? metrics = GMetrics.new(adv * xs, lsb * xs + @x_offset) outline = @font.outline_offset(glyph) return metrics if outline.nil? bbox = glyph_bbox(outline) return nil if !bbox metrics.min_width = bbox[2] - bbox[0] + 1 metrics.min_height = bbox[3] - bbox[1] + 1 metrics.y_offset = @flags & DOWNWARD_Y != 0 ? bbox[3] : bbox[1] return metrics end |
#kerning(left_glyph, right_glyph) ⇒ Object
176
93 94 95 |
# File 'lib/skrift/sft.rb', line 93 def kerning(left_glyph, right_glyph) # 176 @font.kerning[[left_glyph,right_glyph].pack("n*")] end |
#lmetrics ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/skrift/sft.rb', line 60 def lmetrics hhea = font.reqtable("hhea") factor = @y_scale.to_f / @font.units_per_em LMetrics.new( font.geti16(hhea + 4) * factor, # ascender font.geti16(hhea + 6) * factor, # descender font.geti16(hhea + 8) * factor # line_gap ) end |
#lookup(codepoint, variation: nil) ⇒ Object
Glyph id for codepoint. With variation (a variation selector such as Font::VS_EMOJI), resolve the <codepoint, selector> sequence via cmap-14 first, falling back to the plain glyph when the font omits the sequence.
21 22 23 24 25 26 |
# File 'lib/skrift/sft.rb', line 21 def lookup(codepoint, variation: nil) if variation && (g = font.variation_glyph_id(codepoint, variation)) return g end font.glyph_id(codepoint) end |
#render(glyph, image) ⇒ Object
Rasterise glyph into image (mutated in place). Returns true if the glyph had a renderable outline, false otherwise (e.g. a space).
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/skrift/sft.rb', line 72 def render(glyph, image) # 239 outline = @font.outline_offset(glyph) return false if outline.nil? bbox = glyph_bbox(outline) return false if !bbox # Set up the transformation matrix such that # the transformed bounding boxes min corner lines # up with the (0, 0) point. xr = [@x_scale.to_f / @font.units_per_em, 0.0, @x_offset - bbox[0]] ys = @y_scale.to_f / @font.units_per_em if @flags.allbits?(DOWNWARD_Y) transform = [xr, [0.0, -ys, bbox[3] - @y_offset]] else transform = [xr, [0.0, +ys, @y_offset - bbox[1] ]] end outl = @font.decode_outline(outline) return false unless outl outl.render(transform, image) true end |