thinreports 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +41 -0
  3. data/.travis.yml +4 -6
  4. data/CHANGELOG.md +21 -2
  5. data/Gemfile +2 -4
  6. data/README.md +4 -5
  7. data/Rakefile +7 -8
  8. data/examples/character_spacing/character_spacing.rb +1 -1
  9. data/examples/dynamic_image/dynamic_image.rb +3 -3
  10. data/examples/dynamic_style/dynamic_style.rb +1 -1
  11. data/examples/eudc/eudc.rb +1 -1
  12. data/examples/helper.rb +2 -2
  13. data/examples/hidden_shapes/hidden_shapes.rb +1 -1
  14. data/examples/list_events/list_events.rb +1 -1
  15. data/examples/list_manual_generation/list_manual_generation.rb +1 -1
  16. data/examples/list_page_number/list_page_number.rb +1 -1
  17. data/examples/page_number/page_number.rb +1 -1
  18. data/examples/palleted_png/palleted_png.rb +1 -3
  19. data/examples/password_setting/password_setting.rb +1 -1
  20. data/examples/report_callbacks/report_callbacks.rb +1 -1
  21. data/examples/single_line_tblock/single_line_tblock.rb +1 -1
  22. data/examples/tblock_overflow/tblock_overflow.rb +1 -1
  23. data/examples/tblock_styles/tblock_styles.rb +1 -1
  24. data/examples/text_align/text_align.rb +1 -1
  25. data/examples/typeB_page_size/typeB_page_size.rb +1 -1
  26. data/examples/word_wrap/word_wrap.rb +1 -1
  27. data/lib/thinreports.rb +16 -15
  28. data/lib/thinreports/config.rb +2 -24
  29. data/lib/thinreports/core/errors.rb +6 -17
  30. data/lib/thinreports/core/format/base.rb +62 -61
  31. data/lib/thinreports/core/shape.rb +13 -14
  32. data/lib/thinreports/core/shape/base.rb +3 -12
  33. data/lib/thinreports/core/shape/base/interface.rb +35 -32
  34. data/lib/thinreports/core/shape/base/internal.rb +45 -43
  35. data/lib/thinreports/core/shape/basic.rb +12 -12
  36. data/lib/thinreports/core/shape/basic/block_format.rb +8 -6
  37. data/lib/thinreports/core/shape/basic/block_interface.rb +24 -22
  38. data/lib/thinreports/core/shape/basic/block_internal.rb +28 -26
  39. data/lib/thinreports/core/shape/basic/format.rb +11 -9
  40. data/lib/thinreports/core/shape/basic/interface.rb +79 -77
  41. data/lib/thinreports/core/shape/basic/internal.rb +17 -14
  42. data/lib/thinreports/core/shape/image_block.rb +9 -9
  43. data/lib/thinreports/core/shape/image_block/format.rb +7 -5
  44. data/lib/thinreports/core/shape/image_block/interface.rb +15 -13
  45. data/lib/thinreports/core/shape/image_block/internal.rb +10 -8
  46. data/lib/thinreports/core/shape/list.rb +13 -13
  47. data/lib/thinreports/core/shape/list/format.rb +83 -77
  48. data/lib/thinreports/core/shape/list/manager.rb +182 -176
  49. data/lib/thinreports/core/shape/list/page.rb +94 -93
  50. data/lib/thinreports/core/shape/list/page_state.rb +42 -40
  51. data/lib/thinreports/core/shape/list/section_format.rb +28 -26
  52. data/lib/thinreports/core/shape/list/section_interface.rb +42 -40
  53. data/lib/thinreports/core/shape/list/section_internal.rb +21 -19
  54. data/lib/thinreports/core/shape/manager.rb +4 -13
  55. data/lib/thinreports/core/shape/manager/format.rb +21 -19
  56. data/lib/thinreports/core/shape/manager/internal.rb +88 -84
  57. data/lib/thinreports/core/shape/manager/target.rb +93 -95
  58. data/lib/thinreports/core/shape/page_number.rb +9 -9
  59. data/lib/thinreports/core/shape/page_number/format.rb +20 -18
  60. data/lib/thinreports/core/shape/page_number/interface.rb +20 -18
  61. data/lib/thinreports/core/shape/page_number/internal.rb +47 -44
  62. data/lib/thinreports/core/shape/style.rb +5 -14
  63. data/lib/thinreports/core/shape/style/base.rb +121 -120
  64. data/lib/thinreports/core/shape/style/basic.rb +12 -10
  65. data/lib/thinreports/core/shape/style/graphic.rb +35 -33
  66. data/lib/thinreports/core/shape/style/text.rb +113 -107
  67. data/lib/thinreports/core/shape/text.rb +9 -9
  68. data/lib/thinreports/core/shape/text/format.rb +10 -9
  69. data/lib/thinreports/core/shape/text/interface.rb +13 -11
  70. data/lib/thinreports/core/shape/text/internal.rb +14 -12
  71. data/lib/thinreports/core/shape/text_block.rb +10 -10
  72. data/lib/thinreports/core/shape/text_block/format.rb +35 -33
  73. data/lib/thinreports/core/shape/text_block/formatter.rb +26 -24
  74. data/lib/thinreports/core/shape/text_block/formatter/basic.rb +25 -25
  75. data/lib/thinreports/core/shape/text_block/formatter/datetime.rb +15 -12
  76. data/lib/thinreports/core/shape/text_block/formatter/number.rb +45 -39
  77. data/lib/thinreports/core/shape/text_block/formatter/padding.rb +17 -14
  78. data/lib/thinreports/core/shape/text_block/interface.rb +25 -23
  79. data/lib/thinreports/core/shape/text_block/internal.rb +68 -68
  80. data/lib/thinreports/core/utils.rb +4 -3
  81. data/lib/thinreports/generator/pdf.rb +24 -25
  82. data/lib/thinreports/generator/pdf/document.rb +109 -110
  83. data/lib/thinreports/generator/pdf/document/draw_shape.rb +58 -51
  84. data/lib/thinreports/generator/pdf/document/draw_template_items.rb +51 -47
  85. data/lib/thinreports/generator/pdf/document/font.rb +62 -59
  86. data/lib/thinreports/generator/pdf/document/graphics.rb +32 -33
  87. data/lib/thinreports/generator/pdf/document/graphics/attributes.rb +122 -121
  88. data/lib/thinreports/generator/pdf/document/graphics/basic.rb +113 -114
  89. data/lib/thinreports/generator/pdf/document/graphics/image.rb +58 -150
  90. data/lib/thinreports/generator/pdf/document/graphics/text.rb +152 -137
  91. data/lib/thinreports/generator/pdf/document/page.rb +63 -64
  92. data/lib/thinreports/generator/pdf/document/parse_color.rb +37 -37
  93. data/lib/thinreports/generator/pdf/drawer/base.rb +41 -41
  94. data/lib/thinreports/generator/pdf/drawer/list.rb +48 -45
  95. data/lib/thinreports/generator/pdf/drawer/list_section.rb +42 -40
  96. data/lib/thinreports/generator/pdf/drawer/page.rb +101 -96
  97. data/lib/thinreports/generator/pdf/prawn_ext.rb +4 -30
  98. data/lib/thinreports/generator/pdf/prawn_ext/calc_image_dimensions.rb +34 -0
  99. data/lib/thinreports/generator/pdf/prawn_ext/width_of.rb +29 -0
  100. data/lib/thinreports/layout.rb +5 -7
  101. data/lib/thinreports/layout/base.rb +5 -7
  102. data/lib/thinreports/layout/format.rb +18 -13
  103. data/lib/thinreports/layout/legacy_schema.rb +18 -10
  104. data/lib/thinreports/layout/version.rb +22 -25
  105. data/lib/thinreports/report.rb +4 -6
  106. data/lib/thinreports/report/base.rb +24 -51
  107. data/lib/thinreports/report/internal.rb +9 -11
  108. data/lib/thinreports/report/page.rb +5 -6
  109. data/lib/thinreports/version.rb +2 -2
  110. data/test/schema_helper.rb +4 -3
  111. data/test/test_helper.rb +9 -3
  112. data/test/unit/core/format/test_base.rb +1 -1
  113. data/test/unit/core/shape/base/test_internal.rb +1 -1
  114. data/test/unit/core/shape/basic/test_block_format.rb +1 -1
  115. data/test/unit/core/shape/basic/test_block_interface.rb +1 -1
  116. data/test/unit/core/shape/basic/test_block_internal.rb +1 -1
  117. data/test/unit/core/shape/basic/test_format.rb +1 -1
  118. data/test/unit/core/shape/basic/test_interface.rb +1 -1
  119. data/test/unit/core/shape/basic/test_internal.rb +1 -1
  120. data/test/unit/core/shape/image_block/test_interface.rb +1 -1
  121. data/test/unit/core/shape/image_block/test_internal.rb +1 -1
  122. data/test/unit/core/shape/list/test_format.rb +1 -1
  123. data/test/unit/core/shape/list/test_manager.rb +4 -4
  124. data/test/unit/core/shape/list/test_page.rb +1 -1
  125. data/test/unit/core/shape/list/test_page_state.rb +1 -1
  126. data/test/unit/core/shape/list/test_section_format.rb +1 -1
  127. data/test/unit/core/shape/list/test_section_interface.rb +2 -2
  128. data/test/unit/core/shape/list/test_section_internal.rb +1 -1
  129. data/test/unit/core/shape/manager/test_format.rb +2 -2
  130. data/test/unit/core/shape/manager/test_internal.rb +3 -3
  131. data/test/unit/core/shape/manager/test_target.rb +1 -1
  132. data/test/unit/core/shape/page_number/test_format.rb +1 -1
  133. data/test/unit/core/shape/page_number/test_interface.rb +1 -1
  134. data/test/unit/core/shape/page_number/test_internal.rb +1 -1
  135. data/test/unit/core/shape/styles/test_base.rb +1 -1
  136. data/test/unit/core/shape/styles/test_basic.rb +1 -1
  137. data/test/unit/core/shape/styles/test_graphic.rb +1 -1
  138. data/test/unit/core/shape/styles/test_text.rb +1 -1
  139. data/test/unit/core/shape/text/test_format.rb +1 -1
  140. data/test/unit/core/shape/text/test_internal.rb +1 -1
  141. data/test/unit/core/shape/text_block/formatter/test_basic.rb +1 -1
  142. data/test/unit/core/shape/text_block/formatter/test_datetime.rb +1 -1
  143. data/test/unit/core/shape/text_block/formatter/test_number.rb +1 -1
  144. data/test/unit/core/shape/text_block/formatter/test_padding.rb +2 -2
  145. data/test/unit/core/shape/text_block/test_format.rb +1 -1
  146. data/test/unit/core/shape/text_block/test_formatter.rb +1 -1
  147. data/test/unit/core/shape/text_block/test_interface.rb +1 -1
  148. data/test/unit/core/shape/text_block/test_internal.rb +3 -3
  149. data/test/unit/core/test_shape.rb +1 -1
  150. data/test/unit/core/test_utils.rb +2 -2
  151. data/test/unit/generator/pdf/document/graphics/test_attributes.rb +1 -1
  152. data/test/unit/generator/pdf/document/graphics/test_basic.rb +2 -1
  153. data/test/unit/generator/pdf/document/graphics/test_image.rb +27 -131
  154. data/test/unit/generator/pdf/document/graphics/test_text.rb +1 -1
  155. data/test/unit/generator/pdf/document/test_font.rb +2 -2
  156. data/test/unit/generator/pdf/document/test_graphics.rb +1 -1
  157. data/test/unit/generator/pdf/document/test_page.rb +7 -7
  158. data/test/unit/generator/pdf/document/test_parse_color.rb +1 -1
  159. data/test/unit/generator/pdf/prawn_ext/test_calc_image_dimensions.rb +41 -0
  160. data/test/unit/generator/pdf/prawn_ext/test_width_of.rb +22 -0
  161. data/test/unit/generator/pdf/test_document.rb +8 -6
  162. data/test/unit/generator/test_pdf.rb +12 -10
  163. data/test/unit/layout/test_base.rb +1 -1
  164. data/test/unit/layout/test_format.rb +2 -2
  165. data/test/unit/layout/test_legacy_schema.rb +4 -4
  166. data/test/unit/layout/test_version.rb +11 -80
  167. data/test/unit/report/test_base.rb +45 -59
  168. data/test/unit/report/test_internal.rb +1 -1
  169. data/test/unit/test_config.rb +1 -16
  170. data/test/unit/test_layout.rb +1 -1
  171. data/test/unit/test_report.rb +1 -1
  172. data/thinreports.gemspec +11 -14
  173. metadata +42 -103
  174. data/lib/thinreports/generator.rb +0 -29
  175. data/lib/thinreports/generator/base.rb +0 -40
  176. data/lib/thinreports/generator/configuration.rb +0 -31
  177. data/lib/thinreports/report/events.rb +0 -32
  178. data/test/unit/generator/test_base.rb +0 -40
  179. data/test/unit/generator/test_configuration.rb +0 -21
