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 descender of the font.
-
#scaled_y_min ⇒ Object
The minimum y-coordinate, calculated using the scaled descender of the font.
-
#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, align: :center, valign: center)
549 550 551 552 |
# File 'lib/hexapdf/layout/style.rb', line 549 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
styleis already a Style object, it is just returned. -
If
styleis a hash, a new Style object with the style properties specified by the hash -
is created.
-
If
styleisnil, a new Style object with only default values is created.
533 534 535 536 537 538 539 540 |
# File 'lib/hexapdf/layout/style.rb', line 533 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.
1341 1342 1343 |
# File 'lib/hexapdf/layout/style.rb', line 1341 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.
1358 1359 1360 1361 1362 |
# File 'lib/hexapdf/layout/style.rb', line 1358 def calculated_strikeout_position calculated_text_rise + calculated_font_size / 1000.0 * font.wrapped_font.strikeout_position * font.scaling_factor - calculated_strikeout_thickness / 2.0 end |
#calculated_strikeout_thickness ⇒ Object
Returns the correct thickness for the strikeout line.
1365 1366 1367 |
# File 'lib/hexapdf/layout/style.rb', line 1365 def calculated_strikeout_thickness calculated_font_size / 1000.0 * font.wrapped_font.strikeout_thickness * font.scaling_factor end |
#calculated_text_rise ⇒ Object
The calculated text rise, taking superscript and subscript into account.
1330 1331 1332 1333 1334 1335 1336 1337 1338 |
# File 'lib/hexapdf/layout/style.rb', line 1330 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.
1346 1347 1348 1349 1350 |
# File 'lib/hexapdf/layout/style.rb', line 1346 def calculated_underline_position calculated_text_rise + calculated_font_size / 1000.0 * font.wrapped_font.underline_position * font.scaling_factor - calculated_underline_thickness / 2.0 end |
#calculated_underline_thickness ⇒ Object
Returns the correct thickness for the underline.
1353 1354 1355 |
# File 'lib/hexapdf/layout/style.rb', line 1353 def calculated_underline_thickness calculated_font_size / 1000.0 * font.wrapped_font.underline_thickness * font.scaling_factor 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.
1430 1431 1432 1433 1434 1435 |
# File 'lib/hexapdf/layout/style.rb', line 1430 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.
555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/hexapdf/layout/style.rb', line 555 def initialize_copy(other) super @scaled_item_widths = {} 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.
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 |
# File 'lib/hexapdf/layout/style.rb', line 1212 [ [:font, "raise HexaPDF::Error, 'No font set'"], [:font_size, 10], [: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"}], [:align, :left, {valid_values: [:left, :center, :right, :justify]}], [: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]}], [: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, {valid_values: [:default, :float, :flow, :absolute]}], [:position_hint, nil], ].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.
1376 1377 1378 |
# File 'lib/hexapdf/layout/style.rb', line 1376 def scaled_character_spacing @scaled_character_spacing ||= character_spacing * scaled_horizontal_scaling end |
#scaled_font_ascender ⇒ Object
The ascender of the font scaled appropriately.
1391 1392 1393 |
# File 'lib/hexapdf/layout/style.rb', line 1391 def scaled_font_ascender @scaled_font_ascender ||= font.wrapped_font.ascender * font.scaling_factor * font_size / 1000 end |
#scaled_font_descender ⇒ Object
The descender of the font scaled appropriately.
1396 1397 1398 |
# File 'lib/hexapdf/layout/style.rb', line 1396 def scaled_font_descender @scaled_font_descender ||= font.wrapped_font.descender * font.scaling_factor * font_size / 1000 end |
#scaled_font_size ⇒ Object
The font size scaled appropriately.
1370 1371 1372 1373 |
# File 'lib/hexapdf/layout/style.rb', line 1370 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.
1386 1387 1388 |
# File 'lib/hexapdf/layout/style.rb', line 1386 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.
1415 1416 1417 1418 1419 1420 1421 1422 1423 |
# File 'lib/hexapdf/layout/style.rb', line 1415 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.
1381 1382 1383 |
# File 'lib/hexapdf/layout/style.rb', line 1381 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 descender of the font.
1406 1407 1408 |
# File 'lib/hexapdf/layout/style.rb', line 1406 def scaled_y_max @scaled_y_max ||= scaled_font_ascender + calculated_text_rise end |
#scaled_y_min ⇒ Object
The minimum y-coordinate, calculated using the scaled descender of the font.
1401 1402 1403 |
# File 'lib/hexapdf/layout/style.rb', line 1401 def scaled_y_min @scaled_y_min ||= scaled_font_descender + 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.
572 573 574 575 |
# File 'lib/hexapdf/layout/style.rb', line 572 def update(**properties) properties.each {|key, value| send(key, value) } self end |