Class: HexaPDF::Layout::LineFragment

Inherits:
Object
  • Object
show all
Defined in:
lib/hexapdf/layout/line_fragment.rb

Overview

A LineFragment describes a line of text and can contain TextFragment objects or InlineBox objects.

The items of a line fragment are aligned along the x-axis which coincides with the text baseline. The vertical alignment is determined by the value of the #valign method:

:text_top

Align the top of the box with the top of the text of the LineFragment.

:text_bottom

Align the bottom of the box with the bottom of the text of the LineFragment.

:baseline

Align the bottom of the box with the baseline of the LineFragment.

:top

Align the top of the box with the top of the LineFragment.

:bottom

Align the bottom of the box with the bottom of the LineFragment.

:text

This is a special alignment value for text fragment objects. The text fragment is aligned on the baseline and its minimum and maximum y-coordinates are used when calculating the line’s #text_y_min and #text_y_max.

This value may be used by other objects if they should be handled similar to text fragments, e.g. graphical representation of characters (think: emoji fonts).

Item Requirements

Each item of a line fragment has to respond to the following methods:

#x_min

The minimum x-coordinate of the item.

#x_max

The maximum x-coordinate of the item.

#width

The width of the item.

#valign

The vertical alignment of the item (see above).

#draw(canvas, x, y)

Should draw the item onto the canvas at the position (x, y).

If an item has a vertical alignment of :text, it additionally has to respond to the following methods:

#y_min

The minimum y-coordinate of the item.

#y_max

The maximum y-coordinate of the item.

Otherwise (i.e. a vertical alignment different from :text), the following method must be implemented:

#height

The height of the item.

Defined Under Namespace

Classes: HeightCalculator

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(items = []) ⇒ LineFragment

Creates a new LineFragment object, adding all given items to it.



184
185
186
187
188
189
# File 'lib/hexapdf/layout/line_fragment.rb', line 184

def initialize(items = [])
  @items = []
  items.each {|i| add(i)}
  @x_offset = 0
  @y_offset = 0
end

Instance Attribute Details

#itemsObject

The items: TextFragment and InlineBox objects



171
172
173
# File 'lib/hexapdf/layout/line_fragment.rb', line 171

def items
  @items
end

#x_offsetObject

An optional horizontal offset that should be taken into account when positioning the line.



174
175
176
# File 'lib/hexapdf/layout/line_fragment.rb', line 174

def x_offset
  @x_offset
end

#y_offsetObject

An optional vertical offset that should be taken into account when positioning the line.

For the first line in a paragraph this describes the offset from the top of the box to the top of the line. For all other lines it describes the offset from the previous baseline to the baseline of this line.



181
182
183
# File 'lib/hexapdf/layout/line_fragment.rb', line 181

def y_offset
  @y_offset
end

Instance Method Details

#add(item) ⇒ Object Also known as: <<

Adds the given item at the end of the item list.

If both the item and the last item in the item list are TextFragment objects and they have the same style, they are combined.

Note: The cache is not cleared!



197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/hexapdf/layout/line_fragment.rb', line 197

def add(item)
  last = @items.last
  if last.class == item.class && item.kind_of?(TextFragment) && last.style == item.style
    if last.items.frozen?
      @items[-1] = last = last.dup
      last.items = last.items.dup
    end
    last.items[last.items.length, 0] = item.items
    last.clear_cache
  else
    @items << item
  end
  self
end

#clear_cacheObject

:call-seq:

line_fragment.clear_cache   -> line_fragment

Clears all cached values.

This method needs to be called if the fragment’s items are changed!



295
296
297
298
# File 'lib/hexapdf/layout/line_fragment.rb', line 295

def clear_cache
  @x_max = @y_min = @y_max = @text_y_min = @text_y_max = @width = nil
  self
end

#eachObject

:call-seq:

line_fragment.each {|item, x, y| block }

Yields each item together with its horizontal offset from 0 and vertical offset from the baseline.



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/hexapdf/layout/line_fragment.rb', line 218

def each
  x = 0
  @items.each do |item|
    y = case item.valign
        when :text, :baseline then 0
        when :top then y_max - item.height
        when :text_top then text_y_max - item.height
        when :text_bottom then text_y_min
        when :bottom then y_min
        else
          raise HexaPDF::Error, "Unknown inline box alignment #{item.valign}"
        end
    yield(item, x, y)
    x += item.width
  end
end

#heightObject

The height of the line fragment.



275
276
277
# File 'lib/hexapdf/layout/line_fragment.rb', line 275

def height
  y_max - y_min
end

#ignore_justification!Object

Specifies that this line should not be justified if line justification is used.



280
281
282
# File 'lib/hexapdf/layout/line_fragment.rb', line 280

def ignore_justification!
  @ignore_justification = true
end

#ignore_justification?Boolean

Returns true if justification should be ignored for this line.

Returns:

  • (Boolean)


285
286
287
# File 'lib/hexapdf/layout/line_fragment.rb', line 285

def ignore_justification?
  defined?(@ignore_justification) && @ignore_justification
end

#text_y_maxObject

The maximum y-coordinate of any TextFragment item of the line.



265
266
267
# File 'lib/hexapdf/layout/line_fragment.rb', line 265

def text_y_max
  @text_y_max ||= calculate_y_dimensions[3]
end

#text_y_minObject

The minimum y-coordinate of any TextFragment item of the line.



253
254
255
# File 'lib/hexapdf/layout/line_fragment.rb', line 253

def text_y_min
  @text_y_min ||= calculate_y_dimensions[2]
end

#widthObject

The width of the line fragment.



270
271
272
# File 'lib/hexapdf/layout/line_fragment.rb', line 270

def width
  @width ||= @items.sum(&:width)
end

#x_maxObject

The maximum x-coordinate of the whole line.



241
242
243
# File 'lib/hexapdf/layout/line_fragment.rb', line 241

def x_max
  @x_max ||= width + (items[-1].x_max - items[-1].width)
end

#x_minObject

The minimum x-coordinate of the whole line.



236
237
238
# File 'lib/hexapdf/layout/line_fragment.rb', line 236

def x_min
  @items[0].x_min
end

#y_maxObject

The maximum y-coordinate of any item of the line.

It is always greater than or equal to zero.



260
261
262
# File 'lib/hexapdf/layout/line_fragment.rb', line 260

def y_max
  @y_max ||= calculate_y_dimensions[1]
end

#y_minObject

The minimum y-coordinate of any item of the line.

It is always lower than or equal to zero.



248
249
250
# File 'lib/hexapdf/layout/line_fragment.rb', line 248

def y_min
  @y_min ||= calculate_y_dimensions[0]
end