hexapdf 0.5.0 → 0.6.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 +76 -2
- data/CONTRIBUTERS +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/boxes.rb +68 -0
- data/examples/graphics.rb +12 -12
- data/examples/{text_box_alignment.rb → text_layouter_alignment.rb} +14 -14
- data/examples/text_layouter_inline_boxes.rb +66 -0
- data/examples/{text_box_line_wrapping.rb → text_layouter_line_wrapping.rb} +9 -10
- data/examples/{text_box_shapes.rb → text_layouter_shapes.rb} +58 -54
- data/examples/text_layouter_styling.rb +125 -0
- data/examples/truetype.rb +5 -7
- data/lib/hexapdf/cli/command.rb +1 -0
- data/lib/hexapdf/configuration.rb +170 -106
- data/lib/hexapdf/content/canvas.rb +41 -36
- data/lib/hexapdf/content/graphics_state.rb +15 -0
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/dictionary.rb +20 -8
- data/lib/hexapdf/dictionary_fields.rb +8 -6
- data/lib/hexapdf/document.rb +25 -26
- data/lib/hexapdf/document/fonts.rb +4 -4
- data/lib/hexapdf/document/images.rb +2 -2
- data/lib/hexapdf/document/pages.rb +16 -16
- data/lib/hexapdf/encryption/security_handler.rb +41 -9
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +7 -1
- data/lib/hexapdf/font/true_type/font.rb +20 -0
- data/lib/hexapdf/font/type1/font.rb +23 -0
- data/lib/hexapdf/font_loader.rb +1 -0
- data/lib/hexapdf/font_loader/from_configuration.rb +2 -3
- data/lib/hexapdf/font_loader/from_file.rb +65 -0
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/layout.rb +3 -2
- data/lib/hexapdf/layout/box.rb +146 -0
- data/lib/hexapdf/layout/inline_box.rb +40 -31
- data/lib/hexapdf/layout/{line_fragment.rb → line.rb} +12 -13
- data/lib/hexapdf/layout/style.rb +630 -41
- data/lib/hexapdf/layout/text_fragment.rb +80 -12
- data/lib/hexapdf/layout/{text_box.rb → text_layouter.rb} +164 -109
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/parser.rb +4 -1
- data/lib/hexapdf/revisions.rb +11 -4
- data/lib/hexapdf/stream.rb +8 -9
- data/lib/hexapdf/tokenizer.rb +5 -3
- data/lib/hexapdf/type.rb +3 -0
- data/lib/hexapdf/type/action.rb +56 -0
- data/lib/hexapdf/type/actions.rb +52 -0
- data/lib/hexapdf/type/actions/go_to.rb +52 -0
- data/lib/hexapdf/type/actions/go_to_r.rb +54 -0
- data/lib/hexapdf/type/actions/launch.rb +73 -0
- data/lib/hexapdf/type/actions/uri.rb +65 -0
- data/lib/hexapdf/type/annotation.rb +85 -0
- data/lib/hexapdf/type/annotations.rb +51 -0
- data/lib/hexapdf/type/annotations/link.rb +70 -0
- data/lib/hexapdf/type/annotations/markup_annotation.rb +70 -0
- data/lib/hexapdf/type/annotations/text.rb +81 -0
- data/lib/hexapdf/type/catalog.rb +3 -1
- data/lib/hexapdf/type/embedded_file.rb +6 -11
- data/lib/hexapdf/type/file_specification.rb +4 -6
- data/lib/hexapdf/type/font.rb +3 -1
- data/lib/hexapdf/type/font_descriptor.rb +18 -16
- data/lib/hexapdf/type/form.rb +3 -1
- data/lib/hexapdf/type/graphics_state_parameter.rb +3 -1
- data/lib/hexapdf/type/image.rb +4 -2
- data/lib/hexapdf/type/info.rb +2 -5
- data/lib/hexapdf/type/names.rb +2 -5
- data/lib/hexapdf/type/object_stream.rb +2 -1
- data/lib/hexapdf/type/page.rb +14 -1
- data/lib/hexapdf/type/page_tree_node.rb +9 -6
- data/lib/hexapdf/type/resources.rb +2 -5
- data/lib/hexapdf/type/trailer.rb +2 -5
- data/lib/hexapdf/type/viewer_preferences.rb +2 -5
- data/lib/hexapdf/type/xref_stream.rb +3 -1
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/common_tokenizer_tests.rb +3 -1
- data/test/hexapdf/content/test_canvas.rb +29 -3
- data/test/hexapdf/content/test_graphics_state.rb +11 -0
- data/test/hexapdf/content/test_operator.rb +3 -2
- data/test/hexapdf/document/test_fonts.rb +8 -8
- data/test/hexapdf/document/test_images.rb +4 -12
- data/test/hexapdf/document/test_pages.rb +7 -7
- data/test/hexapdf/encryption/test_security_handler.rb +1 -5
- data/test/hexapdf/filter/test_predictor.rb +40 -12
- data/test/hexapdf/font/true_type/test_font.rb +16 -0
- data/test/hexapdf/font/type1/test_font.rb +30 -0
- data/test/hexapdf/font_loader/test_from_file.rb +29 -0
- data/test/hexapdf/font_loader/test_standard14.rb +4 -3
- data/test/hexapdf/layout/test_box.rb +104 -0
- data/test/hexapdf/layout/test_inline_box.rb +24 -10
- data/test/hexapdf/layout/{test_line_fragment.rb → test_line.rb} +9 -9
- data/test/hexapdf/layout/test_style.rb +519 -31
- data/test/hexapdf/layout/test_text_fragment.rb +136 -15
- data/test/hexapdf/layout/{test_text_box.rb → test_text_layouter.rb} +224 -144
- data/test/hexapdf/layout/test_text_shaper.rb +1 -1
- data/test/hexapdf/test_configuration.rb +12 -6
- data/test/hexapdf/test_dictionary.rb +27 -2
- data/test/hexapdf/test_dictionary_fields.rb +10 -1
- data/test/hexapdf/test_document.rb +14 -13
- data/test/hexapdf/test_parser.rb +12 -0
- data/test/hexapdf/test_revisions.rb +34 -0
- data/test/hexapdf/test_stream.rb +1 -1
- data/test/hexapdf/test_type.rb +18 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/actions/test_launch.rb +24 -0
- data/test/hexapdf/type/actions/test_uri.rb +23 -0
- data/test/hexapdf/type/annotations/test_link.rb +19 -0
- data/test/hexapdf/type/annotations/test_markup_annotation.rb +22 -0
- data/test/hexapdf/type/annotations/test_text.rb +38 -0
- data/test/hexapdf/type/test_annotation.rb +38 -0
- data/test/hexapdf/type/test_file_specification.rb +0 -7
- data/test/hexapdf/type/test_info.rb +0 -5
- data/test/hexapdf/type/test_page.rb +14 -0
- data/test/hexapdf/type/test_page_tree_node.rb +4 -1
- data/test/hexapdf/type/test_trailer.rb +0 -4
- data/test/test_helper.rb +6 -3
- metadata +36 -15
- data/examples/text_box_inline_boxes.rb +0 -56
- data/examples/text_box_styling.rb +0 -72
- data/test/hexapdf/type/test_embedded_file.rb +0 -16
- data/test/hexapdf/type/test_names.rb +0 -9
|
@@ -46,31 +46,33 @@ module HexaPDF
|
|
|
46
46
|
|
|
47
47
|
extend Utils::BitField
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
define_type :FontDescriptor
|
|
50
|
+
|
|
51
|
+
define_field :Type, type: Symbol, required: true, default: self.type
|
|
52
|
+
define_field :FontName, type: Symbol, required: true
|
|
51
53
|
define_field :FontFamily, type: PDFByteString, version: '1.5'
|
|
52
|
-
define_field :FontStretch, type: Symbol,
|
|
53
|
-
define_field :FontWeight, type: Numeric,
|
|
54
|
-
define_field :Flags, type: Integer,
|
|
54
|
+
define_field :FontStretch, type: Symbol, version: '1.5'
|
|
55
|
+
define_field :FontWeight, type: Numeric, version: '1.5'
|
|
56
|
+
define_field :Flags, type: Integer, required: true
|
|
55
57
|
define_field :FontBBox, type: Rectangle
|
|
56
|
-
define_field :ItalicAngle, type: Numeric,
|
|
58
|
+
define_field :ItalicAngle, type: Numeric, required: true
|
|
57
59
|
define_field :Ascent, type: Numeric
|
|
58
60
|
define_field :Descent, type: Numeric
|
|
59
|
-
define_field :Leading, type: Numeric,
|
|
61
|
+
define_field :Leading, type: Numeric, default: 0
|
|
60
62
|
define_field :CapHeight, type: Numeric
|
|
61
|
-
define_field :XHeight, type: Numeric,
|
|
63
|
+
define_field :XHeight, type: Numeric, default: 0
|
|
62
64
|
define_field :StemV, type: Numeric
|
|
63
|
-
define_field :StemH, type: Numeric,
|
|
64
|
-
define_field :AvgWidth, type: Numeric,
|
|
65
|
-
define_field :MaxWidth, type: Numeric,
|
|
66
|
-
define_field :MissingWidth, type: Numeric,
|
|
65
|
+
define_field :StemH, type: Numeric, default: 0
|
|
66
|
+
define_field :AvgWidth, type: Numeric, default: 0
|
|
67
|
+
define_field :MaxWidth, type: Numeric, default: 0
|
|
68
|
+
define_field :MissingWidth, type: Numeric, default: 0
|
|
67
69
|
define_field :FontFile, type: Stream
|
|
68
|
-
define_field :FontFile2, type: Stream,
|
|
69
|
-
define_field :FontFile3, type: Stream,
|
|
70
|
-
define_field :CharSet, type: [String,
|
|
70
|
+
define_field :FontFile2, type: Stream, version: '1.1'
|
|
71
|
+
define_field :FontFile3, type: Stream, version: '1.2'
|
|
72
|
+
define_field :CharSet, type: [String, PDFByteString], version: '1.1'
|
|
71
73
|
|
|
72
74
|
define_field :Style, type: Dictionary
|
|
73
|
-
define_field :Lang, type: Symbol,
|
|
75
|
+
define_field :Lang, type: Symbol, version: '1.5'
|
|
74
76
|
define_field :FD, type: Dictionary
|
|
75
77
|
define_field :CIDSet, type: Stream
|
|
76
78
|
|
data/lib/hexapdf/type/form.rb
CHANGED
|
@@ -42,7 +42,9 @@ module HexaPDF
|
|
|
42
42
|
# See: PDF1.7 s8.10
|
|
43
43
|
class Form < Stream
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
define_type :XObject
|
|
46
|
+
|
|
47
|
+
define_field :Type, type: Symbol, default: self.type
|
|
46
48
|
define_field :Subtype, type: Symbol, required: true, default: :Form
|
|
47
49
|
define_field :FormType, type: Integer, default: 1
|
|
48
50
|
define_field :BBox, type: Rectangle, required: true
|
|
@@ -45,7 +45,9 @@ module HexaPDF
|
|
|
45
45
|
# See: PDF1.7 s8.4.5, s8.1
|
|
46
46
|
class GraphicsStateParameter < Dictionary
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
define_type :ExtGState
|
|
49
|
+
|
|
50
|
+
define_field :Type, type: Symbol, required: true, default: self.type
|
|
49
51
|
define_field :LW, type: Numeric, version: "1.3"
|
|
50
52
|
define_field :LC, type: Integer, version: "1.3"
|
|
51
53
|
define_field :LJ, type: Integer, version: "1.3"
|
data/lib/hexapdf/type/image.rb
CHANGED
|
@@ -48,7 +48,9 @@ module HexaPDF
|
|
|
48
48
|
Info = Struct.new(:type, :width, :height, :color_space, :indexed, :components,
|
|
49
49
|
:bits_per_component, :writable, :extension)
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
define_type :XObject
|
|
52
|
+
|
|
53
|
+
define_field :Type, type: Symbol, default: self.type
|
|
52
54
|
define_field :Subtype, type: Symbol, required: true, default: :Image
|
|
53
55
|
define_field :Width, type: Integer, required: true
|
|
54
56
|
define_field :Height, type: Integer, required: true
|
|
@@ -238,7 +240,7 @@ module HexaPDF
|
|
|
238
240
|
if filter == :FlateDecode && self[:DecodeParms] && self[:DecodeParms][:Predictor].to_i >= 10
|
|
239
241
|
data = stream_source
|
|
240
242
|
else
|
|
241
|
-
flate_decode =
|
|
243
|
+
flate_decode = config.constantize('filter.map', :FlateDecode)
|
|
242
244
|
data = flate_decode.encoder(stream_decoder, Predictor: 15, Colors: 1, Columns: info.width,
|
|
243
245
|
BitsPerComponent: info.bits_per_component)
|
|
244
246
|
end
|
data/lib/hexapdf/type/info.rb
CHANGED
|
@@ -44,6 +44,8 @@ module HexaPDF
|
|
|
44
44
|
# See: PDF1.7 s14.3.3, Trailer
|
|
45
45
|
class Info < Dictionary
|
|
46
46
|
|
|
47
|
+
define_type :XXInfo
|
|
48
|
+
|
|
47
49
|
define_field :Title, type: String, version: '1.1'
|
|
48
50
|
define_field :Author, type: String
|
|
49
51
|
define_field :Subject, type: String, version: '1.1'
|
|
@@ -59,11 +61,6 @@ module HexaPDF
|
|
|
59
61
|
true
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
# Returns +:XXInfo+.
|
|
63
|
-
def type
|
|
64
|
-
:XXInfo
|
|
65
|
-
end
|
|
66
|
-
|
|
67
64
|
end
|
|
68
65
|
|
|
69
66
|
end
|
data/lib/hexapdf/type/names.rb
CHANGED
|
@@ -47,6 +47,8 @@ module HexaPDF
|
|
|
47
47
|
# See: PDF1.7 s7.7.4, HexaPDF::Catalog, HexaPDF::NameTreeNode
|
|
48
48
|
class Names < Dictionary
|
|
49
49
|
|
|
50
|
+
define_type :XXNames
|
|
51
|
+
|
|
50
52
|
define_field :Dests, type: NameTreeNode, version: '1.2'
|
|
51
53
|
define_field :AP, type: NameTreeNode, version: '1.3'
|
|
52
54
|
define_field :JavaScript, type: NameTreeNode, version: '1.3'
|
|
@@ -58,11 +60,6 @@ module HexaPDF
|
|
|
58
60
|
define_field :AlternatePresentations, type: NameTreeNode, version: '1.4'
|
|
59
61
|
define_field :Renditions, type: NameTreeNode, version: '1.5'
|
|
60
62
|
|
|
61
|
-
# Returns +:XXNames+.
|
|
62
|
-
def type
|
|
63
|
-
:XXNames
|
|
64
|
-
end
|
|
65
|
-
|
|
66
63
|
end
|
|
67
64
|
|
|
68
65
|
end
|
|
@@ -95,8 +95,9 @@ module HexaPDF
|
|
|
95
95
|
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
define_type :ObjStm
|
|
98
99
|
|
|
99
|
-
define_field :Type, type: Symbol, required: true, default:
|
|
100
|
+
define_field :Type, type: Symbol, required: true, default: self.type, version: '1.5'
|
|
100
101
|
define_field :N, type: Integer # not required, will be auto-filled on #write_objects
|
|
101
102
|
define_field :First, type: Integer # not required, will be auto-filled on #write_objects
|
|
102
103
|
define_field :Extends, type: Stream
|
data/lib/hexapdf/type/page.rb
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
# is created or manipulated using HexaPDF.
|
|
32
32
|
#++
|
|
33
33
|
|
|
34
|
+
require 'hexapdf/error'
|
|
34
35
|
require 'hexapdf/dictionary'
|
|
35
36
|
require 'hexapdf/stream'
|
|
36
37
|
require 'hexapdf/type/page_tree_node'
|
|
@@ -99,14 +100,26 @@ module HexaPDF
|
|
|
99
100
|
Executive: [0, 0, 522, 756].freeze,
|
|
100
101
|
}.freeze
|
|
101
102
|
|
|
103
|
+
# Returns the media box for the given paper size. See PAPER_SIZE for the defined paper sizes.
|
|
104
|
+
def self.media_box(paper_size, orientation: :portrait)
|
|
105
|
+
unless PAPER_SIZE.key?(paper_size)
|
|
106
|
+
raise HexaPDF::Error, "Invalid paper size specified: #{paper_size}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
media_box = PAPER_SIZE[paper_size].dup
|
|
110
|
+
media_box[2], media_box[3] = media_box[3], media_box[2] if orientation == :landscape
|
|
111
|
+
media_box
|
|
112
|
+
end
|
|
113
|
+
|
|
102
114
|
# The inheritable fields.
|
|
103
115
|
INHERITABLE_FIELDS = [:Resources, :MediaBox, :CropBox, :Rotate].freeze
|
|
104
116
|
|
|
105
117
|
# The required inheritable fields.
|
|
106
118
|
REQUIRED_INHERITABLE_FIELDS = [:Resources, :MediaBox].freeze
|
|
107
119
|
|
|
120
|
+
define_type :Page
|
|
108
121
|
|
|
109
|
-
define_field :Type, type: Symbol, required: true, default:
|
|
122
|
+
define_field :Type, type: Symbol, required: true, default: self.type
|
|
110
123
|
define_field :Parent, type: :Pages, required: true, indirect: true
|
|
111
124
|
define_field :LastModified, type: PDFDate, version: '1.3'
|
|
112
125
|
define_field :Resources, type: :XXResources
|
|
@@ -59,7 +59,9 @@ module HexaPDF
|
|
|
59
59
|
# See: PDF1.7 s7.7.3.2, Page
|
|
60
60
|
class PageTreeNode < Dictionary
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
define_type :Pages
|
|
63
|
+
|
|
64
|
+
define_field :Type, type: Symbol, required: true, default: self.type
|
|
63
65
|
define_field :Parent, type: Dictionary, indirect: true
|
|
64
66
|
define_field :Kids, type: Array, required: true, default: []
|
|
65
67
|
define_field :Count, type: Integer, required: true, default: 0
|
|
@@ -212,12 +214,13 @@ module HexaPDF
|
|
|
212
214
|
|
|
213
215
|
private
|
|
214
216
|
|
|
215
|
-
# Returns a new page object, correctly initialized using the document's configuration
|
|
216
|
-
# options.
|
|
217
|
+
# Returns a new page object, correctly initialized using the document's configuration options.
|
|
217
218
|
def new_page
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
box = config['page.default_media_box']
|
|
220
|
+
if box.kind_of?(Symbol)
|
|
221
|
+
box = Page.media_box(box, orientation: config['page.default_media_orientation'])
|
|
222
|
+
end
|
|
223
|
+
document.add(Type: :Page, MediaBox: box)
|
|
221
224
|
end
|
|
222
225
|
|
|
223
226
|
# Ensures that the /Count and /Parent fields of the whole page tree are set up correctly and
|
|
@@ -44,6 +44,8 @@ module HexaPDF
|
|
|
44
44
|
# See: PDF1.7 s7.8.3
|
|
45
45
|
class Resources < Dictionary
|
|
46
46
|
|
|
47
|
+
define_type :XXResources
|
|
48
|
+
|
|
47
49
|
define_field :ExtGState, type: Dictionary
|
|
48
50
|
define_field :ColorSpace, type: Dictionary
|
|
49
51
|
define_field :Pattern, type: Dictionary
|
|
@@ -53,11 +55,6 @@ module HexaPDF
|
|
|
53
55
|
define_field :ProcSet, type: Array
|
|
54
56
|
define_field :Properties, type: Dictionary, version: '1.2'
|
|
55
57
|
|
|
56
|
-
# Returns +:XXResources+.
|
|
57
|
-
def type
|
|
58
|
-
:XXResources
|
|
59
|
-
end
|
|
60
|
-
|
|
61
58
|
# Returns the color space stored under the given name.
|
|
62
59
|
#
|
|
63
60
|
# If the color space is not found, an error is raised.
|
data/lib/hexapdf/type/trailer.rb
CHANGED
|
@@ -55,6 +55,8 @@ module HexaPDF
|
|
|
55
55
|
# XRefStream
|
|
56
56
|
class Trailer < Dictionary
|
|
57
57
|
|
|
58
|
+
define_type :XXTrailer
|
|
59
|
+
|
|
58
60
|
define_field :Size, type: Integer, indirect: false # will be auto-set when written
|
|
59
61
|
define_field :Prev, type: Integer
|
|
60
62
|
define_field :Root, type: :Catalog, indirect: true
|
|
@@ -63,11 +65,6 @@ module HexaPDF
|
|
|
63
65
|
define_field :ID, type: Array
|
|
64
66
|
define_field :XRefStm, type: Integer, version: '1.5'
|
|
65
67
|
|
|
66
|
-
# Returns +:XXTrailer+.
|
|
67
|
-
def type
|
|
68
|
-
:XXTrailer
|
|
69
|
-
end
|
|
70
|
-
|
|
71
68
|
# Returns the document's Catalog (see Type::Catalog), creating it if needed.
|
|
72
69
|
def catalog
|
|
73
70
|
self[:Root] ||= document.add(Type: :Catalog)
|
|
@@ -44,6 +44,8 @@ module HexaPDF
|
|
|
44
44
|
# See: PDF1.7 s12.2, Catalog
|
|
45
45
|
class ViewerPreferences < Dictionary
|
|
46
46
|
|
|
47
|
+
define_type :XXViewerPreferences
|
|
48
|
+
|
|
47
49
|
define_field :HideToolbar, type: Boolean, default: false
|
|
48
50
|
define_field :HideMenubar, type: Boolean, default: false
|
|
49
51
|
define_field :HideWindowUI, type: Boolean, default: false
|
|
@@ -62,11 +64,6 @@ module HexaPDF
|
|
|
62
64
|
define_field :PrintPageRange, type: Array, version: '1.7'
|
|
63
65
|
define_field :NumCopies, type: Integer, version: '1.7'
|
|
64
66
|
|
|
65
|
-
# Returns +:XXViewerPreferences+.
|
|
66
|
-
def type
|
|
67
|
-
:XXViewerPreferences
|
|
68
|
-
end
|
|
69
|
-
|
|
70
67
|
end
|
|
71
68
|
|
|
72
69
|
end
|
|
@@ -65,7 +65,9 @@ module HexaPDF
|
|
|
65
65
|
# See: PDF1.7 s7.5.8
|
|
66
66
|
class XRefStream < HexaPDF::Stream
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
define_type :XRef
|
|
69
|
+
|
|
70
|
+
define_field :Type, type: Symbol, default: self.type, required: true, indirect: false, version: '1.5'
|
|
69
71
|
# Size is not required because it will be auto-filled before the object is written
|
|
70
72
|
define_field :Size, type: Integer, indirect: false
|
|
71
73
|
define_field :Index, type: Array, indirect: false
|
data/lib/hexapdf/version.rb
CHANGED
|
@@ -206,6 +206,8 @@ module CommonTokenizerTests
|
|
|
206
206
|
|
|
207
207
|
it "next_xref_entry: fails on invalidly formatted entries" do
|
|
208
208
|
create_tokenizer("0000000001 00001 g \n")
|
|
209
|
-
assert_raises(
|
|
209
|
+
assert_raises(RuntimeError) { @tokenizer.next_xref_entry { raise }}
|
|
210
|
+
create_tokenizer("0000000001 00001 n\n")
|
|
211
|
+
assert_raises(RuntimeError) { @tokenizer.next_xref_entry { raise }}
|
|
210
212
|
end
|
|
211
213
|
end
|
|
@@ -87,6 +87,17 @@ describe HexaPDF::Content::Canvas do
|
|
|
87
87
|
assert_operators(@canvas.contents, [[:save_graphics_state], [:restore_graphics_state]])
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
it "saves needed font state information not stored in the graphics state" do
|
|
91
|
+
@canvas.save_graphics_state do
|
|
92
|
+
@canvas.font("Times", size: 12)
|
|
93
|
+
@canvas.save_graphics_state do
|
|
94
|
+
@canvas.font("Helvetica")
|
|
95
|
+
end
|
|
96
|
+
assert_equal("Times-Roman", @canvas.font.wrapped_font.font_name)
|
|
97
|
+
end
|
|
98
|
+
assert_nil(@canvas.font)
|
|
99
|
+
end
|
|
100
|
+
|
|
90
101
|
it "fails if invoked while in an unsupported graphics objects" do
|
|
91
102
|
assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.save_graphics_state }
|
|
92
103
|
end
|
|
@@ -999,9 +1010,9 @@ describe HexaPDF::Content::Canvas do
|
|
|
999
1010
|
it "returns the set font" do
|
|
1000
1011
|
assert_nil(@canvas.font)
|
|
1001
1012
|
@canvas.font("Times", size: 10)
|
|
1002
|
-
assert_same(@doc.fonts.
|
|
1013
|
+
assert_same(@doc.fonts.add("Times"), @canvas.font)
|
|
1003
1014
|
@canvas.font(@canvas.font)
|
|
1004
|
-
assert_same(@doc.fonts.
|
|
1015
|
+
assert_same(@doc.fonts.add("Times"), @canvas.font)
|
|
1005
1016
|
@canvas.font("Helvetica", size: 10)
|
|
1006
1017
|
assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
|
|
1007
1018
|
[:set_leading, [12.0]],
|
|
@@ -1010,7 +1021,7 @@ describe HexaPDF::Content::Canvas do
|
|
|
1010
1021
|
|
|
1011
1022
|
it "sets the font and optionally the font size" do
|
|
1012
1023
|
@canvas.font("Times", size: 12, variant: :italic)
|
|
1013
|
-
assert_same(@doc.fonts.
|
|
1024
|
+
assert_same(@doc.fonts.add("Times", variant: :italic), @canvas.font)
|
|
1014
1025
|
assert_equal(12, @canvas.font_size)
|
|
1015
1026
|
@canvas.font("Helvetica")
|
|
1016
1027
|
assert_equal(12, @canvas.font_size)
|
|
@@ -1066,6 +1077,11 @@ describe HexaPDF::Content::Canvas do
|
|
|
1066
1077
|
[:show_text_with_positioning, [["Hal"]]],
|
|
1067
1078
|
])
|
|
1068
1079
|
end
|
|
1080
|
+
|
|
1081
|
+
it "fails if no valid font is set" do
|
|
1082
|
+
error = assert_raises(HexaPDF::Error) { @canvas.show_glyphs([]) }
|
|
1083
|
+
assert_match(/if a font is set/, error.message)
|
|
1084
|
+
end
|
|
1069
1085
|
end
|
|
1070
1086
|
|
|
1071
1087
|
describe "show_glyphs_only" do
|
|
@@ -1081,6 +1097,11 @@ describe HexaPDF::Content::Canvas do
|
|
|
1081
1097
|
[:show_text_with_positioning, [["Ha", -35, "l lo"]]],
|
|
1082
1098
|
])
|
|
1083
1099
|
end
|
|
1100
|
+
|
|
1101
|
+
it "fails if no valid font is set" do
|
|
1102
|
+
error = assert_raises(HexaPDF::Error) { @canvas.show_glyphs([]) }
|
|
1103
|
+
assert_match(/if a font is set/, error.message)
|
|
1104
|
+
end
|
|
1084
1105
|
end
|
|
1085
1106
|
|
|
1086
1107
|
describe "text" do
|
|
@@ -1112,6 +1133,11 @@ describe HexaPDF::Content::Canvas do
|
|
|
1112
1133
|
[:show_text_with_positioning, [["H"]]],
|
|
1113
1134
|
])
|
|
1114
1135
|
end
|
|
1136
|
+
|
|
1137
|
+
it "fails if no valid font is set" do
|
|
1138
|
+
error = assert_raises(HexaPDF::Error) { @canvas.show_glyphs([]) }
|
|
1139
|
+
assert_match(/if a font is set/, error.message)
|
|
1140
|
+
end
|
|
1115
1141
|
end
|
|
1116
1142
|
|
|
1117
1143
|
describe "marked_content_point" do
|
|
@@ -77,6 +77,17 @@ class GraphicsStateWrapper < Minitest::Spec
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
describe LineDashPattern do
|
|
80
|
+
it "returns a normalized line dash pattern from various values" do
|
|
81
|
+
assert_equal([[], 0], LineDashPattern.normalize(0).to_operands)
|
|
82
|
+
assert_equal([[5], 0], LineDashPattern.normalize(5).to_operands)
|
|
83
|
+
assert_equal([[5, 3], 2], LineDashPattern.normalize([5, 3], 2).to_operands)
|
|
84
|
+
assert_equal([[5], 1], LineDashPattern.normalize(LineDashPattern.normalize(5, 1)).to_operands)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "fails on normalization if an invalid array argument is provided" do
|
|
88
|
+
assert_raises(ArgumentError) { LineDashPattern.normalize(:bla) }
|
|
89
|
+
end
|
|
90
|
+
|
|
80
91
|
it "fails on initialization if the phase is negative" do
|
|
81
92
|
assert_raises(ArgumentError) { LineDashPattern.new([], -1) }
|
|
82
93
|
end
|
|
@@ -463,8 +463,9 @@ end
|
|
|
463
463
|
|
|
464
464
|
describe_operator :SetTextRenderingMode, :Tr do
|
|
465
465
|
it "modifies the text rendering mode" do
|
|
466
|
-
invoke(
|
|
467
|
-
assert_equal(
|
|
466
|
+
invoke(HexaPDF::Content::TextRenderingMode::FILL_STROKE)
|
|
467
|
+
assert_equal(HexaPDF::Content::TextRenderingMode::FILL_STROKE,
|
|
468
|
+
@processor.graphics_state.text_rendering_mode)
|
|
468
469
|
end
|
|
469
470
|
end
|
|
470
471
|
|
|
@@ -9,7 +9,7 @@ describe HexaPDF::Document::Fonts do
|
|
|
9
9
|
@doc.config['font_loader'] = []
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
describe "
|
|
12
|
+
describe "add" do
|
|
13
13
|
before do
|
|
14
14
|
@doc.config['font_loader'] << lambda do |doc, name, **options|
|
|
15
15
|
assert_equal(@doc, doc)
|
|
@@ -26,23 +26,23 @@ describe HexaPDF::Document::Fonts do
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it "loads the specified font" do
|
|
29
|
-
assert_equal(:NormalFont, @doc.fonts.
|
|
30
|
-
assert_equal(:BoldFont, @doc.fonts.
|
|
29
|
+
assert_equal(:NormalFont, @doc.fonts.add(:TestFont).name)
|
|
30
|
+
assert_equal(:BoldFont, @doc.fonts.add(:TestFont, variant: :bold).name)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "caches loaded fonts" do
|
|
34
|
-
font = @doc.fonts.
|
|
35
|
-
assert_same(font, @doc.fonts.
|
|
36
|
-
assert_same(font, @doc.fonts.
|
|
34
|
+
font = @doc.fonts.add(:TestFont)
|
|
35
|
+
assert_same(font, @doc.fonts.add(:TestFont))
|
|
36
|
+
assert_same(font, @doc.fonts.add(:TestFont, variant: :none))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "fails if the requested font is not found" do
|
|
40
|
-
assert_raises(HexaPDF::Error) { @doc.fonts.
|
|
40
|
+
assert_raises(HexaPDF::Error) { @doc.fonts.add("Unknown") }
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "raises an error if a font loader cannot be correctly retrieved" do
|
|
44
44
|
@doc.config['font_loader'][0] = 'UnknownFontLoader'
|
|
45
|
-
assert_raises(HexaPDF::Error) { @doc.fonts.
|
|
45
|
+
assert_raises(HexaPDF::Error) { @doc.fonts.add(:Other) }
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|