Class: HexaPDF::Layout::Style
- Inherits:
-
Object
- Object
- HexaPDF::Layout::Style
- Defined in:
- lib/hexapdf/layout/style.rb
Overview
A Style is a container for properties that describe the appearance of text or graphics.
Each property except #font has a default value, so only the desired properties need to be changed.
Each property has three associated methods:
- property_name
-
Getter method.
- property_name(*args) and property_name=
-
Setter method.
- property_name?
-
Tester method to see if a value has been set or if the default value has already been used.
Defined Under Namespace
Classes: Border, Layers, LineSpacing, LinkLayer, Quad
Constant Summary collapse
- UNSET =
:nodoc:
::Object.new
Class Method Summary collapse
-
.create(style) ⇒ Object
:call-seq: Style.create(style) -> style Style.create(properties_hash) -> style.
Instance Method Summary collapse
-
#calculated_font_size ⇒ Object
The calculated font size, taking superscript and subscript into account.
-
#calculated_strikeout_position ⇒ Object
Returns the correct offset from the baseline for the strikeout line.
-
#calculated_strikeout_thickness ⇒ Object
Returns the correct thickness for the strikeout line.
-
#calculated_text_rise ⇒ Object
The calculated text rise, taking superscript and subscript into account.
-
#calculated_underline_position ⇒ Object
Returns the correct offset from the baseline for the underline.
-
#calculated_underline_thickness ⇒ Object
Returns the correct thickness for the underline.
-
#clear_cache ⇒ Object
Clears all cached values.
-
#initialize(**properties) ⇒ Style
constructor
Creates a new Style object.
-
#initialize_copy(other) ⇒ Object
Duplicates the complex properties that can be modified, as well as the cache.
-
#name ⇒ Object
:method: text_line_wrapping_algorithm :call-seq: text_line_wrapping_algorithm(algorithm = nil) {|items, width_block| block }.
-
#scaled_character_spacing ⇒ Object
The character spacing scaled appropriately.
-
#scaled_font_ascender ⇒ Object
The ascender of the font scaled appropriately.
-
#scaled_font_descender ⇒ Object
The descender of the font scaled appropriately.
-
#scaled_font_size ⇒ Object
The font size scaled appropriately.
-
#scaled_horizontal_scaling ⇒ Object
The horizontal scaling scaled appropriately.
-
#scaled_item_width(item) ⇒ Object
Returns the width of the item scaled appropriately (by taking font size, characters spacing, word spacing and horizontal scaling into account).
-
#scaled_word_spacing ⇒ Object
The word spacing scaled appropriately.
-
#scaled_y_max ⇒ Object
The maximum y-coordinate, calculated using the scaled ascender of the font and the line height or font size.
-
#scaled_y_min ⇒ Object
The minimum y-coordinate, calculated using the scaled descender of the font and the line height or font size.
-
#update(**properties) ⇒ Object
:call-seq: style.update(**properties) -> style.
Constructor Details
#initialize(**properties) ⇒ Style
Creates a new Style object.
The properties
hash may be used to set the initial values of properties by using keys equivalent to the property names.
Example:
Style.new(font_size: 15, text_align: :center, text_valign: center)
581 582 583 584 |
# File 'lib/hexapdf/layout/style.rb', line 581 def initialize(**properties) update(**properties) @scaled_item_widths = {}.compare_by_identity end |
Class Method Details
.create(style) ⇒ Object
:call-seq:
Style.create(style) -> style
Style.create(properties_hash) -> style
Creates a Style object based on the style
argument and returns it:
-
If
style
is already a Style object, it is just returned. -
If
style
is a hash, a new Style object with the style properties specified by the hash -
is created.
-
If
style
isnil
, a new Style object with only default values is created.
565 566 567 568 569 570 571 572 |
# File 'lib/hexapdf/layout/style.rb', line 565 def self.create(style) case style when self then style when Hash then new(**style) when nil then new else raise ArgumentError, "Invalid argument class #{style.class}" end end |
Instance Method Details
#calculated_font_size ⇒ Object
The calculated font size, taking superscript and subscript into account.
1532 1533 1534 |
# File 'lib/hexapdf/layout/style.rb', line 1532 def calculated_font_size (superscript || subscript ? 0.583 : 1) * font_size end |
#calculated_strikeout_position ⇒ Object
Returns the correct offset from the baseline for the strikeout line.
1551 1552 1553 1554 1555 1556 |
# File 'lib/hexapdf/layout/style.rb', line 1551 def calculated_strikeout_position calculated_text_rise + font.wrapped_font.strikeout_position * font.scaling_factor * font.pdf_object.glyph_scaling_factor * calculated_font_size - calculated_strikeout_thickness / 2.0 end |
#calculated_strikeout_thickness ⇒ Object
Returns the correct thickness for the strikeout line.
1559 1560 1561 1562 |
# File 'lib/hexapdf/layout/style.rb', line 1559 def calculated_strikeout_thickness font.wrapped_font.strikeout_thickness * font.scaling_factor * font.pdf_object.glyph_scaling_factor * calculated_font_size end |
#calculated_text_rise ⇒ Object
The calculated text rise, taking superscript and subscript into account.
1521 1522 1523 1524 1525 1526 1527 1528 1529 |
# File 'lib/hexapdf/layout/style.rb', line 1521 def calculated_text_rise if superscript text_rise + font_size * 0.33 elsif subscript text_rise - font_size * 0.20 else text_rise end end |
#calculated_underline_position ⇒ Object
Returns the correct offset from the baseline for the underline.
1537 1538 1539 1540 1541 1542 |
# File 'lib/hexapdf/layout/style.rb', line 1537 def calculated_underline_position calculated_text_rise + font.wrapped_font.underline_position * font.scaling_factor * font.pdf_object.glyph_scaling_factor * calculated_font_size - calculated_underline_thickness / 2.0 end |
#calculated_underline_thickness ⇒ Object
Returns the correct thickness for the underline.
1545 1546 1547 1548 |
# File 'lib/hexapdf/layout/style.rb', line 1545 def calculated_underline_thickness font.wrapped_font.underline_thickness * font.scaling_factor * font.pdf_object.glyph_scaling_factor * calculated_font_size end |
#clear_cache ⇒ Object
Clears all cached values.
This method needs to be called if the following style properties are changed and values were already cached: font, font_size, character_spacing, word_spacing, horizontal_scaling, ascender, descender.
1631 1632 1633 1634 1635 1636 |
# File 'lib/hexapdf/layout/style.rb', line 1631 def clear_cache @scaled_font_size = @scaled_character_spacing = @scaled_word_spacing = nil @scaled_horizontal_scaling = @scaled_font_ascender = @scaled_font_descender = nil @scaled_y_min = @scaled_y_max = nil @scaled_item_widths.clear end |
#initialize_copy(other) ⇒ Object
Duplicates the complex properties that can be modified, as well as the cache.
587 588 589 590 591 592 593 594 595 596 597 598 |
# File 'lib/hexapdf/layout/style.rb', line 587 def initialize_copy(other) super @scaled_item_widths = {}.compare_by_identity clear_cache @font_features = @font_features.dup if defined?(@font_features) @padding = @padding.dup if defined?(@padding) @margin = @margin.dup if defined?(@margin) @border = @border.dup if defined?(@border) @overlays = @overlays.dup if defined?(@overlays) @underlays = @underlays.dup if defined?(@underlays) end |
#name ⇒ Object
:method: text_line_wrapping_algorithm :call-seq:
text_line_wrapping_algorithm(algorithm = nil) {|items, width_block| block }
The line wrapping algorithm that should be used, defaults to TextLayouter::SimpleLineWrapping.
When setting the algorithm, either an object that responds to #call or a block can be used. See TextLayouter::SimpleLineWrapping#call for the needed method signature.
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 |
# File 'lib/hexapdf/layout/style.rb', line 1398 [ [:font, "raise HexaPDF::Error, 'No font set'"], [:font_size, 10], [:line_height, nil], [:character_spacing, 0], [:word_spacing, 0], [:horizontal_scaling, 100], [:text_rise, 0], [:font_features, {}], [:text_rendering_mode, "Content::TextRenderingMode::FILL", {setter: "Content::TextRenderingMode.normalize(value)"}], [:subscript, false, {setter: "value; superscript(false) if superscript", valid_values: [true, false]}], [:superscript, false, {setter: "value; subscript(false) if subscript", valid_values: [true, false]}], [:underline, false, {valid_values: [true, false]}], [:strikeout, false, {valid_values: [true, false]}], [:fill_color, "default_color"], [:fill_alpha, 1], [:stroke_color, "default_color"], [:stroke_alpha, 1], [:stroke_width, 1], [:stroke_cap_style, "Content::LineCapStyle::BUTT_CAP", {setter: "Content::LineCapStyle.normalize(value)"}], [:stroke_join_style, "Content::LineJoinStyle::MITER_JOIN", {setter: "Content::LineJoinStyle.normalize(value)"}], [:stroke_miter_limit, 10.0], [:stroke_dash_pattern, "Content::LineDashPattern.new", {setter: "Content::LineDashPattern.normalize(value, phase)", extra_args: ", phase = 0"}], [:text_align, :left, {valid_values: [:left, :center, :right, :justify]}], [:text_valign, :top, {valid_values: [:top, :center, :bottom]}], [:text_indent, 0], [:line_spacing, "LineSpacing.new(type: :single)", {setter: "LineSpacing.new(**(value.kind_of?(Symbol) || value.kind_of?(Numeric) ? " \ "{type: value, value: extra_arg} : value))", extra_args: ", extra_arg = nil"}], [:last_line_gap, false, {valid_values: [true, false]}], [:fill_horizontal, nil], [:background_color, nil], [:background_alpha, 1], [:padding, "Quad.new(0)", {setter: "Quad.new(value)"}], [:margin, "Quad.new(0)", {setter: "Quad.new(value)"}], [:border, "Border.new", {setter: "Border.new(**value)"}], [:overlays, "Layers.new", {setter: "Layers.new(value)"}], [:underlays, "Layers.new", {setter: "Layers.new(value)"}], [:position, :default], [:align, :left, {valid_values: [:left, :center, :right]}], [:valign, :top, {valid_values: [:top, :center, :bottom]}], [:mask_mode, :default, {valid_values: [:default, :none, :box, :fill_horizontal, :fill_frame_horizontal, :fill_vertical, :fill]}], ].each do |name, default, = {}| default = default.inspect unless default.kind_of?(String) setter = .delete(:setter) || "value" extra_args = .delete(:extra_args) || "" valid_values = .delete(:valid_values) raise ArgumentError, "Invalid keywords: #{.keys.join(', ')}" unless .empty? valid_values_const = "#{name}_valid_values".upcase const_set(valid_values_const, valid_values) module_eval(<<-EOF, __FILE__, __LINE__ + 1) def #{name}(value = UNSET#{extra_args}) if value == UNSET @#{name} ||= #{default} elsif #{valid_values_const} && !#{valid_values_const}.include?(value) raise ArgumentError, "\#{value.inspect} is not a valid #{name} value " \\ "(\#{#{valid_values_const}.map(&:inspect).join(', ')})" else @#{name} = #{setter} self end end def #{name}? defined?(@#{name}) end EOF alias_method("#{name}=", name) end |
#scaled_character_spacing ⇒ Object
The character spacing scaled appropriately.
1571 1572 1573 |
# File 'lib/hexapdf/layout/style.rb', line 1571 def scaled_character_spacing @scaled_character_spacing ||= character_spacing * scaled_horizontal_scaling end |
#scaled_font_ascender ⇒ Object
The ascender of the font scaled appropriately.
1586 1587 1588 1589 |
# File 'lib/hexapdf/layout/style.rb', line 1586 def scaled_font_ascender @scaled_font_ascender ||= font.wrapped_font.ascender * font.scaling_factor * font.pdf_object.glyph_scaling_factor * font_size end |
#scaled_font_descender ⇒ Object
The descender of the font scaled appropriately.
1592 1593 1594 1595 |
# File 'lib/hexapdf/layout/style.rb', line 1592 def scaled_font_descender @scaled_font_descender ||= font.wrapped_font.descender * font.scaling_factor * font.pdf_object.glyph_scaling_factor * font_size end |
#scaled_font_size ⇒ Object
The font size scaled appropriately.
1565 1566 1567 1568 |
# File 'lib/hexapdf/layout/style.rb', line 1565 def scaled_font_size @scaled_font_size ||= calculated_font_size * font.pdf_object.glyph_scaling_factor * scaled_horizontal_scaling end |
#scaled_horizontal_scaling ⇒ Object
The horizontal scaling scaled appropriately.
1581 1582 1583 |
# File 'lib/hexapdf/layout/style.rb', line 1581 def scaled_horizontal_scaling @scaled_horizontal_scaling ||= horizontal_scaling / 100.0 end |
#scaled_item_width(item) ⇒ Object
Returns the width of the item scaled appropriately (by taking font size, characters spacing, word spacing and horizontal scaling into account).
The item may be a (singleton) glyph object or an integer/float, i.e. items that can appear inside a TextFragment.
1616 1617 1618 1619 1620 1621 1622 1623 1624 |
# File 'lib/hexapdf/layout/style.rb', line 1616 def scaled_item_width(item) @scaled_item_widths[item] ||= if item.kind_of?(Numeric) -item * scaled_font_size else item.width * scaled_font_size + scaled_character_spacing + (item.apply_word_spacing? ? scaled_word_spacing : 0) end end |
#scaled_word_spacing ⇒ Object
The word spacing scaled appropriately.
1576 1577 1578 |
# File 'lib/hexapdf/layout/style.rb', line 1576 def scaled_word_spacing @scaled_word_spacing ||= word_spacing * scaled_horizontal_scaling end |
#scaled_y_max ⇒ Object
The maximum y-coordinate, calculated using the scaled ascender of the font and the line height or font size.
1606 1607 1608 1609 |
# File 'lib/hexapdf/layout/style.rb', line 1606 def scaled_y_max @scaled_y_max ||= scaled_font_ascender * (line_height || font_size) / font_size.to_f + calculated_text_rise end |
#scaled_y_min ⇒ Object
The minimum y-coordinate, calculated using the scaled descender of the font and the line height or font size.
1599 1600 1601 1602 |
# File 'lib/hexapdf/layout/style.rb', line 1599 def scaled_y_min @scaled_y_min ||= scaled_font_descender * (line_height || font_size) / font_size.to_f + calculated_text_rise end |
#update(**properties) ⇒ Object
:call-seq:
style.update(**properties) -> style
Updates the style’s properties using the key-value pairs specified by the properties
hash.
604 605 606 607 |
# File 'lib/hexapdf/layout/style.rb', line 604 def update(**properties) properties.each {|key, value| send(key, value) } self end |