thinreports 0.6.0.pre3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/README.rdoc +37 -32
  2. data/doc/yardoc_templates/default/layout/html/footer.erb +1 -1
  3. data/lib/thinreports.rb +2 -1
  4. data/lib/thinreports/config.rb +21 -0
  5. data/lib/thinreports/core/errors.rb +14 -1
  6. data/lib/thinreports/core/format/builder.rb +6 -1
  7. data/lib/thinreports/core/page.rb +6 -6
  8. data/lib/thinreports/core/shape.rb +8 -9
  9. data/lib/thinreports/core/shape/base/internal.rb +6 -12
  10. data/lib/thinreports/core/shape/basic.rb +3 -0
  11. data/lib/thinreports/core/shape/basic/block_format.rb +12 -0
  12. data/lib/thinreports/core/shape/basic/block_interface.rb +25 -0
  13. data/lib/thinreports/core/shape/basic/block_internal.rb +33 -0
  14. data/lib/thinreports/core/shape/basic/interface.rb +37 -11
  15. data/lib/thinreports/core/shape/basic/internal.rb +3 -12
  16. data/lib/thinreports/core/shape/image_block.rb +15 -0
  17. data/lib/thinreports/core/shape/image_block/format.rb +13 -0
  18. data/lib/thinreports/core/shape/image_block/interface.rb +19 -0
  19. data/lib/thinreports/core/shape/image_block/internal.rb +16 -0
  20. data/lib/thinreports/core/shape/list/events.rb +19 -2
  21. data/lib/thinreports/core/shape/list/manager.rb +17 -4
  22. data/lib/thinreports/core/shape/list/page.rb +2 -2
  23. data/lib/thinreports/core/shape/list/page_state.rb +4 -0
  24. data/lib/thinreports/core/shape/list/section_internal.rb +4 -0
  25. data/lib/thinreports/core/shape/manager/format.rb +1 -1
  26. data/lib/thinreports/core/shape/manager/internal.rb +24 -11
  27. data/lib/thinreports/core/shape/manager/target.rb +2 -2
  28. data/lib/thinreports/core/shape/style.rb +15 -0
  29. data/lib/thinreports/core/shape/style/base.rb +149 -0
  30. data/lib/thinreports/core/shape/style/basic.rb +17 -0
  31. data/lib/thinreports/core/shape/style/graphic.rb +60 -0
  32. data/lib/thinreports/core/shape/style/text.rb +138 -0
  33. data/lib/thinreports/core/shape/text/internal.rb +4 -0
  34. data/lib/thinreports/core/shape/text_block.rb +16 -0
  35. data/lib/thinreports/core/shape/{tblock → text_block}/format.rb +3 -3
  36. data/lib/thinreports/core/shape/{tblock → text_block}/formatter.rb +7 -7
  37. data/lib/thinreports/core/shape/{tblock → text_block}/formatter/basic.rb +1 -1
  38. data/lib/thinreports/core/shape/{tblock → text_block}/formatter/datetime.rb +1 -1
  39. data/lib/thinreports/core/shape/{tblock → text_block}/formatter/number.rb +1 -1
  40. data/lib/thinreports/core/shape/{tblock → text_block}/formatter/padding.rb +10 -8
  41. data/lib/thinreports/core/shape/{tblock → text_block}/interface.rb +2 -21
  42. data/lib/thinreports/core/shape/{tblock → text_block}/internal.rb +16 -10
  43. data/lib/thinreports/core/utils.rb +0 -8
  44. data/lib/thinreports/generator.rb +2 -2
  45. data/lib/thinreports/generator/configuration.rb +30 -0
  46. data/lib/thinreports/generator/pdf.rb +13 -10
  47. data/lib/thinreports/generator/pdf/configuration.rb +28 -0
  48. data/lib/thinreports/generator/pdf/document.rb +16 -56
  49. data/lib/thinreports/generator/pdf/document/draw_shape.rb +35 -17
  50. data/lib/thinreports/generator/pdf/document/font.rb +25 -9
  51. data/lib/thinreports/generator/pdf/document/graphics.rb +1 -1
  52. data/lib/thinreports/generator/pdf/document/graphics/attributes.rb +18 -4
  53. data/lib/thinreports/generator/pdf/document/graphics/basic.rb +1 -1
  54. data/lib/thinreports/generator/pdf/document/graphics/image.rb +18 -1
  55. data/lib/thinreports/generator/pdf/document/graphics/text.rb +29 -6
  56. data/lib/thinreports/generator/pdf/document/page.rb +70 -0
  57. data/lib/thinreports/generator/pdf/document/parse_color.rb +1 -1
  58. data/lib/thinreports/generator/pdf/document/parse_svg.rb +1 -1
  59. data/lib/thinreports/generator/pdf/drawer.rb +1 -1
  60. data/lib/thinreports/generator/pdf/drawer/base.rb +5 -7
  61. data/lib/thinreports/generator/pdf/drawer/list.rb +4 -4
  62. data/lib/thinreports/generator/pdf/drawer/list_section.rb +8 -3
  63. data/lib/thinreports/generator/pdf/drawer/page.rb +10 -3
  64. data/lib/thinreports/generator/pdf/prawn_ext.rb +16 -21
  65. data/lib/thinreports/layout/format.rb +2 -2
  66. data/lib/thinreports/layout/version.rb +2 -2
  67. data/lib/thinreports/report/base.rb +68 -31
  68. data/tasks/test.rake +48 -4
  69. data/test/benchmark/basic_estimate.tlf +1 -0
  70. data/test/benchmark/bench_basic_estimate.rb +95 -0
  71. data/test/case/character_spacing/character_spacing.rb +7 -0
  72. data/test/case/character_spacing/character_spacing.tlf +1 -0
  73. data/test/case/dynamic_image/dynamic_image.rb +41 -0
  74. data/test/case/dynamic_image/dynamic_image.tlf +1 -0
  75. data/test/case/dynamic_image/img200x100.png +0 -0
  76. data/test/case/dynamic_image/img50x50.png +0 -0
  77. data/test/case/dynamic_style/dynamic_style.rb +154 -0
  78. data/test/case/dynamic_style/dynamic_style.tlf +1 -0
  79. data/test/case/dynamic_style/dynamic_style_in_list.tlf +1 -0
  80. data/test/case/dynamic_style/image.png +0 -0
  81. data/test/case/eudc/eudc.rb +20 -0
  82. data/test/case/eudc/eudc.tlf +1 -0
  83. data/test/case/eudc/eudc.ttf +0 -0
  84. data/test/case/helper.rb +27 -0
  85. data/test/case/hidden_shapes/hidden_shapes.rb +13 -0
  86. data/test/case/hidden_shapes/hidden_shapes.tlf +1 -0
  87. data/test/case/list_events/list_events.rb +32 -0
  88. data/test/case/list_events/list_events.tlf +1 -0
  89. data/test/case/list_header_inheriting/list_header_inheriting.rb +19 -0
  90. data/test/case/list_header_inheriting/list_header_inheriting.tlf +1 -0
  91. data/test/case/list_manual_generation/list_manual_generation.rb +24 -0
  92. data/test/case/list_manual_generation/list_manual_generation.tlf +1 -0
  93. data/test/case/single_line_tblock/single_line_tblock.rb +15 -0
  94. data/test/case/single_line_tblock/single_line_tblock.tlf +1 -0
  95. data/test/case/tblock_styles/tblock_styles.rb +27 -0
  96. data/test/case/tblock_styles/tblock_styles.tlf +1 -0
  97. data/test/case/text_align/text_align.rb +9 -0
  98. data/test/case/text_align/text_align.tlf +1 -0
  99. data/test/unit/core/shape/base/test_internal.rb +65 -85
  100. data/test/unit/core/shape/basic/test_basic_format.rb +30 -0
  101. data/test/unit/core/shape/basic/test_basic_interface.rb +27 -0
  102. data/test/unit/core/shape/basic/test_basic_internal.rb +55 -0
  103. data/test/unit/core/shape/basic/test_interface.rb +84 -36
  104. data/test/unit/core/shape/basic/test_internal.rb +32 -24
  105. data/test/unit/core/shape/image_block/test_format.rb +58 -0
  106. data/test/unit/core/shape/image_block/test_interface.rb +23 -0
  107. data/test/unit/core/shape/image_block/test_internal.rb +28 -0
  108. data/test/unit/core/shape/list/test_events.rb +19 -11
  109. data/test/unit/core/shape/list/test_manager.rb +112 -0
  110. data/test/unit/core/shape/list/test_page.rb +57 -0
  111. data/test/unit/core/shape/list/test_section_format.rb +1 -1
  112. data/test/unit/core/shape/list/test_section_interface.rb +37 -30
  113. data/test/unit/core/shape/list/test_section_internal.rb +39 -14
  114. data/test/unit/core/shape/manager/test_format.rb +12 -18
  115. data/test/unit/core/shape/manager/test_internal.rb +127 -93
  116. data/test/unit/core/shape/manager/test_target.rb +63 -56
  117. data/test/unit/core/shape/styles/test_base.rb +219 -0
  118. data/test/unit/core/shape/styles/test_basic.rb +24 -0
  119. data/test/unit/core/shape/styles/test_graphic.rb +69 -0
  120. data/test/unit/core/shape/styles/test_text.rb +318 -0
  121. data/test/unit/core/shape/{tblock → text_block}/formatter/test_basic.rb +2 -2
  122. data/test/unit/core/shape/{tblock → text_block}/formatter/test_datetime.rb +2 -2
  123. data/test/unit/core/shape/{tblock → text_block}/formatter/test_number.rb +2 -2
  124. data/test/unit/core/shape/{tblock → text_block}/formatter/test_padding.rb +11 -6
  125. data/test/unit/core/shape/text_block/test_format.rb +160 -0
  126. data/test/unit/core/shape/{tblock → text_block}/test_formatter.rb +2 -2
  127. data/test/unit/core/shape/text_block/test_interface.rb +46 -0
  128. data/test/unit/core/shape/text_block/test_internal.rb +128 -0
  129. data/test/unit/core/test_shape.rb +31 -6
  130. data/test/unit/data/basic_layout1.tlf +1 -0
  131. data/test/unit/data/basic_layout2.tlf +1 -0
  132. data/test/unit/data/basic_list_layout.tlf +1 -0
  133. data/test/unit/generator/pdf/document/graphics/test_attributes.rb +81 -52
  134. data/test/unit/generator/pdf/document/graphics/test_text.rb +159 -0
  135. data/test/unit/generator/pdf/document/test_font.rb +21 -6
  136. data/test/unit/generator/pdf/document/test_graphics.rb +2 -2
  137. data/test/unit/generator/pdf/document/test_page.rb +95 -0
  138. data/test/unit/generator/pdf/document/test_parse_color.rb +2 -2
  139. data/test/unit/generator/pdf/test_configuration.rb +24 -0
  140. data/test/unit/generator/pdf/test_document.rb +28 -0
  141. data/test/unit/generator/test_configuration.rb +25 -0
  142. data/test/unit/generator/test_pdf.rb +19 -0
  143. data/test/unit/helper.rb +18 -0
  144. data/test/unit/layout/test_format.rb +24 -7
  145. data/test/unit/layout/test_version.rb +61 -27
  146. data/test/unit/report/test_base.rb +185 -89
  147. data/test/unit/test_config.rb +22 -0
  148. data/test/unit/test_report.rb +4 -4
  149. metadata +94 -43
  150. data/lib/thinreports/core/shape/tblock.rb +0 -16
  151. data/lib/thinreports/generator/pxd.rb +0 -75
  152. data/lib/thinreports/generator/pxd/helper.rb +0 -33
  153. data/lib/thinreports/generator/pxd/list_renderer.rb +0 -58
  154. data/lib/thinreports/generator/pxd/page_renderer.rb +0 -75
  155. data/tasks/clean.rake +0 -6
  156. data/test/unit/core/shape/tblock/test_format.rb +0 -125
  157. data/test/unit/core/shape/tblock/test_interface.rb +0 -40
  158. data/test/unit/core/shape/tblock/test_internal.rb +0 -139
