fullcirclegroup-prawn 0.2.99.3

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 (117) hide show
  1. data/COPYING +340 -0
  2. data/LICENSE +56 -0
  3. data/README +47 -0
  4. data/Rakefile +76 -0
  5. data/data/fonts/Activa.ttf +0 -0
  6. data/data/fonts/Chalkboard.ttf +0 -0
  7. data/data/fonts/Courier-Bold.afm +342 -0
  8. data/data/fonts/Courier-BoldOblique.afm +342 -0
  9. data/data/fonts/Courier-Oblique.afm +342 -0
  10. data/data/fonts/Courier.afm +342 -0
  11. data/data/fonts/DejaVuSans.ttf +0 -0
  12. data/data/fonts/Dustismo_Roman.ttf +0 -0
  13. data/data/fonts/Helvetica-Bold.afm +2827 -0
  14. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  15. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  16. data/data/fonts/Helvetica.afm +3051 -0
  17. data/data/fonts/MustRead.html +19 -0
  18. data/data/fonts/Symbol.afm +213 -0
  19. data/data/fonts/Times-Bold.afm +2588 -0
  20. data/data/fonts/Times-BoldItalic.afm +2384 -0
  21. data/data/fonts/Times-Italic.afm +2667 -0
  22. data/data/fonts/Times-Roman.afm +2419 -0
  23. data/data/fonts/ZapfDingbats.afm +225 -0
  24. data/data/fonts/comicsans.ttf +0 -0
  25. data/data/fonts/gkai00mp.ttf +0 -0
  26. data/data/images/arrow.png +0 -0
  27. data/data/images/arrow2.png +0 -0
  28. data/data/images/barcode_issue.png +0 -0
  29. data/data/images/dice.alpha +0 -0
  30. data/data/images/dice.dat +0 -0
  31. data/data/images/dice.png +0 -0
  32. data/data/images/page_white_text.alpha +0 -0
  33. data/data/images/page_white_text.dat +0 -0
  34. data/data/images/page_white_text.png +0 -0
  35. data/data/images/pigs.jpg +0 -0
  36. data/data/images/rails.dat +0 -0
  37. data/data/images/rails.png +0 -0
  38. data/data/images/ruport.png +0 -0
  39. data/data/images/ruport_data.dat +0 -0
  40. data/data/images/ruport_transparent.png +0 -0
  41. data/data/images/ruport_type0.png +0 -0
  42. data/data/images/stef.jpg +0 -0
  43. data/data/images/web-links.dat +1 -0
  44. data/data/images/web-links.png +0 -0
  45. data/data/shift_jis_text.txt +1 -0
  46. data/examples/addressbook.csv +6 -0
  47. data/examples/alignment.rb +16 -0
  48. data/examples/bounding_boxes.rb +30 -0
  49. data/examples/canvas.rb +12 -0
  50. data/examples/cell.rb +38 -0
  51. data/examples/chinese_text_wrapping.rb +17 -0
  52. data/examples/currency.csv +1834 -0
  53. data/examples/curves.rb +10 -0
  54. data/examples/family_based_styling.rb +21 -0
  55. data/examples/fancy_table.rb +61 -0
  56. data/examples/flowing_text_with_header_and_footer.rb +72 -0
  57. data/examples/font_size.rb +27 -0
  58. data/examples/hexagon.rb +14 -0
  59. data/examples/image.rb +23 -0
  60. data/examples/image2.rb +13 -0
  61. data/examples/image_flow.rb +34 -0
  62. data/examples/kerning.rb +27 -0
  63. data/examples/lazy_bounding_boxes.rb +19 -0
  64. data/examples/line.rb +31 -0
  65. data/examples/multi_page_layout.rb +14 -0
  66. data/examples/page_geometry.rb +28 -0
  67. data/examples/png_types.rb +23 -0
  68. data/examples/polygons.rb +16 -0
  69. data/examples/position_by_baseline.rb +26 -0
  70. data/examples/ruport_formatter.rb +50 -0
  71. data/examples/ruport_helpers.rb +18 -0
  72. data/examples/russian_boxes.rb +34 -0
  73. data/examples/simple_text.rb +15 -0
  74. data/examples/simple_text_ttf.rb +16 -0
  75. data/examples/sjis.rb +21 -0
  76. data/examples/span.rb +27 -0
  77. data/examples/table.rb +47 -0
  78. data/examples/table_header_color.rb +16 -0
  79. data/examples/text_flow.rb +65 -0
  80. data/examples/top_and_bottom_cells.rb +40 -0
  81. data/examples/utf8.rb +12 -0
  82. data/lib/prawn.rb +67 -0
  83. data/lib/prawn/compatibility.rb +46 -0
  84. data/lib/prawn/document.rb +309 -0
  85. data/lib/prawn/document/bounding_box.rb +362 -0
  86. data/lib/prawn/document/internals.rb +113 -0
  87. data/lib/prawn/document/page_geometry.rb +79 -0
  88. data/lib/prawn/document/span.rb +47 -0
  89. data/lib/prawn/document/table.rb +350 -0
  90. data/lib/prawn/document/text.rb +196 -0
  91. data/lib/prawn/errors.rb +48 -0
  92. data/lib/prawn/font.rb +356 -0
  93. data/lib/prawn/font/cmap.rb +59 -0
  94. data/lib/prawn/font/metrics.rb +378 -0
  95. data/lib/prawn/font/wrapping.rb +47 -0
  96. data/lib/prawn/graphics.rb +252 -0
  97. data/lib/prawn/graphics/cell.rb +264 -0
  98. data/lib/prawn/graphics/color.rb +132 -0
  99. data/lib/prawn/images.rb +336 -0
  100. data/lib/prawn/images/jpg.rb +45 -0
  101. data/lib/prawn/images/png.rb +199 -0
  102. data/lib/prawn/pdf_object.rb +73 -0
  103. data/lib/prawn/reference.rb +56 -0
  104. data/spec/bounding_box_spec.rb +141 -0
  105. data/spec/document_spec.rb +181 -0
  106. data/spec/font_spec.rb +141 -0
  107. data/spec/graphics_spec.rb +209 -0
  108. data/spec/images_spec.rb +68 -0
  109. data/spec/jpg_spec.rb +25 -0
  110. data/spec/metrics_spec.rb +62 -0
  111. data/spec/pdf_object_spec.rb +112 -0
  112. data/spec/png_spec.rb +196 -0
  113. data/spec/reference_spec.rb +42 -0
  114. data/spec/spec_helper.rb +23 -0
  115. data/spec/table_spec.rb +179 -0
  116. data/spec/text_spec.rb +135 -0
  117. metadata +181 -0