@@ -1,172 +1,80 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'tempfile'
4
4
  require 'base64'
5
5
  require 'digest/md5'
6
- require 'chunky_png'
7
6
 
8
7
  module Thinreports
9
8
  module Generator
10
-
11
- module PDF::Graphics
12
- # @param [String] filename
13
- # @param [Numeric, Strng] x
14
- # @param [Numeric, Strng] y
15
- # @param [Numeric, Strng] w
16
- # @param [Numeric, Strng] h
17
- def image(filename, x, y, w, h)
18
- w, h = s2f(w, h)
19
- pdf.image(filename, at: pos(x, y), width: w, height: h)
20
- end
21
-
22
- # @param [String] image_type Mime-type of image
23
- # @param [String] base64
24
- # @param [Numeric, Strng] x
25
- # @param [Numeric, Strng] y
26
- # @param [Numeric, Strng] w
27
- # @param [Numeric, Strng] h
28
- def base64image(image_type, base64_data, x, y, w, h)
29
- image_path = normalize_image_from_base64(image_type, base64_data)
30
- image(image_path, x, y, w, h)
31
- end
32
-
33
- # @param [String, IO] file
34
- # @param [Numeric, Strng] x
35
- # @param [Numeric, Strng] y
36
- # @param [Numeric, Strng] w
37
- # @param [Numeric, Strng] h
38
- # @param [Hash] options
39
- # @option options [:left, :center, :right] :position_x (:left)
40
- # @option options [:top, :center, :bottom] :position_y (:top)
41
- def image_box(file, x, y, w, h, options = {})
42
- image_data_or_path = normalize_image_from_file(file)
43
-
44
- w, h = s2f(w, h)
45
- pdf.bounding_box(pos(x, y), width: w, height: h) do
46
- pdf.image(
47
- image_data_or_path,
48
- position: options[:position_x] || :left,
49
- vposition: options[:position_y] || :top,
50
- auto_fit: [w, h]
51
- )
9
+ class PDF
10
+ module Graphics
11
+ # @param [String, IO] filename_or_io
12
+ # @param [Numeric, Strng] x
13
+ # @param [Numeric, Strng] y
14
+ # @param [Numeric, Strng] w
15
+ # @param [Numeric, Strng] h
16
+ def image(filename_or_io, x, y, w, h)
17
+ w, h = s2f(w, h)
18
+ pdf.image(filename_or_io, at: pos(x, y), width: w, height: h)
52
19
  end