@@ -0,0 +1 @@
1
+ {"version":"0.6.0.pre3","finger-print":-164125034,"config":{"title":"Basic Layout","option":{},"page":{"paper-type":"A4","orientation":"portrait","margin-top":"20","margin-bottom":"20","margin-left":"20","margin-right":"20"}},"svg":"<svg width=\"595.2\" height=\"841.8\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" preserveAspectRatio=\"none\" viewBox=\"0 0 595.2 841.8\"><defs></defs><g class=\"canvas\"><g class=\"s-text\" stroke-width=\"0\" fill=\"#000000\" fill-opacity=\"1\" letter-spacing=\"normal\" x-display=\"true\" x-id=\"\" font-size=\"36\" font-family=\"Times New Roman\" font-weight=\"normal\" font-style=\"normal\" text-anchor=\"middle\" text-decoration=\"none\" x-width=\"206\" x-height=\"100\" x-left=\"197.6\" x-top=\"370.9\" x-valign=\"center\"><rect class=\"s-text-box\" stroke=\"none\" fill=\"#000000\" fill-opacity=\"0.001\" width=\"206\" height=\"100\" x=\"197.6\" y=\"370.9\"></rect><text class=\"s-text-l0\" xml:space=\"preserve\" stroke=\"none\" fill=\"inherit\" fill-opacity=\"1\" text-decoration=\"none\" x=\"300.6\" y=\"428.4\">Basic Layout1</text></g></g></svg>"}
@@ -0,0 +1 @@
1
+ {"version":"0.6.0.pre3","finger-print":-312717403,"config":{"title":"Basic Layout2","option":{},"page":{"paper-type":"A4","orientation":"portrait","margin-top":"20","margin-bottom":"20","margin-left":"20","margin-right":"20"}},"svg":"<svg width=\"595.2\" height=\"841.8\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" preserveAspectRatio=\"none\" viewBox=\"0 0 595.2 841.8\"><defs></defs><g class=\"canvas\"><g class=\"s-text\" stroke-width=\"0\" fill=\"#000000\" fill-opacity=\"1\" letter-spacing=\"normal\" x-display=\"true\" x-id=\"\" stroke=\"none\" font-weight=\"normal\" font-style=\"normal\" font-family=\"Times New Roman\" font-size=\"36\" text-anchor=\"middle\" x-valign=\"center\" text-decoration=\"none\" x-width=\"206\" x-height=\"100\" x-left=\"197.6\" x-top=\"370.9\"><rect class=\"s-text-box\" stroke=\"none\" fill=\"#000000\" fill-opacity=\"0.001\" width=\"206\" height=\"100\" x=\"197.6\" y=\"370.9\"></rect><text class=\"s-text-l0\" xml:space=\"preserve\" stroke=\"none\" fill=\"inherit\" fill-opacity=\"1\" text-decoration=\"none\" x=\"300.6\" y=\"428.4\">Basic Layout2</text></g></g></svg>"}
@@ -0,0 +1 @@
1
+ {"version":"0.7.0","finger-print":651703864,"config":{"title":"Basic List Layout","option":{},"page":{"paper-type":"A4","orientation":"portrait","margin-top":"20","margin-bottom":"20","margin-left":"20","margin-right":"20"}},"svg":"<svg width=\"595.2\" height=\"841.8\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" preserveAspectRatio=\"none\" viewBox=\"0 0 595.2 841.8\"><g class=\"canvas\"><!--SHAPE{\"type\":\"s-list\",\"id\":\"list\",\"display\":\"true\",\"desc\":null,\"footer\":{\"height\":55.5,\"svg\":{\"tag\":\"g\",\"content\":\"<g class=\\\"s-text\\\" stroke-width=\\\"0\\\" fill=\\\"#000000\\\" fill-opacity=\\\"1\\\" kerning=\\\"auto\\\" x-display=\\\"true\\\" x-id=\\\"\\\" stroke=\\\"none\\\" font-weight=\\\"normal\\\" font-style=\\\"normal\\\" font-family=\\\"Helvetica\\\" font-size=\\\"18\\\" text-anchor=\\\"start\\\" text-decoration=\\\"none\\\" x-width=\\\"53\\\" x-height=\\\"18\\\" x-left=\\\"271.1\\\" x-top=\\\"318.3\\\"><rect class=\\\"s-text-box\\\" stroke=\\\"none\\\" fill=\\\"#000000\\\" fill-opacity=\\\"0.001\\\" width=\\\"53\\\" height=\\\"18\\\" x=\\\"271.1\\\" y=\\\"318.3\\\"></rect><text class=\\\"s-text-l0\\\" xml:space=\\\"preserve\\\" stroke=\\\"none\\\" fill=\\\"inherit\\\" fill-opacity=\\\"1\\\" text-decoration=\\\"none\\\" x=\\\"271.1\\\" y=\\\"335.3\\\">Footer</text></g>\"},\"translate\":{\"x\":0,\"y\":-218.5}},\"footer-enabled\":\"true\",\"page-footer\":{\"height\":55.5,\"svg\":{\"tag\":\"g\",\"content\":\"<g class=\\\"s-text\\\" stroke-width=\\\"0\\\" fill=\\\"#000000\\\" fill-opacity=\\\"1\\\" kerning=\\\"auto\\\" x-display=\\\"true\\\" x-id=\\\"\\\" stroke=\\\"none\\\" font-weight=\\\"normal\\\" font-style=\\\"normal\\\" font-family=\\\"Helvetica\\\" font-size=\\\"18\\\" text-anchor=\\\"start\\\" text-decoration=\\\"none\\\" x-width=\\\"99\\\" x-height=\\\"18\\\" x-left=\\\"248.1\\\" x-top=\\\"262.8\\\"><rect class=\\\"s-text-box\\\" stroke=\\\"none\\\" fill=\\\"#000000\\\" fill-opacity=\\\"0.001\\\" width=\\\"99\\\" height=\\\"18\\\" x=\\\"248.1\\\" y=\\\"262.8\\\"></rect><text class=\\\"s-text-l0\\\" xml:space=\\\"preserve\\\" stroke=\\\"none\\\" fill=\\\"inherit\\\" fill-opacity=\\\"1\\\" text-decoration=\\\"none\\\" x=\\\"248.1\\\" y=\\\"279.8\\\">Page Footer</text></g>\"},\"translate\":{\"x\":0,\"y\":-163}},\"page-footer-enabled\":\"true\",\"detail\":{\"height\":50,\"svg\":{\"tag\":\"g\",\"content\":\"<g class=\\\"s-text\\\" stroke-width=\\\"0\\\" fill=\\\"#000000\\\" fill-opacity=\\\"1\\\" kerning=\\\"auto\\\" x-display=\\\"true\\\" x-id=\\\"\\\" font-size=\\\"18\\\" font-family=\\\"Helvetica\\\" font-weight=\\\"normal\\\" font-style=\\\"normal\\\" text-anchor=\\\"start\\\" text-decoration=\\\"none\\\" x-width=\\\"47\\\" x-height=\\\"18\\\" x-left=\\\"274.1\\\" x-top=\\\"186\\\"><rect class=\\\"s-text-box\\\" stroke=\\\"none\\\" fill=\\\"#000000\\\" fill-opacity=\\\"0.001\\\" width=\\\"47\\\" height=\\\"18\\\" x=\\\"274.1\\\" y=\\\"186\\\"></rect><text class=\\\"s-text-l0\\\" xml:space=\\\"preserve\\\" stroke=\\\"none\\\" fill=\\\"inherit\\\" fill-opacity=\\\"1\\\" text-decoration=\\\"none\\\" x=\\\"274.1\\\" y=\\\"203\\\">Detail</text></g>\"},\"translate\":{\"x\":0,\"y\":-89}},\"header\":{\"height\":61,\"svg\":{\"tag\":\"g\",\"content\":\"<g class=\\\"s-text\\\" stroke-width=\\\"0\\\" fill=\\\"#000000\\\" fill-opacity=\\\"1\\\" kerning=\\\"auto\\\" x-display=\\\"true\\\" x-id=\\\"\\\" font-size=\\\"18\\\" font-family=\\\"Helvetica\\\" font-weight=\\\"normal\\\" font-style=\\\"normal\\\" text-anchor=\\\"start\\\" text-decoration=\\\"none\\\" x-width=\\\"60\\\" x-height=\\\"18\\\" x-left=\\\"267.6\\\" x-top=\\\"116\\\"><rect class=\\\"s-text-box\\\" stroke=\\\"none\\\" fill=\\\"#000000\\\" fill-opacity=\\\"0.001\\\" width=\\\"60\\\" height=\\\"18\\\" x=\\\"267.6\\\" y=\\\"116\\\"></rect><text class=\\\"s-text-l0\\\" xml:space=\\\"preserve\\\" stroke=\\\"none\\\" fill=\\\"inherit\\\" fill-opacity=\\\"1\\\" text-decoration=\\\"none\\\" x=\\\"267.6\\\" y=\\\"133\\\">Header</text></g>\"},\"translate\":{\"x\":0,\"y\":-76}},\"header-enabled\":\"true\",\"svg\":{\"tag\":\"g\",\"attrs\":{}},\"content-height\":261.1,\"page-break\":\"true\"}SHAPE--><!--LAYOUT<g class=\"s-list\" x-id=\"list\" x-header-enabled=\"true\" x-page-footer-enabled=\"true\" x-footer-enabled=\"true\" x-changing-page=\"true\" x-display=\"true\" width=\"555.2\" height=\"322.1\" x=\"20\" y=\"20\"><g class=\"s-list-header\" transform=\"translate(0,-76) rotate(0 0 0)\" x-top=\"20\" x-height=\"61\"><g class=\"s-text\" stroke-width=\"0\" fill=\"#000000\" fill-opacity=\"1\" kerning=\"auto\" x-display=\"true\" x-id=\"\" font-size=\"18\" font-family=\"Helvetica\" font-weight=\"normal\" font-style=\"normal\" text-anchor=\"start\" text-decoration=\"none\" x-width=\"60\" x-height=\"18\" x-left=\"267.6\" x-top=\"116\"><rect class=\"s-text-box\" stroke=\"none\" fill=\"#000000\" fill-opacity=\"0.001\" width=\"60\" height=\"18\" x=\"267.6\" y=\"116\"></rect><text class=\"s-text-l0\" xml:space=\"preserve\" stroke=\"none\" fill=\"inherit\" fill-opacity=\"1\" text-decoration=\"none\" x=\"267.6\" y=\"133\">Header</text></g></g><g class=\"s-list-detail\" transform=\"translate(0,-89) rotate(0 0 0)\" x-top=\"81\" x-height=\"50\"><g class=\"s-text\" stroke-width=\"0\" fill=\"#000000\" fill-opacity=\"1\" kerning=\"auto\" x-display=\"true\" x-id=\"\" font-size=\"18\" font-family=\"Helvetica\" font-weight=\"normal\" font-style=\"normal\" text-anchor=\"start\" text-decoration=\"none\" x-width=\"47\" x-height=\"18\" x-left=\"274.1\" x-top=\"186\"><rect class=\"s-text-box\" stroke=\"none\" fill=\"#000000\" fill-opacity=\"0.001\" width=\"47\" height=\"18\" x=\"274.1\" y=\"186\"></rect><text class=\"s-text-l0\" xml:space=\"preserve\" stroke=\"none\" fill=\"inherit\" fill-opacity=\"1\" text-decoration=\"none\" x=\"274.1\" y=\"203\">Detail</text></g></g><g class=\"s-list-page-footer\" transform=\"translate(0,-113) rotate(0 0 0)\" x-top=\"131\" x-height=\"55.5\"><g class=\"s-text\" stroke-width=\"0\" fill=\"#000000\" fill-opacity=\"1\" kerning=\"auto\" x-display=\"true\" x-id=\"\" stroke=\"none\" font-weight=\"normal\" font-style=\"normal\" font-family=\"Helvetica\" font-size=\"18\" text-anchor=\"start\" text-decoration=\"none\" x-width=\"99\" x-height=\"18\" x-left=\"248.1\" x-top=\"262.8\"><rect class=\"s-text-box\" stroke=\"none\" fill=\"#000000\" fill-opacity=\"0.001\" width=\"99\" height=\"18\" x=\"248.1\" y=\"262.8\"></rect><text class=\"s-text-l0\" xml:space=\"preserve\" stroke=\"none\" fill=\"inherit\" fill-opacity=\"1\" text-decoration=\"none\" x=\"248.1\" y=\"279.8\">Page Footer</text></g></g><g class=\"s-list-footer\" transform=\"translate(0,-113) rotate(0 0 0)\" x-top=\"186.5\" x-height=\"55.5\"><g class=\"s-text\" stroke-width=\"0\" fill=\"#000000\" fill-opacity=\"1\" kerning=\"auto\" x-display=\"true\" x-id=\"\" stroke=\"none\" font-weight=\"normal\" font-style=\"normal\" font-family=\"Helvetica\" font-size=\"18\" text-anchor=\"start\" text-decoration=\"none\" x-width=\"53\" x-height=\"18\" x-left=\"271.1\" x-top=\"318.3\"><rect class=\"s-text-box\" stroke=\"none\" fill=\"#000000\" fill-opacity=\"0.001\" width=\"53\" height=\"18\" x=\"271.1\" y=\"318.3\"></rect><text class=\"s-text-l0\" xml:space=\"preserve\" stroke=\"none\" fill=\"inherit\" fill-opacity=\"1\" text-decoration=\"none\" x=\"271.1\" y=\"335.3\">Footer</text></g></g><text class=\"s-list-id\" font-size=\"11\" font-family=\"Helvetica\" font-weight=\"normal\" font-style=\"normal\" text-anchor=\"start\" stroke=\"none\" fill=\"#7C4007\" fill-opacity=\"1\" x=\"22\" y=\"30.8\">list</text><rect stroke-dasharray=\"5\" stroke=\"#BBBBBB\" stroke-width=\"1\" fill=\"#FFFFFF\" fill-opacity=\"0\" class=\"s-list-face\" width=\"555.2\" height=\"322.1\" x=\"20\" y=\"20\"></rect></g>LAYOUT--></g></svg>"}
@@ -2,102 +2,131 @@
2
2
 
