lib/thinreports/generator/pdf/document/graphics/text.rb in thinreports-0.9.1 vs lib/thinreports/generator/pdf/document/graphics/text.rb in thinreports-0.10.0
- old
+ new
@@ -1,161 +1,176 @@
-# coding: utf-8
+# frozen_string_literal: true
module Thinreports
module Generator
+ class PDF
+ module Graphics
+ # @param [String] content
+ # @param [Numeric, String] x
+ # @param [Numeric, String] y
+ # @param [Numeric, String] w
+ # @param [Numeric, String] h
+ # @param [Hash] attrs ({})
+ # @option attrs [String] :font
+ # @option attrs [Numeric, String] :size
+ # @option attrs [String] :color
+ # @option attrs [Array<:bold, :italic, :underline, :strikethrough>]
+ # :styles (nil)
+ # @option attrs [:left, :center, :right] :align (:left)
+ # @option attrs [:top, :center, :bottom] :valign (:top)
+ # @option attrs [Numeric, String] :line_height The total height of an text line.
+ # @option attrs [Numeric, String] :letter_spacing
+ # @option attrs [Boolean] :single (false)
+ # @option attrs [:trancate, :shrink_to_fit, :expand] :overflow (:trancate)
+ # @option attrs [:none, :break_word] :word_wrap (:none)
+ def text_box(content, x, y, w, h, attrs = {})
+ w, h = s2f(w, h)
- module PDF::Graphics
- # @param [String] content
- # @param [Numeric, String] x
- # @param [Numeric, String] y
- # @param [Numeric, String] w
- # @param [Numeric, String] h
- # @param [Hash] attrs ({})
- # @option attrs [String] :font
- # @option attrs [Numeric, String] :size
- # @option attrs [String] :color
- # @option attrs [Array<:bold, :italic, :underline, :strikethrough>]
- # :styles (nil)
- # @option attrs [:left, :center, :right] :align (:left)
- # @option attrs [:top, :center, :bottom] :valign (:top)
- # @option attrs [Numeric, String] :line_height The total height of an text line.
- # @option attrs [Numeric, String] :letter_spacing
- # @option attrs [Boolean] :single (false)
- # @option attrs [:trancate, :shrink_to_fit, :expand] :overflow (:trancate)
- # @option attrs [:none, :break_word] :word_wrap (:none)
- def text_box(content, x, y, w, h, attrs = {})
- w, h = s2f(w, h)
- box_attrs = text_box_attrs(x, y, w, h, single: attrs.delete(:single),
- overflow: attrs[:overflow])
- # Do not break by word unless :word_wrap is :break_word
- content = text_without_line_wrap(content) if attrs[:word_wrap] == :none
+ box_attrs = text_box_attrs(
+ x, y, w, h,
+ single: attrs.delete(:single),
+ overflow: attrs[:overflow]
+ )
- with_text_styles(attrs) do |built_attrs, font_styles|
- pdf.formatted_text_box([{ text: content, styles: font_styles }],
- built_attrs.merge(box_attrs))
+ # Do not break by word unless :word_wrap is :break_word
+ content = text_without_line_wrap(content) if attrs[:word_wrap] == :none
+
+ with_text_styles(attrs) do |built_attrs, font_styles|
+ pdf.formatted_text_box(
+ [{ text: content, styles: font_styles }],
+ built_attrs.merge(box_attrs)
+ )
+ end
+ # rubocop:disable Lint/HandleExceptions
+ rescue Prawn::Errors::CannotFit
+ # Nothing to do.
+ #
+ # When the area is too small compared
+ # with the content and the style of the text.
+ # (See prawn/core/text/formatted/line_wrap.rb#L185)
end
- rescue Prawn::Errors::CannotFit
- # Nothing to do.
- #
- # When the area is too small compared
- # with the content and the style of the text.
- # (See prawn/core/text/formatted/line_wrap.rb#L185)
- end
- # @see #text_box
- def text(content, x, y, w, h, attrs = {})
- # Set the :overflow property to :shirink_to_fit.
- text_box(content, x, y, w, h, { overflow: :shirink_to_fit }.merge(attrs))
- end
+ # @see #text_box
+ def text(content, x, y, w, h, attrs = {})
+ # Set the :overflow property to :shirink_to_fit.
+ text_box(content, x, y, w, h, { overflow: :shirink_to_fit }.merge(attrs))
+ end
- private
+ private
- # @param x (see #text_box)
- # @param y (see #text_box)
- # @param w (see #text_box)
- # @param h (see #text_box)
- # @param [Hash] states
- # @option states [Boolean] :single
- # @option states [Symbold] :overflow
- # @return [Hash]
- def text_box_attrs(x, y, w, h, states = {})
- attrs = {at: pos(x, y),
- width: s2f(w)}
- if states[:single]
- states[:overflow] != :expand ? attrs.merge(single_line: true) : attrs
- else
- attrs.merge(height: s2f(h))
+ # @param x (see #text_box)
+ # @param y (see #text_box)
+ # @param w (see #text_box)
+ # @param h (see #text_box)
+ # @param [Hash] states
+ # @option states [Boolean] :single
+ # @option states [Symbold] :overflow
+ # @return [Hash]
+ def text_box_attrs(x, y, w, h, states = {})
+ attrs = {
+ at: pos(x, y),
+ width: s2f(w)
+ }
+ if states[:single]
+ states[:overflow] != :expand ? attrs.merge(single_line: true) : attrs
+ else
+ attrs.merge(height: s2f(h))
+ end
end
- end
- # @param attrs (see #text)
- # @yield [built_attrs, font_styles]
- # @yieldparam [Hash] built_attrs The finalized attributes.
- # @yieldparam [Array] font_styles The finalized styles.
- def with_text_styles(attrs, &block)
- # When no color is given, do not draw.
- return unless attrs.key?(:color) && attrs[:color] != 'none'
+ # @param attrs (see #text)
+ # @yield [built_attrs, font_styles]
+ # @yieldparam [Hash] built_attrs The finalized attributes.
+ # @yieldparam [Array] font_styles The finalized styles.
+ # rubocop:disable Metrics/AbcSize
+ def with_text_styles(attrs, &block)
+ # When no color is given, do not draw.
+ return unless attrs.key?(:color) && attrs[:color] != 'none'
- save_graphics_state
+ save_graphics_state
- fontinfo = {name: attrs.delete(:font).to_s,
- color: parse_color(attrs.delete(:color)),
- size: s2f(attrs.delete(:size))}
+ fontinfo = {
+ name: attrs.delete(:font).to_s,
+ color: parse_color(attrs.delete(:color)),
+ size: s2f(attrs.delete(:size))
+ }
- # Add the specified value to :leading option.
- line_height = attrs.delete(:line_height)
- if line_height
- attrs[:leading] = text_line_leading(s2f(line_height),
- name: fontinfo[:name],
- size: fontinfo[:size])
- end
+ # Add the specified value to :leading option.
+ line_height = attrs.delete(:line_height)
+ if line_height
+ attrs[:leading] = text_line_leading(
+ s2f(line_height),
+ name: fontinfo[:name],
+ size: fontinfo[:size]
+ )
+ end
- # Set the :character_spacing option.
- spacing = attrs.delete(:letter_spacing)
- attrs[:character_spacing] = s2f(spacing) if spacing
+ # Set the :character_spacing option.
+ spacing = attrs.delete(:letter_spacing)
+ attrs[:character_spacing] = s2f(spacing) if spacing
- # Or... with_font_styles(attrs, fontinfo, &block)
- with_font_styles(attrs, fontinfo) do |modified_attrs, styles|
- block.call(modified_attrs, styles)
+ # Or... with_font_styles(attrs, fontinfo, &block)
+ with_font_styles(attrs, fontinfo) do |modified_attrs, styles|
+ block.call(modified_attrs, styles)
+ end
+
+ restore_graphics_state
end
- restore_graphics_state
- end
+ # @param [Numeric] line_height
+ # @param [Hash] font
+ # @option font [String] :name Name of font.
+ # @option font [Numeric] :size Size of font.
+ # @return [Numeric]
+ def text_line_leading(line_height, font)
+ line_height - pdf.font(font[:name], size: font[:size]).height
+ end
- # @param [Numeric] line_height
- # @param [Hash] font
- # @option font [String] :name Name of font.
- # @option font [Numeric] :size Size of font.
- # @return [Numeric]
- def text_line_leading(line_height, font)
- line_height - pdf.font(font[:name], size: font[:size]).height
- end
+ # @param [String] content
+ # @return [String]
+ def text_without_line_wrap(content)
+ content.gsub(/ /, Prawn::Text::NBSP)
+ end
- # @param [String] content
- # @return [String]
- def text_without_line_wrap(content)
- content.gsub(/ /, Prawn::Text::NBSP)
- end
+ # @param [Hash] attrs
+ # @param [Hash] font
+ # @option font [String] :color
+ # @option font [Numeric] :size
+ # @option font [String] :name
+ # @yield [attributes, styles]
+ # @yieldparam [Hash] modified_attrs
+ # @yieldparam [Array] styles
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
+ def with_font_styles(attrs, font, &block)
+ # Building font styles.
+ styles = attrs.delete(:styles)
- # @param [Hash] attrs
- # @param [Hash] font
- # @option font [String] :color
- # @option font [Numeric] :size
- # @option font [String] :name
- # @yield [attributes, styles]
- # @yieldparam [Hash] modified_attrs
- # @yieldparam [Array] styles
- def with_font_styles(attrs, font, &block)
- # Building font styles.
- styles = attrs.delete(:styles)
-
- if styles
- manual, styles = styles.partition do |style|
- [:bold, :italic].include?(style) && !font_has_style?(font[:name], style)
+ if styles
+ manual, styles = styles.partition do |style|
+ %i[bold italic].include?(style) && !font_has_style?(font[:name], style)
+ end
end
- end
- # Emulate bold style.
- if manual && manual.include?(:bold)
- pdf.stroke_color(font[:color])
- pdf.line_width(font[:size] * 0.025)
+ # Emulate bold style.
+ if manual && manual.include?(:bold)
+ pdf.stroke_color(font[:color])
+ pdf.line_width(font[:size] * 0.025)
- # Change rendering mode to :fill_stroke.
- attrs[:mode] = :fill_stroke
- end
+ # Change rendering mode to :fill_stroke.
+ attrs[:mode] = :fill_stroke
+ end
- # Emulate italic style.
- if manual && manual.include?(:italic)
- # FIXME
- # pdf.transformation_matrix(1, 0, 0.26, 1, 0, 0)
- end
+ # Emulate italic style.
+ if manual && manual.include?(:italic)
+ # FIXME
+ # pdf.transformation_matrix(1, 0, 0.26, 1, 0, 0)
+ end
- pdf.font(font[:name], size: font[:size]) do
- pdf.fill_color(font[:color])
- block.call(attrs, styles || [])
+ pdf.font(font[:name], size: font[:size]) do
+ pdf.fill_color(font[:color])
+ block.call(attrs, styles || [])
+ end
end
end
-
end
-
end
end