53
- end
54
-
55
- def normalize_image_from_base64(image_type, base64_string)
56
- raw_image_data = Base64.decode64(base64_string)
57
-
58
- image_data =
59
- if png_conversion_enabled? && image_type == 'image/png'
60
- png_normalizer = PNGNormalizer.load_blob(raw_image_data)
61
-
62
- if png_normalizer.need_normalize?
63
- png_normalizer.normalize
64
- else
65
- raw_image_data
66
- end
67
- else
68
- raw_image_data
69
- end
70
20
 
71
- image_id = Digest::MD5.hexdigest(base64_string)
72
- create_temp_imagefile(image_id, image_data)
73
- end
74
-
75
- def normalize_image_from_file(file)
76
- return file unless file.is_a?(String)
77
-
78
- filename = file
79
- extname = File.extname(filename)
80
-
81
- return filename unless png_conversion_enabled?
82
- return filename unless extname.downcase == '.png' || extname.empty?
83
-
84
- return temp_image_registry[filename].path if temp_image_registry.key?(filename)
85
-
86
- png_normalizer = PNGNormalizer.load_file(filename)
87
-
88
- # Returns the original filename when the image is not PNG.
89
- return filename if png_normalizer.nil?
90
- return filename unless png_normalizer.need_normalize?
91
-
92
- image_id = filename
93
- image_data = png_normalizer.normalize
94
-
95
- create_temp_imagefile(image_id, image_data)
96
- end
97
-
98
- def clean_temp_images
99
- temp_image_registry.each_value do |image_path|
100
- File.delete(image_path) if File.exist?(image_path)
101
- end
102
- end
103
-
104
- def temp_image_registry
105
- @temp_image_registry ||= {}
106
- end
107
-
108
- # @param [String] image_id
109
- # @param [String] image_data
110
- # @return [String] Path to imagefile
111
- def create_temp_imagefile(image_id, image_data)
112
- temp_image_registry[image_id] ||= begin
113
- file = Tempfile.new('temp-image')
114
- file.binmode
115
- file.write(image_data)
116
- file.open
117
- file
118
- end
119
- temp_image_registry[image_id].path
120
- end
121
-
122
- def png_conversion_enabled?
123
- Thinreports.config.convert_palleted_transparency_png
124
- end
125
-
126
- class PNGNormalizer
127
- def self.load_file(filename)
128
- image = ChunkyPNG::Image.from_file(filename)
129
- datastream = ChunkyPNG::Datastream.from_file(filename)
130
- self.new image, datastream
131
- rescue ChunkyPNG::SignatureMismatch
132
- # Returns nil if image is not PNG.
133
- nil
134
- end
135
-
136
- def self.load_blob(data)
137
- image = ChunkyPNG::Image.from_blob(data)
138
- datastream = ChunkyPNG::Datastream.from_blob(data)
139
- self.new image, datastream
140
- rescue ChunkyPNG::SignatureMismatch
141
- # Returns nil if image is not PNG.
142
- nil
143
- end
144
-
145
- def initialize(image, datastream)
146
- @image = image
147
- @datastream = datastream
21
+ # @param [String] base64_data
22
+ # @param [Numeric, Strng] x
23
+ # @param [Numeric, Strng] y
24
+ # @param [Numeric, Strng] w
25
+ # @param [Numeric, Strng] h
26
+ def base64image(base64_data, x, y, w, h)
27
+ image_data = Base64.decode64(base64_data)
28
+ image_id = Digest::MD5.hexdigest(base64_data)
29
+ image_path = create_temp_imagefile(image_id, image_data)
30
+
31
+ image(image_path, x, y, w, h)
148
32
  end