3
3
  require 'test/unit/helper'
4
4
 
5
- class ThinReports::Generator::Pdf::Graphics::TestAttributes < MiniTest::Unit::TestCase
5
+ class ThinReports::Generator::PDF::Graphics::TestAttributes < MiniTest::Unit::TestCase
6
6
  include ThinReports::TestHelpers
7
7
 
8
- class TestAttrs
9
- include ThinReports::Generator::Pdf::Graphics
10
- end
11
-
12
8
  def setup
13
- @attrs = TestAttrs.new
9
+ @pdf = ThinReports::Generator::PDF::Document.new
14
10
  end
15
11
 
16
- def test_common_graphic_attrs
17
- result = @attrs.common_graphic_attrs('stroke' => '#ff0000',
18
- 'stroke-width' => '1',
19
- 'fill' => '#0000ff')
12
+ def test_common_graphic_attrs_should_return_converted_Hash_as_attributes
13
+ result = @pdf.common_graphic_attrs('stroke' => '#ff0000',
14
+ 'stroke-width' => '1',
15
+ 'fill' => '#0000ff')
20
16
  assert_equal result.values_at(:stroke, :stroke_width, :fill),
21
17
  ['#ff0000', '1', '#0000ff']
22
18
  end
23
19
 
24
- def test_common_graphic_attrs_with_stroke_dasharray
25
- result1 = @attrs.common_graphic_attrs('stroke-dasharray' => '3,5')
26
- result2 = @attrs.common_graphic_attrs('stroke-dasharray' => 'none')
27
- result3 = @attrs.common_graphic_attrs({})
28
-
29
- assert_equal result1[:stroke_dash], %w( 3 5 )
30
- assert_nil result2[:stroke_dash]
31
- assert_nil result3[:stroke_dash]
20
+ def test_common_graphic_attrs_should_return_the_stroke_dash_attribute_into_an_array
21
+ result = @pdf.common_graphic_attrs('stroke-dasharray' => '3,5')
22
+ assert_equal result[:stroke_dash], %w( 3 5 )
23
+ end
24
+
25
+ def test_common_graphic_attrs_should_return_nil_as_a_value_of_stroke_dash_attribute_when_value_is_none
26
+ result = @pdf.common_graphic_attrs('stroke-dasharray' => 'none')
27
+ assert_nil result[:stroke_dash]
28
+ end
29
+
30
+ def test_common_graphic_attrs_should_return_nil_as_a_value_of_stroke_dash_attribute_when_value_is_empty
31
+ result = @pdf.common_graphic_attrs({})
32
+ assert_nil result[:stroke_dash]
32
33
  end
