@@ -12,6 +12,8 @@ def initialize(pdf)
1212 @buffer = [ ]
1313 @context = Context . new
1414 @last_margin = 0
15+ @last_text = ''
16+ @last_tag_open = false
1517 @pdf = pdf
1618 end
1719
@@ -22,6 +24,8 @@ def on_tag_close(element)
2224 render_if_needed ( element )
2325 apply_tag_close_styles ( element )
2426 context . remove_last
27+ @last_tag_open = false
28+ @last_text = ''
2529 end
2630
2731 # On tag open callback
@@ -38,6 +42,7 @@ def on_tag_open(tag_name, attributes:, element_styles: '')
3842 options = { width : pdf . page_width , height : pdf . page_height }
3943 tag_class . new ( tag_name , attributes : attributes , options : options ) . tap do |element |
4044 setup_element ( element , element_styles : element_styles )
45+ @last_tag_open = true
4146 end
4247 end
4348
@@ -47,9 +52,10 @@ def on_tag_open(tag_name, attributes:, element_styles: '')
4752 #
4853 # @return [NilClass] nil value (=> no element)
4954 def on_text_node ( content )
50- return if content . match? ( /\A \s *\Z / )
55+ return if context . previous_tag &. block? && content . match? ( /\A \s *\Z / )
5156
52- buffer << context . merged_styles . merge ( text : prepare_text ( content ) )
57+ text = prepare_text ( content )
58+ buffer << context . merged_styles . merge ( text : text ) unless text . empty?
5359 context . last_text_node = true
5460 nil
5561 end
@@ -70,17 +76,13 @@ def render
7076 attr_reader :buffer , :context , :last_margin , :pdf
7177
7278 def setup_element ( element , element_styles :)
73- add_space_if_needed unless render_if_needed ( element )
79+ render_if_needed ( element )
7480 context . add ( element )
7581 element . process_styles ( element_styles : element_styles )
7682 apply_tag_open_styles ( element )
7783 element . custom_render ( pdf , context ) if element . respond_to? ( :custom_render )
7884 end
7985
80- def add_space_if_needed
81- buffer << SPACE if buffer . any? && !context . last_text_node && ![ NEW_LINE , SPACE ] . include? ( buffer . last )
82- end
83-
8486 def render_if_needed ( element )
8587 render_needed = element &.block? && buffer . any? && buffer . last != NEW_LINE
8688 return false unless render_needed
@@ -104,10 +106,12 @@ def apply_tag_open_styles(element)
104106 end
105107
106108 def prepare_text ( content )
107- white_space_pre = context . last && context . last . styles [ :white_space ] == :pre
108- text = ::Oga ::HTML ::Entities . decode ( context . before_content )
109- text += white_space_pre ? content : content . gsub ( /\A \s *\n \s *|\s *\n \s *\Z / , '' ) . delete ( "\n " ) . squeeze ( ' ' )
110- text
109+ text = context . before_content ? ::Oga ::HTML ::Entities . decode ( context . before_content ) : ''
110+ return ( @last_text = text + content ) if context . white_space_pre?
111+
112+ content = content . lstrip if @last_text [ -1 ] == ' ' || @last_tag_open
113+ text += content . tr ( "\n " , ' ' ) . squeeze ( ' ' )
114+ @last_text = text
111115 end
112116
113117 def output_content ( buffer , block_styles )
@@ -129,7 +133,10 @@ def apply_callbacks(buffer)
129133 def adjust_leading ( buffer , leading )
130134 return leading if leading
131135
132- ( buffer . map { |item | item [ :size ] || Context ::DEFAULT_STYLES [ :size ] } . max * 0.055 ) . round ( 4 )
136+ leadings = buffer . map do |item |
137+ ( item [ :size ] || Context ::DEFAULT_STYLES [ :size ] ) * ( ADJUST_LEADING [ item [ :font ] ] || ADJUST_LEADING [ nil ] )
138+ end
139+ leadings . max . round ( 4 )
133140 end
134141
135142 def bounds ( buffer , options , block_styles )
0 commit comments