149
33
 
150
- def need_normalize?
151
- pallete_based? && transparency_chunk?
34
+ # @param [String, IO] filename_or_io
35
+ # @param [Numeric, Strng] x
36
+ # @param [Numeric, Strng] y
37
+ # @param [Numeric, Strng] w
38
+ # @param [Numeric, Strng] h
39
+ # @param [Hash] options
40
+ # @option options [:left, :center, :right] :position_x (:left)
41
+ # @option options [:top, :center, :bottom] :position_y (:top)
42
+ def image_box(filename_or_io, x, y, w, h, options = {})
43
+ w, h = s2f(w, h)
44
+ pdf.bounding_box(pos(x, y), width: w, height: h) do
45
+ pdf.image(
46
+ filename_or_io,
47
+ position: options[:position_x] || :left,
48
+ vposition: options[:position_y] || :top,
49
+ auto_fit: [w, h]
50
+ )
51
+ end
152
52
  end
153
53
 
154
- def normalize
155
- @image.to_blob(color_mode: ChunkyPNG::COLOR_TRUECOLOR_ALPHA)
54
+ def clean_temp_images
55
+ temp_image_registry.each_value do |image_path|
56
+ File.delete(image_path) if File.exist?(image_path)
57
+ end
156
58
  end
157
59
 