33
34
 
34
- def test_common_graphic_attrs_set_0_to_stroke_width_when_opacity_is_0
35
- result = @attrs.common_graphic_attrs('stroke-width' => '1',
36
- 'stroke-opacity' => '0')
35
+ def test_common_graphic_attrs_should_set_0_as_a_value_of_stroke_width_attribute_when_opacity_is_0
36
+ result = @pdf.common_graphic_attrs('stroke-width' => '1',
37
+ 'stroke-opacity' => '0')
37
38
  assert_equal result[:stroke_width], 0
38
39
  end
39
40
 
40
41
  def test_common_graphic_attrs_with_block
41
- result = @attrs.common_graphic_attrs('stroke' => '#ff0000') do |attrs|
42
+ result = @pdf.common_graphic_attrs('stroke' => '#ff0000') do |attrs|
42
43
  attrs[:stroke].gsub!(/0/, 'f')
43
44
  end
44
45
  assert_equal result[:stroke], '#ffffff'
45
46
  end
46
47
 
47
- def test_text_align
48
+ def test_text_align_should_return_converted_value_type_of_Symbol
48
49
  aligns = ['start', 'middle', 'end', nil]
49
- assert_equal aligns.map {|a| @attrs.text_align(a) },
50
+ assert_equal aligns.map {|a| @pdf.text_align(a) },
50
51
  [:left, :center, :right, :left]
