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)
583 584 585 586 |
# File 'lib/hexapdf/layout/style.rb', line 583 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.
567 568 569 570 571 572 573 574 |
# File 'lib/hexapdf/layout/style.rb', line 567 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.
1560 1561 1562 |
# File 'lib/hexapdf/layout/style.rb', line 1560 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.
1579 1580 1581 1582 1583 1584 |
# File 'lib/hexapdf/layout/style.rb', line 1579 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.
1587 1588 1589 1590 |
# File 'lib/hexapdf/layout/style.rb', line 1587 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.
1549 1550 1551 1552 1553 1554 1555 1556 1557 |
# File 'lib/hexapdf/layout/style.rb', line 1549 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.
1565 1566 1567 1568 1569 1570 |
# File 'lib/hexapdf/layout/style.rb', line 1565 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.
1573 1574 1575 1576 |
# File 'lib/hexapdf/layout/style.rb', line 1573 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.
1659 1660 1661 1662 1663 1664 |
# File 'lib/hexapdf/layout/style.rb', line 1659 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.
589 590 591 592 593 594 595 596 597 598 599 600 |
# File 'lib/hexapdf/layout/style.rb', line 589 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.
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 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 |
# File 'lib/hexapdf/layout/style.rb', line 1425 [ [: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]}], [:overflow, :error], ].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.
1599 1600 1601 |
# File 'lib/hexapdf/layout/style.rb', line 1599 def scaled_character_spacing @scaled_character_spacing ||= character_spacing * scaled_horizontal_scaling end |
#scaled_font_ascender ⇒ Object
The ascender of the font scaled appropriately.
1614 1615 1616 1617 |
# File 'lib/hexapdf/layout/style.rb', line 1614 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.
1620 1621 1622 1623 |
# File 'lib/hexapdf/layout/style.rb', line 1620 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.
1593 1594 1595 1596 |
# File 'lib/hexapdf/layout/style.rb', line 1593 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.
1609 1610 1611 |
# File 'lib/hexapdf/layout/style.rb', line 1609 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.
1644 1645 1646 1647 1648 1649 1650 1651 1652 |
# File 'lib/hexapdf/layout/style.rb', line 1644 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.
1604 1605 1606 |
# File 'lib/hexapdf/layout/style.rb', line 1604 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.
1634 1635 1636 1637 |
# File 'lib/hexapdf/layout/style.rb', line 1634 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.
1627 1628 1629 1630 |
# File 'lib/hexapdf/layout/style.rb', line 1627 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.
606 607 608 609 |
# File 'lib/hexapdf/layout/style.rb', line 606 def update(**properties) properties.each {|key, value| send(key, value) } self end |