158
- private
159
-
160
- def pallete_based?
161
- color_mode, _depth = @image.palette.best_color_settings
162
- color_mode == ChunkyPNG::COLOR_INDEXED
60
+ def temp_image_registry
61
+ @temp_image_registry ||= {}
163
62
  end
164
63
 
165
- def transparency_chunk?
166
- !@datastream.transparency_chunk.nil?
64
+ # @param [String] image_id
65
+ # @param [String] image_data
66
+ # @return [String] Path to imagefile
67
+ def create_temp_imagefile(image_id, image_data)
68
+ temp_image_registry[image_id] ||= begin
69
+ file = Tempfile.new('temp-image')
70
+ file.binmode
71
+ file.write(image_data)
72
+ file.open
73
+ file
74
+ end
75
+ temp_image_registry[image_id].path
167
76
  end
168
77
  end
169
78
  end
170
-
171
79
  end
172
80
  end
@@ -1,161 +1,176 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Thinreports
4
4
  module Generator
5
-
6
- module PDF::Graphics
7
- # @param [String] content
8
- # @param [Numeric, String] x
9
- # @param [Numeric, String] y
10
- # @param [Numeric, String] w
11
- # @param [Numeric, String] h
12
- # @param [Hash] attrs ({})
13
- # @option attrs [String] :font
14
- # @option attrs [Numeric, String] :size
15
- # @option attrs [String] :color
16
- # @option attrs [Array<:bold, :italic, :underline, :strikethrough>]
17
- # :styles (nil)
18
- # @option attrs [:left, :center, :right] :align (:left)
19
- # @option attrs [:top, :center, :bottom] :valign (:top)
20
- # @option attrs [Numeric, String] :line_height The total height of an text line.
21
- # @option attrs [Numeric, String] :letter_spacing
22
- # @option attrs [Boolean] :single (false)
23
- # @option attrs [:trancate, :shrink_to_fit, :expand] :overflow (:trancate)
24
- # @option attrs [:none, :break_word] :word_wrap (:none)
25
- def text_box(content, x, y, w, h, attrs = {})
26
- w, h = s2f(w, h)
27
- box_attrs = text_box_attrs(x, y, w, h, single: attrs.delete(:single),
28
- overflow: attrs[:overflow])
29
- # Do not break by word unless :word_wrap is :break_word
30
- content = text_without_line_wrap(content) if attrs[:word_wrap] == :none
31
-
32
- with_text_styles(attrs) do |built_attrs, font_styles|
33
- pdf.formatted_text_box([{ text: content, styles: font_styles }],
34
- built_attrs.merge(box_attrs))
5
+ class PDF
6
+ module Graphics
7
+ # @param [String] content
8
+ # @param [Numeric, String] x
9
+ # @param [Numeric, String] y
10
+ # @param [Numeric, String] w
11
+ # @param [Numeric, String] h
12
+ # @param [Hash] attrs ({})
13
+ # @option attrs [String] :font
14
+ # @option attrs [Numeric, String] :size
15
+ # @option attrs [String] :color
16
+ # @option attrs [Array<:bold, :italic, :underline, :strikethrough>]
17
+ # :styles (nil)
18
+ # @option attrs [:left, :center, :right] :align (:left)
19
+ # @option attrs [:top, :center, :bottom] :valign (:top)
20
+ # @option attrs [Numeric, String] :line_height The total height of an text line.
21
+ # @option attrs [Numeric, String] :letter_spacing
22
+ # @option attrs [Boolean] :single (false)
23
+ # @option attrs [:trancate, :shrink_to_fit, :expand] :overflow (:trancate)
24
+ # @option attrs [:none, :break_word] :word_wrap (:none)
25
+ def text_box(content, x, y, w, h, attrs = {})
26
+ w, h = s2f(w, h)
27
+
28
+ box_attrs = text_box_attrs(
29
+ x, y, w, h,
30
+ single: attrs.delete(:single),
31
+ overflow: attrs[:overflow]
32
+ )
33
+
34
+ # Do not break by word unless :word_wrap is :break_word
35
+ content = text_without_line_wrap(content) if attrs[:word_wrap] == :none
36
+
37
+ with_text_styles(attrs) do |built_attrs, font_styles|
38
+ pdf.formatted_text_box(
39
+ [{ text: content, styles: font_styles }],
40
+ built_attrs.merge(box_attrs)
41
+ )
42
+ end
43
+ # rubocop:disable Lint/HandleExceptions
44
+ rescue Prawn::Errors::CannotFit
45
+ # Nothing to do.
46
+ #
47
+ # When the area is too small compared
48
+ # with the content and the style of the text.
49
+ # (See prawn/core/text/formatted/line_wrap.rb#L185)
35
50
  end