51
52
  end
52
53
 
53
- def test_text_valign
54
+ def test_text_valign_should_return_converted_value_type_of_Symbol
54
55
  valigns = ['top', 'center', 'bottom', nil]
55
- assert_equal valigns.map {|a| @attrs.text_valign(a) },
56
+ assert_equal valigns.map {|a| @pdf.text_valign(a) },
56
57
  [:top, :center, :bottom, :top]
57
58
  end
58
59
 
59
60
  def test_extract_base64_string
60
61
  base64 = 'data:image/png;base64,iVBORw0KGg1+/AAy/plYlzil'
61
- assert_equal @attrs.extract_base64_string(base64),
62
+ assert_equal @pdf.extract_base64_string(base64),
62
63
  'iVBORw0KGg1+/AAy/plYlzil'
63
64
  end
64
65
 
65
- def test_font_styles_with_bold_and_italic
66
- assert_equal @attrs.font_styles('font-weight' => 'bold'), [:bold]
67
- assert_equal @attrs.font_styles('font-style' => 'italic'), [:italic]
68
-
69
- refute_includes @attrs.font_styles('font-weight' => 'normal'), :bold
70
- refute_includes @attrs.font_styles('font-style' => 'normal'), :italic
66
+ def test_font_styles_should_return_bold_style_when_font_weight_is_bold
67
+ assert_equal @pdf.font_styles('font-weight' => 'bold'), [:bold]
71
68
  end
