Class: Prawn::SVG::Elements::TextComponent

Inherits:
DepthFirstBase show all
Defined in:
lib/prawn/svg/elements/text_component.rb

Defined Under Namespace

Classes: Printable, TextState

Constant Summary

Constants inherited from Base

Base::COMMA_WSP_REGEXP, Base::MissingAttributesError, Base::PAINT_TYPES, Base::SVG_NAMESPACE, Base::SkipElementError, Base::SkipElementQuietly

Constants included from Attributes::Stroke

Attributes::Stroke::CAP_STYLE_TRANSLATIONS, Attributes::Stroke::JOIN_STYLE_TRANSLATIONS

Instance Attribute Summary collapse

Attributes inherited from Base

#attributes, #base_calls, #calls, #document, #parent_calls, #properties, #source, #state

Instance Method Summary collapse

Methods inherited from DepthFirstBase

#initialize, #parse_and_apply, #process

Methods inherited from Base

#initialize, #name, #parse_and_apply, #process

Methods included from TransformParser

#parse_transform_attribute

Methods included from Attributes::Space

#parse_xml_space_attribute

Methods included from Attributes::Stroke

#parse_stroke_attributes_and_call

Methods included from Attributes::ClipPath

#parse_clip_path_attribute_and_call

Methods included from Attributes::Opacity

#parse_opacity_attributes_and_call

Methods included from Attributes::Transform

#parse_transform_attribute_and_call

Constructor Details

This class inherits a constructor from Prawn::SVG::Elements::DepthFirstBase

Instance Attribute Details

#commandsObject (readonly)

Returns the value of attribute commands.



2
3
4
# File 'lib/prawn/svg/elements/text_component.rb', line 2

def commands
  @commands
end

Instance Method Details

#applyObject

Raises:



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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/prawn/svg/elements/text_component.rb', line 38

def apply
  raise SkipElementQuietly if computed_properties.display == "none"

  font = select_font
  apply_font(font) if font

  # text_anchor and dominant_baseline aren't Prawn options; we have to do some math to support them
  # and so we handle them in Prawn::SVG::Interface#rewrite_call_arguments
  opts = {
    size:        computed_properties.numerical_font_size,
    style:       font && font.subfamily,
    text_anchor: computed_properties.text_anchor,
  }

  opts[:dominant_baseline] = computed_properties.dominant_baseline unless computed_properties.dominant_baseline == 'auto'
  opts[:decoration] = computed_properties.text_decoration unless computed_properties.text_decoration == 'none'

  if state.text.parent
    add_call_and_enter 'character_spacing', state.text.spacing unless state.text.spacing == state.text.parent.spacing
    add_call_and_enter 'text_rendering_mode', state.text.mode unless state.text.mode == state.text.parent.mode
  else
    add_call_and_enter 'character_spacing', state.text.spacing unless state.text.spacing == 0
    add_call_and_enter 'text_rendering_mode', state.text.mode unless state.text.mode == :fill
  end

  @commands.each do |command|
    case command
    when Printable
      apply_text(command.text, opts)
    when self.class
      add_call 'save'
      command.apply_step(calls)
      add_call 'restore'
    else
      raise
    end
  end

  # It's possible there was no text to render.  In that case, add a 'noop' so character_spacing/text_rendering_mode
  # don't blow up when they find they don't have a block to execute.
  add_call 'noop' if calls.empty?
end

#parseObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/prawn/svg/elements/text_component.rb', line 7

def parse
  if state.inside_clip_path
    raise SkipElementError, "<text> elements are not supported in clip paths"
  end

  state.text.x = (attributes['x'] || "").split(COMMA_WSP_REGEXP).collect { |n| x(n) }
  state.text.y = (attributes['y'] || "").split(COMMA_WSP_REGEXP).collect { |n| y(n) }
  state.text.dx = (attributes['dx'] || "").split(COMMA_WSP_REGEXP).collect { |n| x_pixels(n) }
  state.text.dy = (attributes['dy'] || "").split(COMMA_WSP_REGEXP).collect { |n| y_pixels(n) }
  state.text.rotation = (attributes['rotate'] || "").split(COMMA_WSP_REGEXP).collect(&:to_f)
  state.text.text_length = normalize_length(attributes['textLength'])
  state.text.length_adjust = attributes['lengthAdjust']
  state.text.spacing = calculate_character_spacing
  state.text.mode = calculate_text_rendering_mode

  @commands = []

  svg_text_children.each do |child|
    if child.node_type == :text
      append_text(child)
    else
      case child.name
      when 'tspan', 'tref'
        append_child(child)
      else
        warnings << "Unknown tag '#{child.name}' inside text tag; ignoring"
      end
    end
  end
end