36
- rescue Prawn::Errors::CannotFit
37
- # Nothing to do.
38
- #
39
- # When the area is too small compared
40
- # with the content and the style of the text.
41
- # (See prawn/core/text/formatted/line_wrap.rb#L185)
42
- end
43
51
 
44
- # @see #text_box
45
- def text(content, x, y, w, h, attrs = {})
46
- # Set the :overflow property to :shirink_to_fit.
47
- text_box(content, x, y, w, h, { overflow: :shirink_to_fit }.merge(attrs))
48
- end
49
-
50
- private
51
-
52
- # @param x (see #text_box)
53
- # @param y (see #text_box)
54
- # @param w (see #text_box)
55
- # @param h (see #text_box)
56
- # @param [Hash] states
57
- # @option states [Boolean] :single
58
- # @option states [Symbold] :overflow
59
- # @return [Hash]
60
- def text_box_attrs(x, y, w, h, states = {})
61
- attrs = {at: pos(x, y),
62
- width: s2f(w)}
63
- if states[:single]
64
- states[:overflow] != :expand ? attrs.merge(single_line: true) : attrs
65
- else
66
- attrs.merge(height: s2f(h))
52
+ # @see #text_box
53
+ def text(content, x, y, w, h, attrs = {})
54
+ # Set the :overflow property to :shirink_to_fit.
55
+ text_box(content, x, y, w, h, { overflow: :shirink_to_fit }.merge(attrs))
67
56
  end