72
69
 
73
- def test_font_styles_with_underline_and_strikethrough_via_text_decoration
74
- assert_equal @attrs.font_styles('text-decoration' => 'underline line-through'),
70
+ def test_font_styles_should_return_italic_style_when_font_style_is_italic
71
+ assert_equal @pdf.font_styles('font-style' => 'italic'), [:italic]
72
+ end
73
+
74
+ def test_font_styles_should_return_underline_and_strikethrough_style_via_text_decoration
75
+ assert_equal @pdf.font_styles('text-decoration' => 'underline line-through'),
75
76
  [:underline, :strikethrough]
76
77
  end
77
78
 
78
- def common_text_attrs
79
- result = @attrs.common_text_attrs('font-family' => 'IPAMincho',
80
- 'font-size' => '12',
81
- 'fill' => '#000000',
82
- 'text-anchor' => 'middle',
83
- 'font-weight' => 'bold',
84
- 'text-decoration' => 'line-through')
85
- assert_equal result.values_at(:font, :size, :color, :align, :styles),
86
- ['IPAMincho', '12', '#000000', :center, [:bold, :strikethrough]]
79
+ def test_common_text_attrs_should_return_the_value_of_font_family_as_font
80
+ result = @pdf.common_text_attrs('font-family' => 'IPAMincho')
81
+ assert_equal result[:font], 'IPAMincho'
82
+ end
83
+
84
+ def test_common_text_attrs_should_return_the_value_of_font_size_as_size
85
+ result = @pdf.common_text_attrs('font-size' => '12')
86
+ assert_equal result[:size], '12'
87
+ end
88
+
89
+ def test_common_text_attrs_should_return_the_value_of_fill_color_as_color
90
+ result = @pdf.common_text_attrs('fill' => '#000000')
91
+ assert_equal result[:color], '#000000'
87
92
  end
88
93
 
89
- def common_text_attrs_with_letter_spacing
90
- result1 = @attrs.common_text_attrs('letter-spacing' => '5')
91
- result2 = @attrs.common_text_attrs('letter-spacing' => 'normal')
92
-
93
- assert_equal result1[:letter_spacing], '5'
94
- assert_nil result2[:letter_spacing]
94
+ def test_common_text_attrs_should_return_the_value_of_text_anchor_as_align
95
+ result = @pdf.common_text_attrs('text-anchor' => 'middle')
96
+ assert_equal result[:align], :center
95
97
  end
96
98
 
97
- def common_text_attrs_with_block
98
- result = @attrs.common_text_attrs('fill' => '#000000') do |attrs|
99
+ def test_common_text_attrs_should_return_the_value_of_text_styles_as_styles
100
+ result = @pdf.common_text_attrs('font-weight' => 'bold')
101
+ assert_equal result[:styles], [:bold]
102
+ end
103
+
104
+ def test_common_text_attrs_should_return_the_value_of_letter_spacing_as_letter_spacing
105
+ result = @pdf.common_text_attrs('letter-spacing' => '5')
106
+ assert_equal result[:letter_spacing], '5'
107
+ end
108
+
109
+ def test_common_text_attrs_should_return_the_value_of_kerning_as_letter_spacing
110
+ result = @pdf.common_text_attrs('kerning' => '10')
111
+ assert_equal result[:letter_spacing], '10'
112
+ end
113
+
114
+ def test_common_text_attrs_with_block
115
+ result = @pdf.common_text_attrs('fill' => '#000000') do |attrs|
99
116
  attrs[:color].gsub!(/0/, 'f')
100
117
  end
101
118
  assert_equal result[:color], '#ffffff'
102
119
  end
120
+
121
+ def test_text_letter_spacing_should_return_raw_value
122
+ assert_equal @pdf.text_letter_spacing('10'), '10'
123
+ end
124
+
125
+ def test_text_letter_spacing_should_return_nil_when_value_is_normal
126
+ assert_nil @pdf.text_letter_spacing('normal')
127
+ end
128
+
129
+ def test_text_letter_spacing_should_return_nil_when_value_is_auto
130
+ assert_nil @pdf.text_letter_spacing('auto')
131
+ end
103
132
  end
