Class: Skrift::X11::Glyphs

Inherits:
Object
  • Object
show all
Defined in:
lib/skrift/x11/glyphs.rb

Overview

Thin XRender adapter over Skrift::GlyphCache. Monochrome glyphs go into an A8 glyph set (coloured at composite time by a solid fill); colour glyphs (emoji, via the skrift-color delegate) go into an ARGB32 glyph set and are composited with a neutral white source so their own colours show. A string is drawn as runs of like-typed glyphs, one composite per run. All the platform-independent work (fallback, rasterisation, layout, caching, box drawing, colour delegation) lives in skrift core + the plugins.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dpy, font = nil, fontset: nil, x_scale:, y_scale:, pic: nil, fixed: nil, maxheight: nil, fit: false, color: nil) ⇒ Glyphs

color (optional) is a font (path, name or Skrift::Font) providing colour glyphs, e.g. an emoji font; requires the skrift-color gem.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/skrift/x11/glyphs.rb', line 35

def initialize(dpy, font=nil, fontset: nil, x_scale:, y_scale:, pic: nil, fixed: nil, maxheight: nil, fit: false, color: nil)
  @dpy = dpy
  @pic = pic
  @maxheight = maxheight

  color_renderer = build_color_renderer(color, x_scale, y_scale)
  @cache = Skrift::GlyphCache.new(fontset || font,
                                  x_scale: x_scale, y_scale: y_scale,
                                  fixed: fixed, maxheight: maxheight, fit: fit,
                                  special: ->(cp) { @boxes.glyph(cp) },
                                  color: color_renderer)
  @boxes = Skrift::BoxDrawing.new(@cache.cell_width, @cache.cell_height)
  @fixed_width = @cache.cell_width
  @lm = Skrift::LMetrics.new(@cache.ascent, @cache.descent, @cache.line_gap)

  @colcache = {}
  @gids     = {}        # codepoint -> [:mono|:color, glyph-set id]
  @nextgid  = 1

  @gfmt     = @dpy.render_find_standard_format(:a8).id
  @glyphset = @dpy.render_create_glyph_set(@gfmt)

  if color_renderer
    @cfmt      = @dpy.render_find_standard_format(:argb24).id
    @cglyphset = @dpy.render_create_glyph_set(@cfmt)
    @white     = @dpy.render_create_solid_fill(0xffff, 0xffff, 0xffff, 0xffff)
  end
end

Instance Attribute Details

#fixed_widthObject (readonly)

Returns the value of attribute fixed_width.



30
31
32
# File 'lib/skrift/x11/glyphs.rb', line 30

def fixed_width
  @fixed_width
end

#lmObject

Returns the value of attribute lm.



31
32
33
# File 'lib/skrift/x11/glyphs.rb', line 31

def lm
  @lm
end

#maxheightObject

Returns the value of attribute maxheight.



31
32
33
# File 'lib/skrift/x11/glyphs.rb', line 31

def maxheight
  @maxheight
end

Instance Method Details

#fill_for_col(col) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/skrift/x11/glyphs.rb', line 66

def fill_for_col(col)
  return @colcache[col] if @colcache[col]
  r = col >> 16
  r |= r << 8
  g = (col >> 8) & 0xff
  g |= g << 8
  b = col & 0xff
  b |= b << 8
  @colcache[col] = @dpy.render_create_solid_fill(r, g, b, 0xffff)
end

#inspectObject



64
# File 'lib/skrift/x11/glyphs.rb', line 64

def inspect = "<Glyphs #{object_id}>"

#render_str(pic, col, x, y, str) ⇒ Object

Draw str as one composite per run of same-typed glyphs (mono vs colour). Each rendered glyph advances the pen by one cell, so a pure-text string is a single A8 composite exactly as before; emoji break the run.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/skrift/x11/glyphs.rb', line 82

def render_str(pic, col, x, y, str)
  glyphs   = str.to_s.each_char.map { |ch| gsgid_for(ch.ord) }
  rendered = 0
  i = 0
  while i < glyphs.length
    (i += 1; next) if glyphs[i].nil? # unmapped: skip, no advance
    type   = glyphs[i].first
    run_x  = x + rendered * @fixed_width
    ids    = []
    while i < glyphs.length && glyphs[i] && glyphs[i].first == type
      ids << glyphs[i].last
      rendered += 1
      i += 1
    end
    composite_run(type, pic, col, run_x, y, ids)
  end
end

#text_width(str) ⇒ Object



77
# File 'lib/skrift/x11/glyphs.rb', line 77

def text_width(str) = @cache.text_width(str)