68
- end
69
57
 
70
- # @param attrs (see #text)
71
- # @yield [built_attrs, font_styles]
72
- # @yieldparam [Hash] built_attrs The finalized attributes.
73
- # @yieldparam [Array] font_styles The finalized styles.
74
- def with_text_styles(attrs, &block)
75
- # When no color is given, do not draw.
76
- return unless attrs.key?(:color) && attrs[:color] != 'none'
77
-
78
- save_graphics_state
79
-
80
- fontinfo = {name: attrs.delete(:font).to_s,
81
- color: parse_color(attrs.delete(:color)),
82
- size: s2f(attrs.delete(:size))}
83
-
84
- # Add the specified value to :leading option.
85
- line_height = attrs.delete(:line_height)
86
- if line_height
87
- attrs[:leading] = text_line_leading(s2f(line_height),
88
- name: fontinfo[:name],
89
- size: fontinfo[:size])
58
+ private
59
+
60
+ # @param x (see #text_box)
61
+ # @param y (see #text_box)
62
+ # @param w (see #text_box)
63
+ # @param h (see #text_box)
64
+ # @param [Hash] states
65
+ # @option states [Boolean] :single
66
+ # @option states [Symbold] :overflow
67
+ # @return [Hash]
68
+ def text_box_attrs(x, y, w, h, states = {})
69
+ attrs = {
70
+ at: pos(x, y),
71
+ width: s2f(w)
72
+ }
73
+ if states[:single]
74
+ states[:overflow] != :expand ? attrs.merge(single_line: true) : attrs
75
+ else
76
+ attrs.merge(height: s2f(h))
77
+ end
90
78
  end
91
79
 
92
- # Set the :character_spacing option.
93
- spacing = attrs.delete(:letter_spacing)
94
- attrs[:character_spacing] = s2f(spacing) if spacing
80
+ # @param attrs (see #text)
81
+ # @yield [built_attrs, font_styles]
82
+ # @yieldparam [Hash] built_attrs The finalized attributes.
83
+ # @yieldparam [Array] font_styles The finalized styles.
84
+ # rubocop:disable Metrics/AbcSize
85
+ def with_text_styles(attrs, &block)
86
+ # When no color is given, do not draw.
87
+ return unless attrs.key?(:color) && attrs[:color] != 'none'
88
+
89
+ save_graphics_state
90
+
91
+ fontinfo = {
92
+ name: attrs.delete(:font).to_s,
93
+ color: parse_color(attrs.delete(:color)),
94
+ size: s2f(attrs.delete(:size))
95
+ }
96
+
97
+ # Add the specified value to :leading option.
98
+ line_height = attrs.delete(:line_height)
99
+ if line_height
100
+ attrs[:leading] = text_line_leading(
101
+ s2f(line_height),
102
+ name: fontinfo[:name],
103
+ size: fontinfo[:size]
104
+ )
105
+ end
95
106
 
96
- # Or... with_font_styles(attrs, fontinfo, &block)
97
- with_font_styles(attrs, fontinfo) do |modified_attrs, styles|
98
- block.call(modified_attrs, styles)
99
- end
107
+ # Set the :character_spacing option.
108
+ spacing = attrs.delete(:letter_spacing)
109
+ attrs[:character_spacing] = s2f(spacing) if spacing
100
110
 
