stationery 0.6.0 → 0.8.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +198 -18
- data/lib/stationery/builder.rb +5 -3
- data/lib/stationery/canvas/text.rb +4 -3
- data/lib/stationery/canvas.rb +24 -2
- data/lib/stationery/cli/render.rb +19 -4
- data/lib/stationery/document.rb +72 -11
- data/lib/stationery/elements.rb +1 -1
- data/lib/stationery/errors.rb +13 -0
- data/lib/stationery/fonts/fallback.rb +3 -3
- data/lib/stationery/fonts/font.rb +39 -21
- data/lib/stationery/fonts/gsub/single_subst.rb +37 -0
- data/lib/stationery/fonts/gsub.rb +65 -20
- data/lib/stationery/fonts/ligatures.rb +6 -4
- data/lib/stationery/hyphenation/patterns/LICENSES.md +60 -0
- data/lib/stationery/hyphenation/patterns/de-1996.pat.txt +36709 -0
- data/lib/stationery/hyphenation/patterns/en-us.hyp.txt +14 -0
- data/lib/stationery/hyphenation/patterns/en-us.pat.txt +4938 -0
- data/lib/stationery/hyphenation/patterns/sv.pat.txt +4693 -0
- data/lib/stationery/hyphenation.rb +132 -0
- data/lib/stationery/images/jpeg.rb +2 -1
- data/lib/stationery/images/png.rb +66 -0
- data/lib/stationery/images/resampled.rb +80 -0
- data/lib/stationery/layout/image.rb +28 -2
- data/lib/stationery/layout/paginator.rb +1 -1
- data/lib/stationery/layout/text.rb +2 -2
- data/lib/stationery/minitest.rb +17 -0
- data/lib/stationery/page_templates.rb +2 -1
- data/lib/stationery/pdf/assembler.rb +40 -6
- data/lib/stationery/pdf/attachments.rb +76 -0
- data/lib/stationery/pdf/conformance.rb +139 -0
- data/lib/stationery/pdf/factur_x.rb +117 -0
- data/lib/stationery/pdf/icc/LICENSE.md +14 -0
- data/lib/stationery/pdf/icc/sRGB2014.icc +0 -0
- data/lib/stationery/pdf/page_labels.rb +71 -0
- data/lib/stationery/pdf/stream.rb +5 -3
- data/lib/stationery/pdf/xmp.rb +149 -0
- data/lib/stationery/resources.rb +3 -0
- data/lib/stationery/svg/clip_path.rb +69 -0
- data/lib/stationery/svg/document.rb +26 -22
- data/lib/stationery/svg/painter.rb +11 -0
- data/lib/stationery/svg/region.rb +25 -0
- data/lib/stationery/svg/shapes.rb +2 -0
- data/lib/stationery/svg/style.rb +25 -14
- data/lib/stationery/svg/viewport.rb +78 -0
- data/lib/stationery/svg/walker.rb +142 -0
- data/lib/stationery/testing/inspector.rb +81 -0
- data/lib/stationery/testing/matchers.rb +77 -0
- data/lib/stationery/text/entities.rb +14 -4
- data/lib/stationery/text/paragraph.rb +1 -1
- data/lib/stationery/text/style.rb +14 -3
- data/lib/stationery/text/wrapper.rb +73 -12
- data/lib/stationery/version.rb +1 -1
- data/lib/stationery/warnings.rb +10 -0
- data/lib/stationery.rb +12 -0
- metadata +20 -1
|
@@ -2,23 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
module Stationery
|
|
4
4
|
module Text
|
|
5
|
-
# Decodes the HTML
|
|
5
|
+
# Decodes the HTML character references markup text may carry: numeric
|
|
6
|
+
# (`'`, `'`, `'`) and named (the built-ins below, then the
|
|
7
|
+
# HTML 4 table). Each reference is decoded once, so `'` yields the
|
|
8
|
+
# literal text `'`; an unknown name, a malformed reference or a code
|
|
9
|
+
# point outside Unicode stays as written.
|
|
6
10
|
module Entities
|
|
7
11
|
NAMED = { "amp" => "&", "lt" => "<", "gt" => ">", "quot" => "\"", "apos" => "'", "nbsp" => " " }.freeze
|
|
8
|
-
PATTERN = /&(#
|
|
12
|
+
PATTERN = /&(#[xX]\h+|#\d+|[a-zA-Z]+);/
|
|
13
|
+
MAX_CODE_POINT = 0x10FFFF
|
|
14
|
+
SURROGATES = (0xD800..0xDFFF)
|
|
9
15
|
|
|
10
16
|
module_function
|
|
11
17
|
|
|
12
18
|
def decode(text)
|
|
13
19
|
text.gsub(PATTERN) do |entity|
|
|
14
20
|
name = Regexp.last_match(1)
|
|
15
|
-
if name.start_with?("#x") then
|
|
16
|
-
elsif name.start_with?("#") then
|
|
21
|
+
if name.start_with?("#x", "#X") then character(name[2..].to_i(16), entity)
|
|
22
|
+
elsif name.start_with?("#") then character(name[1..].to_i, entity)
|
|
17
23
|
else NAMED.fetch(name) { html4.fetch(name, entity) }
|
|
18
24
|
end
|
|
19
25
|
end
|
|
20
26
|
end
|
|
21
27
|
|
|
28
|
+
def character(code, entity)
|
|
29
|
+
code.between?(1, MAX_CODE_POINT) && !SURROGATES.cover?(code) ? [code].pack("U") : entity
|
|
30
|
+
end
|
|
31
|
+
|
|
22
32
|
def html4
|
|
23
33
|
require_relative "entities/html4" unless defined?(HTML4)
|
|
24
34
|
HTML4
|
|
@@ -117,7 +117,7 @@ module Stationery
|
|
|
117
117
|
color: style.color, letter_spacing: style.letter_spacing, rise: style.rise,
|
|
118
118
|
opacity: style.opacity, underline: style.underline,
|
|
119
119
|
strikethrough: style.strikethrough, kerning: style.kerning,
|
|
120
|
-
ligatures: style.ligatures,
|
|
120
|
+
ligatures: style.ligatures, features: style.features,
|
|
121
121
|
synthetic_bold: fragment.face.synthetic_bold,
|
|
122
122
|
synthetic_oblique: fragment.face.synthetic_oblique, word_spacing:)
|
|
123
123
|
canvas.link(x, top, width, line.height, style.link, tag: link) if style.link
|
|
@@ -3,15 +3,26 @@
|
|
|
3
3
|
module Stationery
|
|
4
4
|
module Text
|
|
5
5
|
SCRIPT_SCALE = 0.583
|
|
6
|
+
NO_FEATURES = [].freeze
|
|
6
7
|
|
|
7
8
|
# How a run of text looks. Immutable; derive variants with #with.
|
|
9
|
+
# `hyphenate` is a bundled hyphenation language (see Hyphenation) or nil.
|
|
8
10
|
Style = Data.define(:family, :size, :weight, :style, :color, :letter_spacing,
|
|
9
11
|
:underline, :strikethrough, :script, :link, :opacity, :kerning,
|
|
10
|
-
:ligatures) do
|
|
12
|
+
:ligatures, :features, :hyphenate) do
|
|
13
|
+
# `features:` are OpenType feature tags (`:smcp`, `"onum"`, …) applied on
|
|
14
|
+
# top of `ligatures:`; kept as sorted frozen Strings so equal sets are
|
|
15
|
+
# equal styles.
|
|
11
16
|
def initialize(family:, size: 10, weight: :regular, style: :normal, color: "#000000", letter_spacing: 0,
|
|
12
17
|
underline: false, strikethrough: false, script: nil, link: nil, opacity: nil, kerning: true,
|
|
13
|
-
ligatures: true)
|
|
14
|
-
super
|
|
18
|
+
ligatures: true, features: NO_FEATURES, hyphenate: nil)
|
|
19
|
+
super(family:, size:, weight:, style:, color:, letter_spacing:, underline:, strikethrough:, script:, link:,
|
|
20
|
+
opacity:, kerning:, ligatures:, features: Style.features(features), hyphenate: Hyphenation.tag(hyphenate))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.features(tags)
|
|
24
|
+
tags = Array(tags).map(&:to_s).uniq.sort
|
|
25
|
+
tags.empty? ? NO_FEATURES : tags.freeze
|
|
15
26
|
end
|
|
16
27
|
|
|
17
28
|
# The size glyphs are drawn at: smaller for sub- and superscript.
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
module Stationery
|
|
4
4
|
module Text
|
|
5
5
|
# Greedy line breaking over styled runs. Breaks at spaces (the space is
|
|
6
|
-
# dropped at the break) and after hyphens; a word
|
|
7
|
-
#
|
|
8
|
-
#
|
|
6
|
+
# dropped at the break) and after hyphens; a word that does not fit is
|
|
7
|
+
# hyphenated when it may be (a soft hyphen U+00AD names the break points,
|
|
8
|
+
# else the style's `hyphenate` language), and a word wider than the line
|
|
9
|
+
# is broken between characters. A word that changes style midway
|
|
10
|
+
# ("<b>Tot</b>al") is still one word. Soft hyphens are never measured or
|
|
11
|
+
# drawn: a broken word draws "-" at the break and nothing otherwise.
|
|
9
12
|
class Wrapper
|
|
10
13
|
TOKEN = /\n|[ \t]+|[^ \t\n-]*-+|[^ \t\n-]+/
|
|
14
|
+
SOFT_HYPHEN = ""
|
|
15
|
+
EPSILON = 0.0001
|
|
11
16
|
|
|
12
17
|
Segment = Data.define(:text, :style)
|
|
13
18
|
|
|
@@ -53,16 +58,70 @@ module Stationery
|
|
|
53
58
|
end
|
|
54
59
|
end
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
# A word holding soft hyphens breaks only at them, even once the part
|
|
62
|
+
# after a break carries none (TeX's rule: a discretionary hyphen exempts
|
|
63
|
+
# the whole word from the patterns).
|
|
64
|
+
def place_word(word, explicit: word.any? { |segment| segment.text.include?(SOFT_HYPHEN) })
|
|
65
|
+
@explicit = explicit
|
|
57
66
|
needed = width(@pending_space) + width(word)
|
|
58
|
-
if @current.empty? || line_width + needed <= @max +
|
|
67
|
+
if @current.empty? || line_width + needed <= @max + EPSILON
|
|
59
68
|
@current.concat(@pending_space, word)
|
|
69
|
+
elsif (head, tail = hyphenated(word, @max - line_width - width(@pending_space)))
|
|
70
|
+
@current.concat(@pending_space, head)
|
|
71
|
+
finish(wrapped: true)
|
|
72
|
+
return place_word(tail, explicit:)
|
|
60
73
|
else
|
|
61
74
|
finish(wrapped: true)
|
|
62
75
|
@current.concat(word)
|
|
63
76
|
end
|
|
64
77
|
@pending_space = []
|
|
65
|
-
|
|
78
|
+
overflow
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# A word alone on its line and still too wide: hyphenate what fits,
|
|
82
|
+
# else move the characters that overflow onto following lines.
|
|
83
|
+
def overflow
|
|
84
|
+
while line_width > @max + EPSILON && characters(@current) > 1
|
|
85
|
+
head, tail = hyphenated(@current, @max)
|
|
86
|
+
if head
|
|
87
|
+
@current = head
|
|
88
|
+
finish(wrapped: true)
|
|
89
|
+
@current = tail
|
|
90
|
+
else
|
|
91
|
+
break_long_word
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# [head, tail] with the longest hyphenation of `word` whose head (and
|
|
97
|
+
# its hyphen) fits `available`; nil when the word offers no break that
|
|
98
|
+
# fits. Soft hyphens name the breaks and suppress the patterns.
|
|
99
|
+
def hyphenated(word, available)
|
|
100
|
+
chars = word.flat_map { |segment| segment.text.chars.map { |char| Segment.new(char, segment.style) } }
|
|
101
|
+
break_points(chars).reverse_each do |index|
|
|
102
|
+
head = chars.first(index).reject { |segment| segment.text == SOFT_HYPHEN }
|
|
103
|
+
head << Segment.new(hyphen_for(chars[index - 1].style), chars[index - 1].style)
|
|
104
|
+
return [head, chars.drop(index)] if width(head) <= available + EPSILON
|
|
105
|
+
end
|
|
106
|
+
nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Indexes into the word's characters before which it may break: after
|
|
110
|
+
# each soft hyphen, else where the language's patterns allow.
|
|
111
|
+
def break_points(chars)
|
|
112
|
+
return (1...chars.length).select { |index| chars[index - 1].text == SOFT_HYPHEN } if @explicit
|
|
113
|
+
|
|
114
|
+
text = chars.map(&:text).join
|
|
115
|
+
language = chars.first.style.hyphenate or return []
|
|
116
|
+
core = text[/\p{L}+/] or return []
|
|
117
|
+
offset = text.index(core)
|
|
118
|
+
Hyphenation.points(core, language).map { |point| point + offset }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# The font's hyphen, or the dedicated U+2010 when it lacks "-".
|
|
122
|
+
def hyphen_for(style)
|
|
123
|
+
font = @book.resolve(style).first
|
|
124
|
+
!font.glyph?("-") && font.glyph?("‐") ? "‐" : "-"
|
|
66
125
|
end
|
|
67
126
|
|
|
68
127
|
# Moves characters that overflow the line onto following lines.
|
|
@@ -71,7 +130,7 @@ module Stationery
|
|
|
71
130
|
@current.each do |segment|
|
|
72
131
|
segment.text.each_char do |char|
|
|
73
132
|
piece = Segment.new(char, segment.style)
|
|
74
|
-
return keep_overflow(fitting, piece) if fitting.any? && width(fitting + [piece]) > @max +
|
|
133
|
+
return keep_overflow(fitting, piece) if fitting.any? && width(fitting + [piece]) > @max + EPSILON
|
|
75
134
|
|
|
76
135
|
fitting << piece
|
|
77
136
|
end
|
|
@@ -104,8 +163,10 @@ module Stationery
|
|
|
104
163
|
|
|
105
164
|
def fragments(segments)
|
|
106
165
|
x = 0
|
|
107
|
-
segments.chunk_while { |a, b| a.style == b.style }.
|
|
108
|
-
text = group.map(&:text).join
|
|
166
|
+
segments.chunk_while { |a, b| a.style == b.style }.filter_map do |group|
|
|
167
|
+
text = group.map(&:text).join.delete(SOFT_HYPHEN)
|
|
168
|
+
next if text.empty?
|
|
169
|
+
|
|
109
170
|
font, face = @book.resolve(group.first.style)
|
|
110
171
|
fragment_width = measure(text, group.first.style)
|
|
111
172
|
Fragment.new(text, group.first.style, font, face, fragment_width, x).tap { x += fragment_width }
|
|
@@ -117,16 +178,16 @@ module Stationery
|
|
|
117
178
|
end
|
|
118
179
|
|
|
119
180
|
def line_width = width(@current)
|
|
120
|
-
def characters(segments) = segments.sum { |segment| segment.text.length }
|
|
181
|
+
def characters(segments) = segments.sum { |segment| segment.text.delete(SOFT_HYPHEN).length }
|
|
121
182
|
|
|
122
183
|
def width(segments)
|
|
123
|
-
segments.sum { |segment| measure(segment.text, segment.style) }
|
|
184
|
+
segments.sum { |segment| measure(segment.text.delete(SOFT_HYPHEN), segment.style) }
|
|
124
185
|
end
|
|
125
186
|
|
|
126
187
|
def measure(text, style)
|
|
127
188
|
font = @book.resolve(style).first
|
|
128
189
|
font.width_of(text, style.render_size, letter_spacing: style.letter_spacing, kerning: style.kerning,
|
|
129
|
-
ligatures: style.ligatures)
|
|
190
|
+
ligatures: style.ligatures, features: style.features)
|
|
130
191
|
end
|
|
131
192
|
end
|
|
132
193
|
end
|
data/lib/stationery/version.rb
CHANGED
data/lib/stationery/warnings.rb
CHANGED
|
@@ -29,6 +29,12 @@ module Stationery
|
|
|
29
29
|
def message = %(image "#{source}" skipped: #{reason})
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
OversizedImage = Data.define(:source, :pixels, :ppi, :limit) do
|
|
33
|
+
def message
|
|
34
|
+
%(image "#{source}" #{pixels}px wide is drawn at #{ppi} ppi (limit #{limit}); resize it before embedding)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
32
38
|
UnresolvedLink = Data.define(:name, :page) do
|
|
33
39
|
def message = %(link to "#{name}" on page #{page} has no matching anchor)
|
|
34
40
|
end
|
|
@@ -49,6 +55,10 @@ module Stationery
|
|
|
49
55
|
def message = "tagged PDF has no language: set metadata lang:"
|
|
50
56
|
end
|
|
51
57
|
|
|
58
|
+
ConformanceIssue = Data.define(:level, :subject) do
|
|
59
|
+
def message = "#{PDF::Conformance.label(level)}: #{subject} is not covered by the sRGB output intent"
|
|
60
|
+
end
|
|
61
|
+
|
|
52
62
|
def initialize
|
|
53
63
|
@items = []
|
|
54
64
|
@glyphs = Hash.new(0)
|
data/lib/stationery.rb
CHANGED
|
@@ -27,6 +27,7 @@ require_relative "stationery/fonts/gpos/pair_pos"
|
|
|
27
27
|
require_relative "stationery/fonts/kerning"
|
|
28
28
|
require_relative "stationery/fonts/gsub"
|
|
29
29
|
require_relative "stationery/fonts/gsub/ligature_subst"
|
|
30
|
+
require_relative "stationery/fonts/gsub/single_subst"
|
|
30
31
|
require_relative "stationery/fonts/ligatures"
|
|
31
32
|
require_relative "stationery/fonts/subset"
|
|
32
33
|
require_relative "stationery/fonts/registry"
|
|
@@ -46,6 +47,7 @@ require_relative "stationery/images/cache"
|
|
|
46
47
|
require_relative "stationery/images/scanlines"
|
|
47
48
|
require_relative "stationery/images/jpeg"
|
|
48
49
|
require_relative "stationery/images/png"
|
|
50
|
+
require_relative "stationery/images/resampled"
|
|
49
51
|
require_relative "stationery/color"
|
|
50
52
|
require_relative "stationery/geometry"
|
|
51
53
|
require_relative "stationery/page"
|
|
@@ -59,11 +61,17 @@ require_relative "stationery/canvas/debug"
|
|
|
59
61
|
require_relative "stationery/canvas/marking"
|
|
60
62
|
require_relative "stationery/canvas"
|
|
61
63
|
require_relative "stationery/pdf/outline_writer"
|
|
64
|
+
require_relative "stationery/pdf/page_labels"
|
|
65
|
+
require_relative "stationery/pdf/attachments"
|
|
66
|
+
require_relative "stationery/pdf/xmp"
|
|
67
|
+
require_relative "stationery/pdf/conformance"
|
|
68
|
+
require_relative "stationery/pdf/factur_x"
|
|
62
69
|
require_relative "stationery/forms/metrics"
|
|
63
70
|
require_relative "stationery/forms/field"
|
|
64
71
|
require_relative "stationery/forms/appearance"
|
|
65
72
|
require_relative "stationery/forms/acro_form"
|
|
66
73
|
require_relative "stationery/pdf/assembler"
|
|
74
|
+
require_relative "stationery/hyphenation"
|
|
67
75
|
require_relative "stationery/text/style"
|
|
68
76
|
require_relative "stationery/fonts/fallback"
|
|
69
77
|
require_relative "stationery/fonts/font_book"
|
|
@@ -104,6 +112,10 @@ require_relative "stationery/svg/gradient"
|
|
|
104
112
|
require_relative "stationery/svg/shading"
|
|
105
113
|
require_relative "stationery/svg/painter"
|
|
106
114
|
require_relative "stationery/svg/text"
|
|
115
|
+
require_relative "stationery/svg/viewport"
|
|
116
|
+
require_relative "stationery/svg/region"
|
|
117
|
+
require_relative "stationery/svg/clip_path"
|
|
118
|
+
require_relative "stationery/svg/walker"
|
|
107
119
|
require_relative "stationery/svg/document"
|
|
108
120
|
require_relative "stationery/layout/svg"
|
|
109
121
|
require_relative "stationery/layout/wrap"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stationery
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mikael Henriksson
|
|
@@ -71,6 +71,7 @@ files:
|
|
|
71
71
|
- lib/stationery/fonts/gpos/pair_pos.rb
|
|
72
72
|
- lib/stationery/fonts/gsub.rb
|
|
73
73
|
- lib/stationery/fonts/gsub/ligature_subst.rb
|
|
74
|
+
- lib/stationery/fonts/gsub/single_subst.rb
|
|
74
75
|
- lib/stationery/fonts/installer.rb
|
|
75
76
|
- lib/stationery/fonts/kern_table.rb
|
|
76
77
|
- lib/stationery/fonts/kerning.rb
|
|
@@ -94,10 +95,17 @@ files:
|
|
|
94
95
|
- lib/stationery/html/tree_builder/blocks.rb
|
|
95
96
|
- lib/stationery/html/tree_builder/collector.rb
|
|
96
97
|
- lib/stationery/html/whitespace.rb
|
|
98
|
+
- lib/stationery/hyphenation.rb
|
|
99
|
+
- lib/stationery/hyphenation/patterns/LICENSES.md
|
|
100
|
+
- lib/stationery/hyphenation/patterns/de-1996.pat.txt
|
|
101
|
+
- lib/stationery/hyphenation/patterns/en-us.hyp.txt
|
|
102
|
+
- lib/stationery/hyphenation/patterns/en-us.pat.txt
|
|
103
|
+
- lib/stationery/hyphenation/patterns/sv.pat.txt
|
|
97
104
|
- lib/stationery/images/cache.rb
|
|
98
105
|
- lib/stationery/images/images.rb
|
|
99
106
|
- lib/stationery/images/jpeg.rb
|
|
100
107
|
- lib/stationery/images/png.rb
|
|
108
|
+
- lib/stationery/images/resampled.rb
|
|
101
109
|
- lib/stationery/images/scanlines.rb
|
|
102
110
|
- lib/stationery/instrumentation.rb
|
|
103
111
|
- lib/stationery/layout/box.rb
|
|
@@ -137,16 +145,23 @@ files:
|
|
|
137
145
|
- lib/stationery/page.rb
|
|
138
146
|
- lib/stationery/page_templates.rb
|
|
139
147
|
- lib/stationery/pdf/assembler.rb
|
|
148
|
+
- lib/stationery/pdf/attachments.rb
|
|
149
|
+
- lib/stationery/pdf/conformance.rb
|
|
140
150
|
- lib/stationery/pdf/encryption/aes.rb
|
|
141
151
|
- lib/stationery/pdf/encryption/rc4.rb
|
|
142
152
|
- lib/stationery/pdf/encryption/revision4.rb
|
|
143
153
|
- lib/stationery/pdf/encryption/revision6.rb
|
|
144
154
|
- lib/stationery/pdf/encryption/standard_security.rb
|
|
155
|
+
- lib/stationery/pdf/factur_x.rb
|
|
156
|
+
- lib/stationery/pdf/icc/LICENSE.md
|
|
157
|
+
- lib/stationery/pdf/icc/sRGB2014.icc
|
|
145
158
|
- lib/stationery/pdf/outline_writer.rb
|
|
159
|
+
- lib/stationery/pdf/page_labels.rb
|
|
146
160
|
- lib/stationery/pdf/serializer.rb
|
|
147
161
|
- lib/stationery/pdf/stream.rb
|
|
148
162
|
- lib/stationery/pdf/types.rb
|
|
149
163
|
- lib/stationery/pdf/writer.rb
|
|
164
|
+
- lib/stationery/pdf/xmp.rb
|
|
150
165
|
- lib/stationery/preview.rb
|
|
151
166
|
- lib/stationery/rails.rb
|
|
152
167
|
- lib/stationery/rails/previews_controller.rb
|
|
@@ -162,11 +177,13 @@ files:
|
|
|
162
177
|
- lib/stationery/structure.rb
|
|
163
178
|
- lib/stationery/svg/arc.rb
|
|
164
179
|
- lib/stationery/svg/bounds.rb
|
|
180
|
+
- lib/stationery/svg/clip_path.rb
|
|
165
181
|
- lib/stationery/svg/document.rb
|
|
166
182
|
- lib/stationery/svg/gradient.rb
|
|
167
183
|
- lib/stationery/svg/painter.rb
|
|
168
184
|
- lib/stationery/svg/parser.rb
|
|
169
185
|
- lib/stationery/svg/path_data.rb
|
|
186
|
+
- lib/stationery/svg/region.rb
|
|
170
187
|
- lib/stationery/svg/selector.rb
|
|
171
188
|
- lib/stationery/svg/shading.rb
|
|
172
189
|
- lib/stationery/svg/shapes.rb
|
|
@@ -174,6 +191,8 @@ files:
|
|
|
174
191
|
- lib/stationery/svg/stylesheet.rb
|
|
175
192
|
- lib/stationery/svg/text.rb
|
|
176
193
|
- lib/stationery/svg/transform.rb
|
|
194
|
+
- lib/stationery/svg/viewport.rb
|
|
195
|
+
- lib/stationery/svg/walker.rb
|
|
177
196
|
- lib/stationery/tagging/element.rb
|
|
178
197
|
- lib/stationery/tagging/tree.rb
|
|
179
198
|
- lib/stationery/tagging/writer.rb
|