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.
1558 1559 1560 |
# File 'lib/hexapdf/layout/style.rb', line 1558 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.
1577 1578 1579 1580 1581 1582 |
# File 'lib/hexapdf/layout/style.rb', line 1577 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.
1585 1586 1587 1588 |
# File 'lib/hexapdf/layout/style.rb', line 1585 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.
1547 1548 1549 1550 1551 1552 1553 1554 1555 |
# File 'lib/hexapdf/layout/style.rb', line 1547 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.
1563 1564 1565 1566 1567 1568 |
# File 'lib/hexapdf/layout/style.rb', line 1563 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.
1571 1572 1573 1574 |
# File 'lib/hexapdf/layout/style.rb', line 1571 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.
1657 1658 1659 1660 1661 1662 |
# File 'lib/hexapdf/layout/style.rb', line 1657 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.
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 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 |
# File 'lib/hexapdf/layout/style.rb', line 1423 [ [: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.
1597 1598 1599 |
# File 'lib/hexapdf/layout/style.rb', line 1597 def scaled_character_spacing @scaled_character_spacing ||= character_spacing * scaled_horizontal_scaling end |
#scaled_font_ascender ⇒ Object
The ascender of the font scaled appropriately.
1612 1613 1614 1615 |
# File 'lib/hexapdf/layout/style.rb', line 1612 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.
1618 1619 1620 1621 |
# File 'lib/hexapdf/layout/style.rb', line 1618 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.
1591 1592 1593 1594 |
# File 'lib/hexapdf/layout/style.rb', line 1591 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.
1607 1608 1609 |
# File 'lib/hexapdf/layout/style.rb', line 1607 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.
1642 1643 1644 1645 1646 1647 1648 1649 1650 |
# File 'lib/hexapdf/layout/style.rb', line 1642 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.
1602 1603 1604 |
# File 'lib/hexapdf/layout/style.rb', line 1602 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.
1632 1633 1634 1635 |
# File 'lib/hexapdf/layout/style.rb', line 1632 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.
1625 1626 1627 1628 |
# File 'lib/hexapdf/layout/style.rb', line 1625 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 |