101
- restore_graphics_state
102
- end
111
+ # Or... with_font_styles(attrs, fontinfo, &block)
112
+ with_font_styles(attrs, fontinfo) do |modified_attrs, styles|
113
+ block.call(modified_attrs, styles)
114
+ end
103
115
 
104
- # @param [Numeric] line_height
105
- # @param [Hash] font
106
- # @option font [String] :name Name of font.
107
- # @option font [Numeric] :size Size of font.
108
- # @return [Numeric]
109
- def text_line_leading(line_height, font)
110
- line_height - pdf.font(font[:name], size: font[:size]).height
111
- end
116
+ restore_graphics_state
117
+ end
112
118
 
113
- # @param [String] content
114
- # @return [String]
115
- def text_without_line_wrap(content)
116
- content.gsub(/ /, Prawn::Text::NBSP)
117
- end
119
+ # @param [Numeric] line_height
120
+ # @param [Hash] font
121
+ # @option font [String] :name Name of font.
122
+ # @option font [Numeric] :size Size of font.
123
+ # @return [Numeric]
124
+ def text_line_leading(line_height, font)
125
+ line_height - pdf.font(font[:name], size: font[:size]).height
126
+ end
118
127
 
119
- # @param [Hash] attrs
120
- # @param [Hash] font
121
- # @option font [String] :color
122
- # @option font [Numeric] :size
123
- # @option font [String] :name
124
- # @yield [attributes, styles]
125
- # @yieldparam [Hash] modified_attrs
126
- # @yieldparam [Array] styles
127
- def with_font_styles(attrs, font, &block)
128
- # Building font styles.
129
- styles = attrs.delete(:styles)
130
-
131
- if styles
132
- manual, styles = styles.partition do |style|
133
- [:bold, :italic].include?(style) && !font_has_style?(font[:name], style)
134
- end
128
+ # @param [String] content
129
+ # @return [String]
130
+ def text_without_line_wrap(content)
131
+ content.gsub(/ /, Prawn::Text::NBSP)
135
132
  end
136
133
 
137
- # Emulate bold style.
138
- if manual && manual.include?(:bold)
139
- pdf.stroke_color(font[:color])
140
- pdf.line_width(font[:size] * 0.025)
134
+ # @param [Hash] attrs
135
+ # @param [Hash] font
136
+ # @option font [String] :color
137
+ # @option font [Numeric] :size
138
+ # @option font [String] :name
139
+ # @yield [attributes, styles]
140
+ # @yieldparam [Hash] modified_attrs
141
+ # @yieldparam [Array] styles
142
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
143
+ def with_font_styles(attrs, font, &block)
144
+ # Building font styles.
145
+ styles = attrs.delete(:styles)
146
+
147
+ if styles
148
+ manual, styles = styles.partition do |style|
149
+ %i[bold italic].include?(style) && !font_has_style?(font[:name], style)
150
+ end
151
+ end
141
152
 
142
- # Change rendering mode to :fill_stroke.
143
- attrs[:mode] = :fill_stroke
144
- end
153
+ # Emulate bold style.
154
+ if manual && manual.include?(:bold)
155
+ pdf.stroke_color(font[:color])
156
+ pdf.line_width(font[:size] * 0.025)
145
157
 
146
- # Emulate italic style.
147
- if manual && manual.include?(:italic)
148
- # FIXME
149
- # pdf.transformation_matrix(1, 0, 0.26, 1, 0, 0)
150
- end
158
+ # Change rendering mode to :fill_stroke.
159
+ attrs[:mode] = :fill_stroke
160
+ end
161
+
162
+ # Emulate italic style.
163
+ if manual && manual.include?(:italic)
164
+ # FIXME
165
+ # pdf.transformation_matrix(1, 0, 0.26, 1, 0, 0)
166
+ end
151
167
 
152
- pdf.font(font[:name], size: font[:size]) do
153
- pdf.fill_color(font[:color])
154
- block.call(attrs, styles || [])
168
+ pdf.font(font[:name], size: font[:size]) do
169
+ pdf.fill_color(font[:color])
170
+ block.call(attrs, styles || [])
171
+ end
155
172
  end
156
173
  end
157
-
158
174
  end
159
-
160
175
  end
161
176
  end