@@ -0,0 +1,159 @@
1
+ # coding: utf-8
2
+
3
+ require 'test/unit/helper'
4
+
5
+ class ThinReports::Generator::PDF::Graphics::TestText < MiniTest::Unit::TestCase
6
+ include ThinReports::TestHelpers
7
+
8
+ def setup
9
+ @pdf = ThinReports::Generator::PDF::Document.new
10
+ @pdf.internal.start_new_page
11
+ end
12
+
13
+ def exec_with_font_styles(attrs = nil, font = nil, &block)
14
+ attrs ||= {:styles => [:bold]}
15
+ font ||= {:name => 'IPAMincho', :size => 18, :color => 'ff0000'}
16
+
17
+ @pdf.send(:with_font_styles, attrs, font, &block)
18
+ end
19
+
20
+ def exec_with_text_styles(attrs = {}, &block)
21
+ default_attrs = {:font => 'Helvetica',
22
+ :color => 'ff0000',
23
+ :size => 18}
24
+ @pdf.send(:with_text_styles, default_attrs.merge(attrs), &block)
25
+ end
26
+
27
+ def test_with_text_styles_should_not_operate_when_color_is_none
28
+ exec_with_text_styles(:color => 'none') do |attrs, styles|
29
+ flunk
30
+ end
31
+ end
32
+
33
+ def test_with_text_styles_should_set_leading_via_line_height_attribute
34
+ exec_with_text_styles(:line_height => 30) do |attrs, styles|
35
+ expected = @pdf.send(:text_line_leading,
36
+ @pdf.send(:s2f, 30),
37
+ :name => 'Helvetica', :size => 18)
38
+ assert_equal attrs[:leading], expected
39
+ end
40
+ end
41
+
42
+ def test_with_text_styles_should_not_set_leading_when_line_height_is_not_specified
43
+ exec_with_text_styles do |attrs, styles|
44
+ refute_includes attrs.keys, :leading
45
+ end
46
+ end
47
+
48
+ def test_with_text_styles_should_set_character_spacing_via_letter_spacing_attribute
49
+ exec_with_text_styles(:letter_spacing => 5) do |attrs, styles|
50
+ assert_equal attrs[:character_spacing], @pdf.send(:s2f, 5)
51
+ end
52
+ end
53
+
54
+ def test_with_text_styles_should_not_set_character_spacing_when_letter_spacing_is_not_specified
55
+ exec_with_text_styles do |attrs, styles|
56
+ refute_includes attrs.keys, :character_spacing
57
+ end
58
+ end
59
+
60
+ def test_with_text_styles_should_parse_color
61
+ exec_with_text_styles(:color => '#ff0000') do |attrs, styles|
62
+ assert_equal @pdf.internal.fill_color, 'ff0000'
63
+ end
64
+ end
65
+
66
+ def test_with_font_styles_should_set_fill_color_using_color_of_font
67
+ exec_with_font_styles do |attrs, styles|
68
+ assert_equal @pdf.internal.fill_color, 'ff0000'
69
+ end
70
+ end
71
+
72
+ def test_with_font_styles_should_perform_manual_style_when_bold_style_cannot_be_applied
73
+ exec_with_font_styles do |attrs, styles|
74
+ assert_empty styles
75
+ end
76
+ end
77
+
78
+ def test_with_font_styles_should_perform_manual_style_when_italic_style_cannot_be_applied
79
+ exec_with_font_styles do |attrs, styles|
80
+ assert_empty styles
81
+ end
82
+ end
83
+
84
+ def test_with_font_styles_should_set_stroke_color_using_color_of_font_when_bold_style_cannot_be_applied
85
+ exec_with_font_styles do |attrs, styles|
86
+ assert_equal @pdf.internal.stroke_color, 'ff0000'
87
+ end
88
+ end
89
+
90
+ def test_with_font_styles_should_set_line_width_calculated_from_font_size_when_bold_style_cannot_be_applied
91
+ exec_with_font_styles do |attrs, styles|
92
+ assert_equal @pdf.internal.line_width, 18 * 0.025
93
+ end
94
+ end
95
+
96
+ def test_with_font_styles_should_set_mode_to_fill_stroke_when_bold_style_cannot_be_applied
97
+ exec_with_font_styles do |attrs, styles|
98
+ assert_equal attrs[:mode], :fill_stroke
99
+ end
100
+ end
101
+
102
+ def test_with_font_styles_should_not_perform_a_manual_style_when_bold_style_can_be_applied
103
+ exec_with_font_styles(nil, :name => 'Helvetica', :size => 12, :color => '0000ff') do |attrs, styles|
104
+ assert_includes styles, :bold
105
+ end
106
+ end
107
+
108
+ def test_with_font_styles_should_not_perform_a_manual_style_when_italic_style_can_be_applied
109
+ exec_with_font_styles({:styles => [:italic]}, :name => 'Helvetica', :size => 12, :color => 'ff0000') do |attrs, styles|
110
+ assert_includes styles, :italic
111
+ end
112
+ end
113
+
114
+ def test_text_line_leading_should_return_a_specified_leading_value_minus_the_font_height
115
+ font = {:name => 'IPAMincho', :size => 36}
116
+ font_height = @pdf.internal.font(font[:name], :size => font[:size]).height
117
+
118
+ assert_equal @pdf.send(:text_line_leading, 100, font), 100 - font_height
119
+ end
120
+
121
+ def test_text_without_line_wrap_should_replace_the_spaces_NBSP
122
+ assert_equal @pdf.send(:text_without_line_wrap, ' ' * 2), Prawn::Text::NBSP * 2
123
+ end
124
+
125
+ def test_text_box_should_not_raise_PrawnCannotFitError
126
+ @pdf.text_box('foo', 0, 0, 1, 1, :font => 'IPAMincho',
127
+ :size => 100,
128
+ :color => '000000')
129
+ rescue Prawn::Errors::CannotFit
130
+ flunk('Raise Prawn::Errors::CannotFit.')
131
+ end
132
+
133
+ def test_text_box_attrs_should_return_a_Hash_containing_a_at_and_width_options
134
+ attrs = @pdf.send(:text_box_attrs, 0, 0, 50, 100)
135
+
136
+ assert_equal attrs.values_at(:at, :width),
137
+ [@pdf.send(:pos, 0, 0), @pdf.send(:s2f, 50)]
138
+ end
139
+
140
+ def test_text_box_attrs_should_return_a_Hash_containing_a_single_line_option_when_single_is_true
141
+ attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100, true)
142
+ assert_equal attrs[:single_line], true
143
+ end
144
+
145
+ def test_text_box_attrs_should_return_a_Hash_which_does_not_contain_a_heigh_option_when_single_is_true
146
+ attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100, true)
147
+ refute attrs.key?(:height)
148
+ end
149
+
150
+ def test_text_box_attrs_should_return_a_Hash_which_does_not_contain_a_single_line_option_when_single_is_not_specified
151
+ attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100)
152
+ refute attrs.key?(:single_line)
153
+ end
154
+
155
+ def test_text_box_attrs_should_return_a_Hash_containing_a_height_optin_when_single_is_not_specified
156
+ attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 200)
157
+ assert_equal attrs[:height], 200
158
+ end
159
+ end
@@ -2,14 +2,14 @@
2
2
 
3
3
  require 'test/unit/helper'
4
4
 
5
- class ThinReports::Generator::Pdf::TestFont < MiniTest::Unit::TestCase
5
+ class ThinReports::Generator::PDF::TestFont < MiniTest::Unit::TestCase
6
6
  include ThinReports::TestHelpers
7
7
 
8
8
  # Alias
9
- Font = ThinReports::Generator::Pdf::Font
9
+ Font = ThinReports::Generator::PDF::Font
10
10
 
11
11
  def setup
12
- @doc = ThinReports::Generator::Pdf::Document.new
12
+ @doc = ThinReports::Generator::PDF::Document.new
13
13
  end
14
14
 
15
15
  def test_setup_fonts_install_builtin_fonts