@@ -0,0 +1,252 @@
1
+ # encoding: utf-8
2
+
3
+ # graphics.rb : Implements PDF drawing primitives
4
+ #
5
+ # Copyright April 2008, Gregory Brown. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+
9
+ require "enumerator"
10
+ require "prawn/graphics/cell"
11
+ require "prawn/graphics/color"
12
+
13
+ module Prawn
14
+
15
+ # Implements the drawing facilities for Prawn::Document.
16
+ # Use this to draw the most beautiful imaginable things.
17
+ #
18
+ # This file lifts and modifies several of PDF::Writer's graphics functions
19
+ # ruby-pdf.rubyforge.org
20
+ #
21
+ module Graphics
22
+
23
+ include Color
24
+
25
+ #######################################################################
26
+ # Low level drawing operations must translate to absolute coords! #
27
+ #######################################################################
28
+
29
+ # Moves the drawing position to a given point. The point can be
30
+ # specified as a tuple or a flattened argument list
31
+ #
32
+ # pdf.move_to [100,50]
33
+ # pdf.move_to(100,50)
34
+ #
35
+ def move_to(*point)
36
+ x,y = translate(point)
37
+ add_content("%.3f %.3f m" % [ x, y ])
38
+ end
39
+
40
+ # Draws a line from the current drawing position to the specified point.
41
+ # The destination may be described as a tuple or a flattened list:
42
+ #
43
+ # pdf.line_to [50,50]
44
+ # pdf.line_to(50,50)
45
+ #
46
+ def line_to(*point)
47
+ x,y = translate(point)
48
+ add_content("%.3f %.3f l" % [ x, y ])
49
+ end
50
+
51
+ # Draws a Bezier curve from the current drawing position to the
52
+ # specified point, bounded by two additional points.
53
+ #
54
+ # pdf.curve_to [100,100], :bounds => [[90,90],[75,75]]
55
+ #
56
+ def curve_to(dest,options={})
57
+ options[:bounds] or raise Prawn::Errors::InvalidGraphicsPath,
58
+ "Bounding points for bezier curve must be specified "+
59
+ "as :bounds => [[x1,y1],[x2,y2]]"
60
+
61
+ curve_points = (options[:bounds] << dest).map { |e| translate(e) }
62
+ add_content("%.3f %.3f %.3f %.3f %.3f %.3f c" %
63
+ curve_points.flatten )
64
+ end
65
+
66
+ # Draws a rectangle given <tt>point</tt>, <tt>width</tt> and
67
+ # <tt>height</tt>. The rectangle is bounded by its upper-left corner.
68
+ #
69
+ # pdf.rectangle [300,300], 100, 200
70
+ #
71
+ def rectangle(point,width,height)
72
+ x,y = translate(point)
73
+ add_content("%.3f %.3f %.3f %.3f re" % [ x, y - height, width, height ])
74
+ end
75
+
76
+ ###########################################################
77
+ # Higher level functions: May use relative coords #
78
+ ###########################################################
79
+
80
+ # Sets line thickness to the <tt>width</tt> specified.
81
+ #
82
+ def line_width=(width)
83
+ @line_width = width
84
+ add_content("#{width} w")
85
+ end
86
+
87
+ # The current line thickness
88
+ #
89
+ def line_width(width=nil)
90
+ if width
91
+ self.line_width = width
92
+ else
93
+ @line_width || 1
94
+ end
95
+ end
96
+
97
+ # Draws a line from one point to another. Points may be specified as
98
+ # tuples or flattened argument list:
99
+ #
100
+ # pdf.line [100,100], [200,250]
101
+ # pdf.line(100,100,200,250)
102
+ #
103
+ def line(*points)
104
+ x0,y0,x1,y1 = points.flatten
105
+ move_to(x0, y0)
106
+ line_to(x1, y1)
107
+ end
108
+
109
+ # Draws a horizontal line from <tt>x1</tt> to <tt>x2</tt> at the
110
+ # current <tt>y</tt> position, or the position specified by the :at option.
111
+ #
112
+ # # draw a line from [25, 75] to [100, 75]
113
+ # horizontal_line 25, 100, :at => 75
114
+ #
115
+ def horizontal_line(x1,x2,options={})
116
+ if options[:at]
117
+ y1 = options[:at]
118
+ else
119
+ y1 = y - bounds.absolute_bottom
120
+ end
121
+
122
+ line(x1,y1,x2,y1)
123
+ end
124
+
125
+ # Draws a horizontal line from the left border to the right border of the
126
+ # bounding box at the current <tt>y</tt> position.
127
+ #
128
+ def horizontal_rule
129
+ horizontal_line(bounds.left, bounds.right)
130
+ end
131
+
132
+ # Draws a vertical line at the x cooordinate given by :at from y1 to y2.
133
+ #
134
+ # # draw a line from [25, 100] to [25, 300]
135
+ # vertical_line 100, 300, :at => 25
136
+ #
137
+ def vertical_line(y1,y2,params)
138
+ line(params[:at],y1,params[:at],y2)
139
+ end
140
+
141
+ # Draws a Bezier curve between two points, bounded by two additional
142
+ # points
143
+ #
144
+ # pdf.curve [50,100], [100,100], :bounds => [[90,90],[75,75]]
145
+ #
146
+ def curve(origin,dest, options={})
147
+ move_to(*origin)
148
+ curve_to(dest,options)
149
+ end
150
+
151
+ # This constant is used to approximate a symmetrical arc using a cubic
152
+ # Bezier curve.
153
+ #
154
+ KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0)
155
+
156
+ # Draws a circle of radius <tt>:radius</tt> with the centre-point at <tt>point</tt>
157
+ # as a complete subpath. The drawing point will be moved to the
158
+ # centre-point upon completion of the drawing the circle.
159
+ #
160
+ # pdf.circle_at [100,100], :radius => 25
161
+ #
162
+ def circle_at(point, options)
163
+ x,y = point
164
+ ellipse_at [x, y], options[:radius]
165
+ end
166
+
167
+ # Draws an ellipse of +x+ radius <tt>r1</tt> and +y+ radius <tt>r2</tt>
168
+ # with the centre-point at <tt>point</tt> as a complete subpath. The
169
+ # drawing point will be moved to the centre-point upon completion of the
170
+ # drawing the ellipse.
171
+ #
172
+ # # draws an ellipse with x-radius 25 and y-radius 50
173
+ # pdf.ellipse_at [100,100], 25, 50
174
+ #
175
+ def ellipse_at(point, r1, r2 = r1)
176
+ x, y = point
177
+ l1 = r1 * KAPPA
178
+ l2 = r2 * KAPPA
179
+
180
+ move_to(x + r1, y)
181
+
182
+ # Upper right hand corner
183
+ curve_to [x, y + r2],
184
+ :bounds => [[x + r1, y + l1], [x + l2, y + r2]]
185
+
186
+ # Upper left hand corner
187
+ curve_to [x - r1, y],
188
+ :bounds => [[x - l2, y + r2], [x - r1, y + l1]]
189
+
190
+ # Lower left hand corner
191
+ curve_to [x, y - r2],
192
+ :bounds => [[x - r1, y - l1], [x - l2, y - r2]]
193
+
194
+ # Lower right hand corner
195
+ curve_to [x + r1, y],
196
+ :bounds => [[x + l2, y - r2], [x + r1, y - l1]]
197
+
198
+ move_to(x, y)
199
+ end
200
+
201
+ # Draws a polygon from the specified points.
202
+ #
203
+ # # draws a snazzy triangle
204
+ # pdf.polygon [100,100], [100,200], [200,200]
205
+ #
206
+ def polygon(*points)
207
+ move_to points[0]
208
+ (points << points[0]).each_cons(2) do |p1,p2|
209
+ line_to(*p2)
210
+ end
211
+ end
212
+
213
+ # Strokes and closes the current path. See Graphic::Color for color details
214
+ #
215
+ def stroke
216
+ yield if block_given?
217
+ add_content "S"
218
+ end
219
+
220
+ # Draws and strokes a rectangle represented by the current bounding box
221
+ #
222
+ def stroke_bounds
223
+ stroke_rectangle bounds.top_left, bounds.width, bounds.height
224
+ end
225
+
226
+ # Fills and closes the current path. See Graphic::Color for color details
227
+ #
228
+ def fill
229
+ yield if block_given?
230
+ add_content "f"
231
+ end
232
+
233
+ # Fills, strokes, and closes the current path. See Graphic::Color for color details
234
+ #
235
+ def fill_and_stroke
236
+ yield if block_given?
237
+ add_content "b"
238
+ end
239
+
240
+ private
241
+
242
+ def translate(*point)
243
+ x,y = point.flatten
244
+ [@bounding_box.absolute_left + x, @bounding_box.absolute_bottom + y]
245
+ end
246
+
247
+ def translate!(point)
248
+ point.replace(translate(point))
249
+ end
250
+
251
+ end
252
+ end
@@ -0,0 +1,264 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ # cell.rb : Table support functions
5
+ #
6
+ # Copyright June 2008, Gregory Brown. All Rights Reserved.
7
+ #
8
+ # This is free software. Please see the LICENSE and COPYING files for details.
9
+ module Prawn
10
+
11
+ class Document
12
+ # Builds and renders a Graphics::Cell. A cell is essentially a
13
+ # special-purpose bounding box designed for flowing text within a bordered
14
+ # area. For available options, see Graphics::Cell#new.
15
+ #
16
+ # Prawn::Document.generate("cell.pdf") do
17
+ # cell [100,500],
18
+ # :width => 200,
19
+ # :text => "The rain in Spain falls mainly on the plains"
20
+ # end
21
+ #
22
+ def cell(point, options={})
23
+ Prawn::Graphics::Cell.new(
24
+ options.merge(:document => self, :point => point)).draw
25
+ end
26
+ end
27
+
28
+ module Graphics
29
+ # A cell is a special-purpose bounding box designed to flow text within a
30
+ # bordered area. This is used by Prawn's Document::Table implementation but
31
+ # can also be used standalone for drawing text boxes via Document#cell
32
+ #
33
+ class Cell
34
+
35
+ # Creates a new cell object. Generally used indirectly via Document#cell
36
+ #
37
+ # Of the available options listed below, <tt>:point</tt>, <tt>:width</tt>,
38
+ # and <tt>:text</tt> must be provided. If you are not using the
39
+ # Document#cell shortcut, the <tt>:document</tt> must also be provided.
40
+ #
41
+ # <tt>:point</tt>:: Absolute [x,y] coordinate of the top-left corner of the cell.
42
+ # <tt>:document</tt>:: The Prawn::Document object to render on.
43
+ # <tt>:text</tt>:: The text to be flowed within the cell
44
+ # <tt>:width</tt>:: The width in PDF points of the cell.
45
+ # <tt>:height</tt>:: The height in PDF points of the cell.
46
+ # <tt>:horizontal_padding</tt>:: The horizontal padding in PDF points
47
+ # <tt>:vertical_padding</tt>:: The vertical padding in PDF points
48
+ # <tt>:padding</tt>:: Overrides both horizontal and vertical padding
49
+ # <tt>:align</tt>:: One of <tt>:left</tt>, <tt>:right</tt>, <tt>:center</tt>
50
+ # <tt>:borders</tt>:: An array of sides which should have a border. Any of <tt>:top</tt>, <tt>:left</tt>, <tt>:right</tt>, <tt>:bottom</tt>
51
+ # <tt>:border_width</tt>:: The border line width. Defaults to 1.
52
+ # <tt>:border_style</tt>:: One of <tt>:all</tt>, <tt>:no_top</tt>, <tt>:no_bottom</tt>, <tt>:sides</tt>, <tt>:none</tt>, <tt>:bottom_only</tt> or <tt>:top_and_bottom</tt>. Defaults to :all.
53
+ #
54
+ def initialize(options={})
55
+ @point = options[:point]
56
+ @document = options[:document]
57
+ @text = options[:text].to_s
58
+ @text_color = options[:text_color]
59
+ @width = options[:width]
60
+ @height = options[:height]
61
+ @borders = options[:borders]
62
+ @border_width = options[:border_width] || 1
63
+ @border_style = options[:border_style] || :all
64
+ @border_color = options[:border_color]
65
+ @background_color = options[:background_color]
66
+ @align = options[:align] || :left
67
+ @font_size = options[:font_size]
68
+
69
+ @horizontal_padding = options[:horizontal_padding] || 0
70
+ @vertical_padding = options[:vertical_padding] || 0
71
+
72
+ if options[:padding]
73
+ @horizontal_padding = @vertical_padding = options[:padding]
74
+ end
75
+ end
76
+
77
+ attr_accessor :point, :border_style, :border_width, :background_color,
78
+ :document, :horizontal_padding, :vertical_padding, :align,
79
+ :borders, :text_color, :border_color
80
+
81
+ attr_writer :height, :width #:nodoc:
82
+
83
+ # Returns the cell's text as a string.
84
+ #
85
+ def to_s
86
+ @text
87
+ end
88
+
89
+ # The width of the text area excluding the horizonal padding
90
+ #
91
+ def text_area_width
92
+ width - 2*@horizontal_padding
93
+ end
94
+
95
+ # The width of the cell in PDF points
96
+ #
97
+ def width
98
+ @width || (@document.font.metrics.string_width(@text,
99
+ @font_size || @document.font.size)) + 2*@horizontal_padding
100
+ end
101
+
102
+ # The height of the cell in PDF points
103
+ #
104
+ def height
105
+ @height || text_area_height + 2*@vertical_padding
106
+ end
107
+
108
+ # The height of the text area excluding the vertical padding
109
+ #
110
+ def text_area_height
111
+ @document.font.height_of(@text, :line_width => text_area_width)
112
+ end
113
+
114
+ # Draws the cell onto the PDF document
115
+ #
116
+ def draw
117
+ rel_point = @point
118
+
119
+ if @background_color
120
+ @document.mask(:fill_color) do
121
+ @document.fill_color @background_color
122
+ h = borders.include?(:bottom) ?
123
+ height - border_width : height + border_width / 2.0
124
+ @document.fill_rectangle [rel_point[0] + border_width / 2.0,
125
+ rel_point[1] - border_width / 2.0 ],
126
+ width - border_width, h
127
+ end
128
+ end
129
+
130
+ if @border_width > 0
131
+ @document.mask(:line_width) do
132
+ @document.line_width = @border_width
133
+
134
+ @document.mask(:stroke_color) do
135
+ @document.stroke_color @border_color if @border_color
136
+
137
+ if borders.include?(:left)
138
+ @document.stroke_line [rel_point[0], rel_point[1] + (@border_width / 2.0)],
139
+ [rel_point[0], rel_point[1] - height - @border_width / 2.0 ]
140
+ end
141
+
142
+ if borders.include?(:right)
143
+ @document.stroke_line(
144
+ [rel_point[0] + width, rel_point[1] + (@border_width / 2.0)],
145
+ [rel_point[0] + width, rel_point[1] - height - @border_width / 2.0] )
146
+ end
147
+
148
+ if borders.include?(:top)
149
+ @document.stroke_line(
150
+ [ rel_point[0] + @border_width / 2.0, rel_point[1] ],
151
+ [ rel_point[0] - @border_width / 2.0 + width, rel_point[1] ])
152
+ end
153
+
154
+ if borders.include?(:bottom)
155
+ @document.stroke_line [rel_point[0], rel_point[1] - height ],
156
+ [rel_point[0] + width, rel_point[1] - height]
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+ borders
163
+
164
+ end
165
+
166
+ @document.bounding_box( [@point[0] + @horizontal_padding,
167
+ @point[1] - @vertical_padding],
168
+ :width => text_area_width,
169
+ :height => height - @vertical_padding) do
170
+ @document.move_up @document.font.line_gap
171
+
172
+ options = {:align => @align}
173
+
174
+ options[:size] = @font_size if @font_size
175
+
176
+ @document.mask(:fill_color) do
177
+ @document.fill_color @text_color if @text_color
178
+ @document.text @text, options
179
+ end
180
+ end
181
+ end
182
+
183
+ private
184
+
185
+ def borders
186
+ @borders ||= case @border_style
187
+ when :all
188
+ [:top,:left,:right,:bottom]
189
+ when :sides
190
+ [:left,:right]
191
+ when :no_top
192
+ [:left,:right,:bottom]
193
+ when :no_bottom
194
+ [:left,:right,:top]
195
+ when :bottom_only
196
+ [:bottom]
197
+ when :top_and_bottom
198
+ [:top, :bottom]
199
+ when :none
200
+ []
201
+ end
202
+ end
203
+
204
+ end
205
+
206
+ class CellBlock #:nodoc:
207
+
208
+ # Not sure if this class is something I want to expose in the public API.
209
+
210
+ def initialize(document)
211
+ @document = document
212
+ @cells = []
213
+ @width = 0
214
+ @height = 0
215
+ end
216
+
217
+ attr_reader :width, :height, :cells
218
+ attr_accessor :background_color, :text_color, :border_color
219
+
220
+ def <<(cell)
221
+ @cells << cell
222
+ @height = cell.height if cell.height > @height
223
+ @width += cell.width
224
+ self
225
+ end
226
+
227
+ def draw
228
+ y = @document.y
229
+ x = @document.bounds.absolute_left
230
+
231
+ @cells.each do |e|
232
+ e.point = [x - @document.bounds.absolute_left,
233
+ y - @document.bounds.absolute_bottom]
234
+ e.height = @height
235
+ e.background_color ||= @background_color
236
+ e.text_color ||= @text_color
237
+ e.border_color ||= @border_color
238
+ e.draw
239
+ x += e.width
240
+ end
241
+
242
+ @document.y = y - @height
243
+ end
244
+
245
+ def border_width
246
+ @cells[0].border_width
247
+ end
248
+
249
+ def border_style=(s)
250
+ @cells.each { |e| e.border_style = s }
251
+ end
252
+
253
+ def align=(align)
254
+ @cells.each { |e| e.align = align }
255
+ end
256
+
257
+ def border_style
258
+ @cells[0].border_style
259
+ end
260
+
261
+ end
262
+ end
263
+
264
+ end