prune 0.0.4
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.
- data/CHANGELOG.ja.txt +16 -0
- data/CHANGELOG.txt +16 -0
- data/MIT-LICENSE.ja.txt +24 -0
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +77 -0
- data/PostInstall.txt +4 -0
- data/README.ja.rdoc +39 -0
- data/README.rdoc +39 -0
- data/Rakefile +28 -0
- data/demo/english_fonts.rb +66 -0
- data/demo/japanese_encodings_euc_jp.rb +27 -0
- data/demo/japanese_encodings_shift_jis.rb +27 -0
- data/demo/japanese_fonts.rb +54 -0
- data/demo/tables.rb +52 -0
- data/demo/text_decoration.rb +55 -0
- data/lib/prune.rb +90 -0
- data/lib/prune/constants.rb +39 -0
- data/lib/prune/document.rb +101 -0
- data/lib/prune/elements/base.rb +55 -0
- data/lib/prune/elements/catalog.rb +51 -0
- data/lib/prune/elements/font.rb +38 -0
- data/lib/prune/elements/font_descriptor.rb +38 -0
- data/lib/prune/elements/info.rb +44 -0
- data/lib/prune/elements/outlines.rb +19 -0
- data/lib/prune/elements/page.rb +115 -0
- data/lib/prune/elements/pages.rb +29 -0
- data/lib/prune/elements/procedure_sets.rb +22 -0
- data/lib/prune/elements/stream.rb +34 -0
- data/lib/prune/errors.rb +73 -0
- data/lib/prune/fonts/base.rb +92 -0
- data/lib/prune/fonts/base_en.rb +38 -0
- data/lib/prune/fonts/base_ja.rb +129 -0
- data/lib/prune/fonts/en/courier.rb +37 -0
- data/lib/prune/fonts/en/helvetica.rb +168 -0
- data/lib/prune/fonts/en/symbol.rb +60 -0
- data/lib/prune/fonts/en/times_roman.rb +168 -0
- data/lib/prune/fonts/en/zapf_dingbats.rb +60 -0
- data/lib/prune/fonts/ja/ms_gothic.rb +55 -0
- data/lib/prune/fonts/ja/ms_mincho.rb +55 -0
- data/lib/prune/fonts/ja/ms_p_gothic.rb +55 -0
- data/lib/prune/fonts/ja/ms_p_mincho.rb +55 -0
- data/lib/prune/fonts/ja/ms_pr_gothic.rb +55 -0
- data/lib/prune/fonts/ja/ms_ui_gothic.rb +55 -0
- data/lib/prune/functions.rb +18 -0
- data/lib/prune/p_objects/aliases.rb +37 -0
- data/lib/prune/p_objects/base.rb +45 -0
- data/lib/prune/p_objects/p_array.rb +62 -0
- data/lib/prune/p_objects/p_dictionary.rb +83 -0
- data/lib/prune/p_objects/p_hexadecimal_string.rb +27 -0
- data/lib/prune/p_objects/p_literal_string.rb +25 -0
- data/lib/prune/p_objects/p_name.rb +45 -0
- data/lib/prune/p_objects/p_stream.rb +29 -0
- data/lib/prune/parsers/base.rb +13 -0
- data/lib/prune/parsers/document/page/table/tr_parser.rb +77 -0
- data/lib/prune/parsers/document/page/table_parser.rb +32 -0
- data/lib/prune/parsers/document/page_parser.rb +91 -0
- data/lib/prune/parsers/document/property_parser.rb +45 -0
- data/lib/prune/parsers/document_parser.rb +26 -0
- data/lib/prune/shapes/base.rb +52 -0
- data/lib/prune/shapes/line.rb +55 -0
- data/lib/prune/shapes/rectangle.rb +64 -0
- data/lib/prune/shapes/text_box.rb +223 -0
- data/prune.gemspec +37 -0
- data/script/console +10 -0
- data/script/console.cmd +1 -0
- data/script/destroy +14 -0
- data/script/destroy.cmd +1 -0
- data/script/generate +14 -0
- data/script/generate.cmd +1 -0
- data/spec/prune/p_objects/p_array_spec.rb +46 -0
- data/spec/prune/p_objects/p_dictionary_spec.rb +61 -0
- data/spec/prune/p_objects/p_stream_spec.rb +29 -0
- data/spec/prune_spec.rb +38 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +11 -0
- data/tasks/prune.rake +38 -0
- data/tasks/rspec.rake +21 -0
- metadata +181 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Parsers
|
5
|
+
# Parser for directive "page".
|
6
|
+
class PageParser < Base
|
7
|
+
attr_reader :page
|
8
|
+
|
9
|
+
# Initialize.
|
10
|
+
def initialize(document, size, options = {})
|
11
|
+
@document = document
|
12
|
+
# Check document size.
|
13
|
+
raise DocumenteSizeError unless DOCUMENT_SIZES.has_key?(size)
|
14
|
+
document_size = DOCUMENT_SIZES[size]
|
15
|
+
# Create a new page.
|
16
|
+
width, height = document_size.collect{|mm| mm_to_pt(mm)}
|
17
|
+
@page = Page.new(@document, [0.0, 0.0, width, height], options)
|
18
|
+
# Add page to pages.
|
19
|
+
@document.pages << @page
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
# Draw rectangle.
|
24
|
+
def rect(x, y, width, height, options = {})
|
25
|
+
rect = Shapes::Rectangle.new(@page, [x, y, width, height], options)
|
26
|
+
rect.render
|
27
|
+
rect
|
28
|
+
end
|
29
|
+
|
30
|
+
# Div tag.
|
31
|
+
def div(string, options = {})
|
32
|
+
# Convert width and height.
|
33
|
+
if options[:width].nil?
|
34
|
+
options[:width] = @page.width
|
35
|
+
else
|
36
|
+
options[:width] = mm_to_pt(options[:width])
|
37
|
+
end
|
38
|
+
unless options[:height].nil?
|
39
|
+
options[:height] = mm_to_pt(options[:height])
|
40
|
+
end
|
41
|
+
div = Shapes::TextBox.new(@page, string, options)
|
42
|
+
div.render
|
43
|
+
@page.y -= div.height
|
44
|
+
div
|
45
|
+
end
|
46
|
+
|
47
|
+
# Span tag.
|
48
|
+
def span(string, options = {})
|
49
|
+
# Convert width and height.
|
50
|
+
unless options[:width].nil?
|
51
|
+
options[:width] = mm_to_pt(options[:width])
|
52
|
+
end
|
53
|
+
unless options[:height].nil?
|
54
|
+
options[:height] = mm_to_pt(options[:height])
|
55
|
+
end
|
56
|
+
span = Shapes::TextBox.new(@page, string, options)
|
57
|
+
span.render
|
58
|
+
@page.x += span.width
|
59
|
+
span
|
60
|
+
end
|
61
|
+
|
62
|
+
# Br tag.
|
63
|
+
def br
|
64
|
+
lf
|
65
|
+
end
|
66
|
+
|
67
|
+
# Goto tag(mm).
|
68
|
+
def goto(x, y)
|
69
|
+
@page.x = mm_to_pt(x)
|
70
|
+
@page.y = @page.height - mm_to_pt(y)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Line feed.
|
74
|
+
def lf(feed = 1)
|
75
|
+
feed = 1 unless feed < 0
|
76
|
+
@page.x = @page.margin_left
|
77
|
+
font_size = @page.current_font[:size]
|
78
|
+
feed.times do
|
79
|
+
@page.y -= font_size + (font_size / 5)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Table tag.
|
84
|
+
def table(options = {}, &block)
|
85
|
+
table_parser = TableParser.new(@page, options)
|
86
|
+
table_parser.instance_eval(&block)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Parsers
|
5
|
+
# Parser for directive "property".
|
6
|
+
class PropertyParser < Base
|
7
|
+
# Initialize.
|
8
|
+
def initialize(document)
|
9
|
+
@document = document
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
# Set title.
|
14
|
+
def title(title)
|
15
|
+
@document.info.title = title
|
16
|
+
end
|
17
|
+
|
18
|
+
# Set subject.
|
19
|
+
def subject(subject)
|
20
|
+
@document.info.subject = subject
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set author.
|
24
|
+
def author(author)
|
25
|
+
@document.info.author = author
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set PDF version.
|
29
|
+
def version(version)
|
30
|
+
valid_versions = %W[1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7]
|
31
|
+
raise PdfVersionError unless valid_versions.include?(version)
|
32
|
+
@document.version = version
|
33
|
+
@document.catalog.version = version
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set language.
|
37
|
+
def language(language)
|
38
|
+
valid_langs = %W[en-US ja-JP]
|
39
|
+
raise PdfLanguageError unless valid_langs.include?(language)
|
40
|
+
@document.catalog.lang = pl(language)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Parsers
|
5
|
+
# Parser for Prune DSL.
|
6
|
+
class DocumentParser < Base
|
7
|
+
def initialize(document)
|
8
|
+
@document = document
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
def property(&block)
|
13
|
+
unless @property_parser
|
14
|
+
@property_parser = PropertyParser.new(@document)
|
15
|
+
end
|
16
|
+
@property_parser.instance_eval(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def page(size = :A4, options = {}, &block)
|
20
|
+
@page_parser = PageParser.new(@document, size, options)
|
21
|
+
@page_parser.instance_eval(&block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Shapes
|
5
|
+
class Base
|
6
|
+
include Errors
|
7
|
+
include Functions
|
8
|
+
|
9
|
+
attr_accessor :id
|
10
|
+
attr_accessor :x
|
11
|
+
attr_accessor :y
|
12
|
+
attr_accessor :width
|
13
|
+
attr_accessor :height
|
14
|
+
|
15
|
+
# Initialize.
|
16
|
+
def initialize(page)
|
17
|
+
@page = page
|
18
|
+
@document = @page.document
|
19
|
+
raise DuplicateIdError if @page.shape_ids.include?(id)
|
20
|
+
@id = "shape_#{@page.shape_ids.size}".to_sym
|
21
|
+
@x = 0.0
|
22
|
+
@y = 0.0
|
23
|
+
@width = 0.0
|
24
|
+
@height = 0.0
|
25
|
+
end
|
26
|
+
|
27
|
+
# Render shapes.
|
28
|
+
def render(stream)
|
29
|
+
stream.each{|line| @page.stream << line}
|
30
|
+
@page.shape_ids << @id
|
31
|
+
@page.shapes.update(@id => self)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
# Convert to String.
|
37
|
+
def to_s
|
38
|
+
"Shape<#{@id}:#{self.class.to_s}>"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convert color string.
|
42
|
+
def convert_color_str(color_str)
|
43
|
+
raise ColorFormatError unless /\A#[0-9a-fA-F]{6}\z/ === color_str
|
44
|
+
r = color_str[1, 2].to_i(16) / 255.0
|
45
|
+
g = color_str[3, 2].to_i(16) / 255.0
|
46
|
+
b = color_str[5, 2].to_i(16) / 255.0
|
47
|
+
"%.2f %.2f %.2f" % [r, g, b]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Shapes
|
5
|
+
class Line < Base
|
6
|
+
STYLES = {
|
7
|
+
:solid => "[] 0 d",
|
8
|
+
:dashed => "[5 5] 0 d"
|
9
|
+
} unless const_defined?(:STYLES)
|
10
|
+
|
11
|
+
# Draw line.
|
12
|
+
def initialize(page, from_x, from_y, to_x, to_y, options = {})
|
13
|
+
super(page)
|
14
|
+
# Check arguments.
|
15
|
+
raise LineArgumentError unless from_x.is_a?(Numeric)
|
16
|
+
raise LineArgumentError unless from_y.is_a?(Numeric)
|
17
|
+
raise LineArgumentError unless to_x.is_a?(Numeric)
|
18
|
+
raise LineArgumentError unless to_y.is_a?(Numeric)
|
19
|
+
# Set instance variables.
|
20
|
+
@id = options[:id] if options.key?(:id)
|
21
|
+
@x = from_x
|
22
|
+
@y = from_y
|
23
|
+
@to_x = to_x
|
24
|
+
@to_y = to_y
|
25
|
+
@width = to_x - from_x
|
26
|
+
@height = -(to_y - from_y)
|
27
|
+
@options = options
|
28
|
+
# Parse options.
|
29
|
+
@style = options[:style] || :none
|
30
|
+
@width = options[:width] || 1.0
|
31
|
+
@color = options[:color] || "#000000"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Render shape.
|
35
|
+
def render
|
36
|
+
return [] if @style == :none
|
37
|
+
return [] if @width <= 0.0
|
38
|
+
raise LineStyleError unless STYLES.include?(@style)
|
39
|
+
stream = []
|
40
|
+
stream << "q"
|
41
|
+
stream << "2 J"
|
42
|
+
stream << "0 j"
|
43
|
+
stream << STYLES[@style]
|
44
|
+
stream << "%s RG" % convert_color_str(@color)
|
45
|
+
stream << "%.2f w" % width
|
46
|
+
stream << "%.2f %.2f m" % [@x, @y]
|
47
|
+
stream << "%.2f %.2f l" % [@to_x, @to_y]
|
48
|
+
stream << "s"
|
49
|
+
stream << "Q"
|
50
|
+
super(stream)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Shapes
|
5
|
+
class Rectangle < Base
|
6
|
+
STYLES = {
|
7
|
+
:solid => "[] 0 d",
|
8
|
+
:dashed => "[5 5] 0 d"
|
9
|
+
} unless const_defined?(:STYLES)
|
10
|
+
|
11
|
+
# Draw rectangle.
|
12
|
+
def initialize(page, x, y, width, height, options = {})
|
13
|
+
super(page)
|
14
|
+
# Check arguments.
|
15
|
+
raise RectangleArgumentError unless x.is_a?(Numeric)
|
16
|
+
raise RectangleArgumentError unless y.is_a?(Numeric)
|
17
|
+
raise RectangleArgumentError unless width.is_a?(Numeric)
|
18
|
+
raise RectangleArgumentError unless height.is_a?(Numeric)
|
19
|
+
|
20
|
+
# Set instance variables.
|
21
|
+
@id = options[:id] if options.key?(:id)
|
22
|
+
@x = x
|
23
|
+
@y = y
|
24
|
+
@width = width
|
25
|
+
@height = height
|
26
|
+
@options = options
|
27
|
+
|
28
|
+
# Parse options.
|
29
|
+
@style = options[:style] || :none
|
30
|
+
@border_width = options[:width] || 1.0
|
31
|
+
@border_color = options[:color] || "#000000"
|
32
|
+
@fill = options[:fill] || false
|
33
|
+
@fill_color = options[:fill_color] || "#000000"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Render shape.
|
37
|
+
def render
|
38
|
+
stream = []
|
39
|
+
boundary = [@x, @y, @width, -@height]
|
40
|
+
stream << "q"
|
41
|
+
# Set fill color.
|
42
|
+
if @fill
|
43
|
+
stream << "%s rg" % convert_color_str(@fill_color)
|
44
|
+
stream << "%.2f %.2f %.2f %.2f re" % boundary
|
45
|
+
stream << "f"
|
46
|
+
end
|
47
|
+
# Draw boundary.
|
48
|
+
unless @style == :none
|
49
|
+
raise RectangleStyleError unless STYLES.include?(@style)
|
50
|
+
stream << "2 J"
|
51
|
+
stream << "0 j"
|
52
|
+
stream << STYLES[@style]
|
53
|
+
stream << "%s RG" % convert_color_str(@border_color)
|
54
|
+
stream << "%.2f w" % @border_width
|
55
|
+
stream << "%.2f %.2f %.2f %.2f re" % boundary
|
56
|
+
stream << "s"
|
57
|
+
end
|
58
|
+
stream << "Q"
|
59
|
+
super(stream)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,223 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Shapes
|
5
|
+
class TextBox < Base
|
6
|
+
attr_accessor :width
|
7
|
+
attr_accessor :height
|
8
|
+
|
9
|
+
# Initialize.
|
10
|
+
def initialize(page, string, options = {})
|
11
|
+
super(page)
|
12
|
+
# Set instance variables.
|
13
|
+
@id = options[:id] if options.key?(:id)
|
14
|
+
@x = @page.x
|
15
|
+
@y = @page.y
|
16
|
+
@options = options
|
17
|
+
# Erase "\r\n" and "\r" line feeds.
|
18
|
+
@string = string.gsub(/\r\n/, "\n").gsub(/\r/, "\n")
|
19
|
+
@string << "\n" unless /\n\z/ === @string
|
20
|
+
# Parse font options.
|
21
|
+
Elements::Page::FONT_OPTIONS.each do |sym|
|
22
|
+
@page.current_font[sym] = @page.default_font[sym]
|
23
|
+
if options.key?(:font) && options[:font].key?(sym)
|
24
|
+
@page.current_font[sym] = options[:font][sym]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
# Get font.
|
28
|
+
@font = get_font(@page.current_font[:name],
|
29
|
+
:bold => @page.current_font[:bold],
|
30
|
+
:italic => @page.current_font[:italic])
|
31
|
+
raise FontNotSpecifiedError if @font.nil?
|
32
|
+
@font_size = @page.current_font[:size]
|
33
|
+
# Text align.
|
34
|
+
@text_align = options[:text_align] || :left
|
35
|
+
@width = get_width(@string, @font, @font_size, options[:width])
|
36
|
+
@height = get_height(@string, @font, @font_size, options[:height])
|
37
|
+
end
|
38
|
+
|
39
|
+
# Render shape.
|
40
|
+
def render
|
41
|
+
# Define local variables.
|
42
|
+
current_x = @x
|
43
|
+
current_y = @y
|
44
|
+
boundary = [@x, @y, @width, @height]
|
45
|
+
|
46
|
+
# Render background color.
|
47
|
+
render_background_color(boundary)
|
48
|
+
# Render borders.
|
49
|
+
render_rectangle_border(boundary)
|
50
|
+
render_top_border(boundary)
|
51
|
+
render_left_border(boundary)
|
52
|
+
render_right_border(boundary)
|
53
|
+
render_bottom_border(boundary)
|
54
|
+
|
55
|
+
# Render String.
|
56
|
+
stream = []
|
57
|
+
current_y -= @font_size
|
58
|
+
stream << "q"
|
59
|
+
# Set colors.
|
60
|
+
stroke_color = @page.current_font[:stroke_color]
|
61
|
+
fill_color = @page.current_font[:fill_color]
|
62
|
+
mode = font_mode(@page.current_font[:mode])
|
63
|
+
stream << "%s RG" % convert_color_str(stroke_color)
|
64
|
+
stream << "%s rg" % convert_color_str(fill_color)
|
65
|
+
|
66
|
+
# Write String.
|
67
|
+
x_before_align = current_x
|
68
|
+
@string.scan(/([^\n]*)\n/) do |token|
|
69
|
+
line = $1
|
70
|
+
line_width = @font.width(line, @font_size)
|
71
|
+
current_x =
|
72
|
+
x_of_text_align(line_width, @width, x_before_align, @text_align)
|
73
|
+
# Set to stream.
|
74
|
+
if line.size > 0
|
75
|
+
stream << "BT"
|
76
|
+
stream << "%s %d Tf" % [@font.name, @font_size]
|
77
|
+
stream << "%.2f %.2f Td" % [current_x, current_y]
|
78
|
+
stream << "%d Tr" % mode
|
79
|
+
stream << "%s Tj" % @font.decode(line)
|
80
|
+
stream << "ET"
|
81
|
+
end
|
82
|
+
current_y -= @font_size
|
83
|
+
end
|
84
|
+
stream << "Q"
|
85
|
+
super(stream)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
# Get font from options.
|
90
|
+
def get_font(name, options)
|
91
|
+
raise UnexistingFontError if name.nil?
|
92
|
+
font_name = name.to_s
|
93
|
+
# Font name shold contain only lower case alphabets and underscores.
|
94
|
+
raise UnexistingFontError unless
|
95
|
+
/\A[a-z][a-z_]*[a-z]\z/ === font_name
|
96
|
+
# Font name should contain one underscore at a time.
|
97
|
+
raise UnexistingFontError if /_{2,}/ === font_name
|
98
|
+
# Constantize font.
|
99
|
+
font_class_name = font_name.gsub(/(?:^|_)(.)/){$1.upcase}
|
100
|
+
font_class = eval("Fonts::#{font_class_name}") rescue UnexistingFontError
|
101
|
+
# Find font instance in document.
|
102
|
+
font_key = font_class.key(options)
|
103
|
+
if @document.fonts.key?(font_key)
|
104
|
+
font = @document.fonts[font_key]
|
105
|
+
else
|
106
|
+
font = font_class.new(@document, options)
|
107
|
+
@document.fonts.update(font_key => font)
|
108
|
+
end
|
109
|
+
# Set font in page instance.
|
110
|
+
@page.set_font(font_key, font)
|
111
|
+
font
|
112
|
+
end
|
113
|
+
|
114
|
+
# Render background color.
|
115
|
+
def render_background_color(boundary)
|
116
|
+
color = @options[:background_color]
|
117
|
+
return unless color
|
118
|
+
x, y, width, height = boundary
|
119
|
+
fill_rect = Rectangle.new(@page, x, y, width, height,
|
120
|
+
:fill => true, :fill_color => color)
|
121
|
+
fill_rect.render
|
122
|
+
end
|
123
|
+
|
124
|
+
# Render rectangle border.
|
125
|
+
def render_rectangle_border(boundary)
|
126
|
+
return unless @options[:border]
|
127
|
+
return if @options[:border_top]
|
128
|
+
return if @options[:border_right]
|
129
|
+
return if @options[:border_left]
|
130
|
+
return if @options[:border_bottom]
|
131
|
+
x, y, width, height = boundary
|
132
|
+
border_rect = Rectangle.new(@page, x, y, width, height,
|
133
|
+
@options[:border])
|
134
|
+
border_rect.render
|
135
|
+
end
|
136
|
+
|
137
|
+
# Render top border.
|
138
|
+
def render_top_border(boundary)
|
139
|
+
return unless @options[:border_top]
|
140
|
+
x, y, width, height = boundary
|
141
|
+
line = Line.new(@page, x, y, x + width, y,
|
142
|
+
@options[:border_top])
|
143
|
+
line.render
|
144
|
+
end
|
145
|
+
|
146
|
+
# Render left border.
|
147
|
+
def render_left_border(boundary)
|
148
|
+
return unless @options[:border_left]
|
149
|
+
x, y, width, height = boundary
|
150
|
+
line = Line.new(@page, x, y, x, y - height,
|
151
|
+
@options[:border_left])
|
152
|
+
line.render
|
153
|
+
end
|
154
|
+
|
155
|
+
# Render right border.
|
156
|
+
def render_right_border(boundary)
|
157
|
+
return unless @options[:border_right]
|
158
|
+
x, y, width, height = boundary
|
159
|
+
line = Line.new(@page, x + width, y, x + width, y - height,
|
160
|
+
@options[:border_right])
|
161
|
+
line.render
|
162
|
+
end
|
163
|
+
|
164
|
+
# Render bottom border.
|
165
|
+
def render_bottom_border(boundary)
|
166
|
+
return unless @options[:border_bottom]
|
167
|
+
x, y, width, height = boundary
|
168
|
+
line = Line.new(@page, x, y - height, x + width, y - height,
|
169
|
+
@options[:border_bottom])
|
170
|
+
line.render
|
171
|
+
end
|
172
|
+
|
173
|
+
# Get width(mm).
|
174
|
+
def get_width(string, font, font_size, default_width)
|
175
|
+
return default_width unless default_width.nil?
|
176
|
+
width = 0.0
|
177
|
+
string.scan(/([^\n]*)\n/) do |token|
|
178
|
+
token_width = font.width(token[0], font_size)
|
179
|
+
width = token_width if token_width > width
|
180
|
+
end
|
181
|
+
width += font_size / 10.0
|
182
|
+
end
|
183
|
+
|
184
|
+
# Get height(mm).
|
185
|
+
def get_height(string, font, font_size, default_height)
|
186
|
+
return default_height unless default_height.nil?
|
187
|
+
height = string.count("\n") * font_size
|
188
|
+
height += font_size / 5.0
|
189
|
+
end
|
190
|
+
|
191
|
+
# Get font mode.
|
192
|
+
def font_mode(mode)
|
193
|
+
case mode
|
194
|
+
when :fill
|
195
|
+
0
|
196
|
+
when :stroke
|
197
|
+
1
|
198
|
+
when :fill_and_stroke
|
199
|
+
2
|
200
|
+
else
|
201
|
+
raise FontModeError
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Get text align.
|
206
|
+
def x_of_text_align(string_width, width, x, text_align)
|
207
|
+
return x if text_align == :left
|
208
|
+
return x if width.nil?
|
209
|
+
return x if width <= string_width
|
210
|
+
# Calculate x position.
|
211
|
+
case text_align
|
212
|
+
when :center
|
213
|
+
x + ((width - string_width) / 2.0)
|
214
|
+
when :right
|
215
|
+
x + (width - string_width)
|
216
|
+
else
|
217
|
+
raise TextAlignError
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|