@@ -19,14 +19,29 @@ class ThinReports::Generator::Pdf::TestFont < MiniTest::Unit::TestCase
19
19
  end
20
20
 
21
21
  def test_setup_fonts_install_fallback_font
22
- assert_includes @doc.internal.font_families.keys, 'FallbackFont'
23
- assert_includes @doc.internal.fallback_fonts, 'FallbackFont'
22
+ assert_includes @doc.internal.font_families.keys, 'DefaultFont'
23
+ assert_includes @doc.internal.fallback_fonts, 'DefaultFont'
24
+ end
25
+
26
+ def test_setup_fonts_install_eudc_fonts
27
+ ThinReports.config.generator.pdf.eudc_fonts = ['eudc1.ttf', 'eudc2.ttf']
28
+ setup
29
+
30
+ assert_includes @doc.internal.font_families.keys, 'EUDC0'
31
+ assert_includes @doc.internal.font_families.keys, 'EUDC1'
32
+ end
33
+
34
+ def test_setup_fonts_install_fallback_fonts_as_eudc
35
+ ThinReports.config.generator.pdf.eudc_fonts = 'eudc.ttf'
36
+ setup
37
+
38
+ assert_includes @doc.internal.fallback_fonts, 'EUDC0'
24
39
  end
25
40
 
26
41
  def test_fallback_font_has_all_styles_as_normal_IPAMincho
27
42
  ipam = Font::BUILTIN_FONTS['IPAMincho'][:normal]
28
43
  [:normal, :bold, :italic, :bold_italic].each do |style|
29
- assert_same @doc.internal.font_families['FallbackFont'][style], ipam
44
+ assert_same @doc.internal.font_families['DefaultFont'][style], ipam
30
45
  end
31
46
  end
32
47
 
@@ -2,12 +2,12 @@
2
2
 
3
3
  require 'test/unit/helper'
4
4
 
5
- class ThinReports::Generator::Pdf::TestGraphics < MiniTest::Unit::TestCase
5
+ class ThinReports::Generator::PDF::TestGraphics < MiniTest::Unit::TestCase
6
6
  include ThinReports::TestHelpers
7
7
 
8
8
  class TestGraphics
9
9
  attr_accessor :pdf
10
- include ThinReports::Generator::Pdf::Graphics
10
+ include ThinReports::Generator::PDF::Graphics
11
11
  end
12
12
 
13
13
  def setup
@@ -0,0 +1,95 @@
1
+ # coding: utf-8
2
+
3
+ require 'test/unit/helper'
4
+
5
+ class ThinReports::Generator::PDF::Document::TestPage < MiniTest::Unit::TestCase
6
+ include ThinReports::TestHelpers
7
+
8
+ def create_pdf
9
+ @pdf = ThinReports::Generator::PDF::Document.new
10
+ end
11
+
12
+ def test_change_page_format_should_return_true_at_first_time
13
+ create_pdf
14
+ format = create_basic_layout_format('basic_layout1.tlf')
15
+
16
+ assert_equal @pdf.send(:change_page_format?, format), true
17
+ end
18
+
19
+ def test_change_page_format_should_return_false_when_given_the_same_format
20
+ create_pdf
21
+ format = create_basic_layout_format('basic_layout1.tlf')
22
+
23
+ @pdf.instance_variable_set(:@current_page_format, format)
24
+ assert_equal @pdf.send(:change_page_format?, format), false
25
+ end
26
+
27
+ def test_change_page_format_should_return_true_when_given_the_other_format
28
+ create_pdf
29
+ format1 = create_basic_layout_format('basic_layout1.tlf')
30
+ format2 = create_basic_layout_format('basic_layout2.tlf')
31
+
32
+ @pdf.instance_variable_set(:@current_page_format, format1)
33
+ assert_equal @pdf.send(:change_page_format?, format2), true
34
+ end
35
+
36
+ def test_new_basic_page_options
37
+ format = create_basic_layout_format('basic_layout1.tlf')
38
+ options = create_pdf.send(:new_basic_page_options, format)
39
+
40
+ assert_equal options[:layout], format.page_orientation.to_sym
41
+ assert_equal options[:size], format.page_paper_type
42
+ end
43
+
44
+ def test_new_basic_page_options_when_the_layout_has_customize_size
45
+ format = flexmock('format').
46
+ should_receive(:user_paper_type? => true,
47
+ :page_width => 100,
48
+ :page_height => 100,
49
+ :page_orientation => 'portrait').mock
50
+
51
+ options = create_pdf.send(:new_basic_page_options, format)
52
+ assert_equal options[:size], [100, 100]
53
+ end
54
+
55
+ def test_start_new_page_should_create_stamp
56
+ create_pdf
57
+ format = create_basic_layout_format('basic_layout1.tlf')
58
+ @pdf.start_new_page(format)
59
+
60
+ assert_includes @pdf.send(:format_stamp_registry), format.identifier
61
+ end
62
+
63
+ def test_start_new_page_should_not_create_stamp
64
+ create_pdf
65
+ format = create_basic_layout_format('basic_layout1.tlf')
66
+ @pdf.start_new_page(format)
67
+ @pdf.start_new_page(format)
68
+
69
+ assert_equal @pdf.send(:format_stamp_registry).size, 1
70
+ end
71
+
72
+ def test_start_new_page_should_stamp_constantly
73
+ create_pdf
74
+ format = create_basic_layout_format('basic_layout1.tlf')
75
+ flexmock(@pdf).should_receive(:stamp).with(format.identifier.to_s).times(2)
76
+
77
+ @pdf.start_new_page(format)
78
+ @pdf.start_new_page(format)
79
+ end
80
+
81
+ def test_add_blank_page_should_create_an_A4_size_page_in_first_page
82
+ create_pdf
83
+ flexmock(@pdf.internal).should_receive(:start_new_page).with(:size => 'A4').once
84
+
85
+ @pdf.add_blank_page
86
+ end
87
+
88
+ def test_add_blank_page_should_call_with_no_arguments_since_second_page
89
+ create_pdf
90
+ @pdf.start_new_page(create_basic_layout_format('basic_layout1.tlf'))
91
+ flexmock(@pdf.internal).should_receive(:start_new_page).with(Hash.new).once
92
+
93
+ @pdf.add_blank_page
94
+ end
95
+ end