hexapdf 0.32.0 → 0.32.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c74f0e152b612b628321f312413a0eb88e52a41a809f7b37e993acb9e0436b2
4
- data.tar.gz: 9dfe8cfaaa10527695b70d9019636ed9cc6059367125a45a3dacde7bc1d8c3bb
3
+ metadata.gz: bee477049a8d45aa858093fa683fef19c4760626c3368bf782b74ca10c26d4e1
4
+ data.tar.gz: e543e4d73eaf80d6f6e434e499715de454f43fb7dae789773282236c2154bc57
5
5
  SHA512:
6
- metadata.gz: f9ee0dbe507a6d31cbf024d2f34e69c15e491bc05a64a0f4039f38bcf6d52192245d6c7d2ac4cb65ae1eb110f8af735afcf13366e15975d96bcc17dda8e2a618
7
- data.tar.gz: 846ce0611e5f125011aa0535d2de69c15c356f6164f9b09f0a314f9968e34e4addda5396c03d82cd70dffc96eaa0408e1a6dd7a6fc55ce59646be5c3f8b4f9a6
6
+ metadata.gz: d2204bac09267cc3459511a4580480b6157dc5eceafd34c61881dbbcc5c52cc457e7862b3d888d0aa5b8260470b38febf2779ee442f697ce971f82044d81f7ee
7
+ data.tar.gz: b77bbcb040ab16e98d3023447a96d7d942a8c80613969bece44ee96427d9235d6db25446dc1ddf6db6ba1f9d0010f4d4f076fdc7ee189947e7ab4cf94a871807
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 0.32.1 - 2023-04-20
2
+
3
+ ### Added
4
+
5
+ * [HexaPDF::Type::FontType0#font_descriptor] and
6
+ [HexaPDF::Type::FontSimple#font_descriptor] for easy access to the font
7
+ descriptor
8
+
9
+ ### Changed
10
+
11
+ * [HexaPDF::Content::Canvas#color_from_specification] to allow strings and color
12
+ objects without a wrapping array
13
+
14
+ ### Fixed
15
+
16
+ * AES 128bit encryption to include unnecessary field in encryption dictionary to
17
+ work around buggy PDF libraries
18
+ * [HexaPDF::Layout::Style::LinkLayer] to correctly process the border color
19
+ * [HexaPDF::Type::AcroForm::AppearanceGenerator] to use fallback for font cap
20
+ height value when necessary
21
+
22
+
1
23
  ## 0.32.0 - 2023-03-08
2
24
 
3
25
  ### Added
@@ -2363,6 +2363,7 @@ module HexaPDF
2363
2363
  # This utility method is meant for use by higher-level methods that need to convert a color
2364
2364
  # specification into a color object for this Canvas object.
2365
2365
  def color_from_specification(spec)
2366
+ spec = Array(spec)
2366
2367
  if spec.length == 1 && spec[0].kind_of?(String)
2367
2368
  ColorSpace.device_color_from_specification(spec)
2368
2369
  elsif spec.length == 1 && spec[0].respond_to?(:color_space)
@@ -358,7 +358,7 @@ module HexaPDF
358
358
  raise(HexaPDF::UnsupportedEncryptionError,
359
359
  "Invalid key length #{key_length} specified")
360
360
  end
361
- dict[:Length] = key_length if dict[:V] == 2
361
+ dict[:Length] = key_length if dict[:V] == 4 || dict[:V] == 2
362
362
 
363
363
  if ![:aes, :arc4].include?(algorithm)
364
364
  raise(HexaPDF::UnsupportedEncryptionError,
@@ -508,6 +508,12 @@ module HexaPDF
508
508
  *matrix.evaluate(box.width, box.height), *matrix.evaluate(0, box.height)]
509
509
  x_minmax = quad_points.values_at(0, 2, 4, 6).minmax
510
510
  y_minmax = quad_points.values_at(1, 3, 5, 7).minmax
511
+ border_color = case @border_color
512
+ when [], nil
513
+ @border_color
514
+ else
515
+ canvas.color_from_specification(@border_color).components
516
+ end
511
517
  annot = {
512
518
  Subtype: :Link,
513
519
  Rect: [x_minmax[0], y_minmax[0], x_minmax[1], y_minmax[1]],
@@ -515,7 +521,7 @@ module HexaPDF
515
521
  Dest: @dest,
516
522
  A: @action,
517
523
  Border: @border,
518
- C: @border_color && canvas.color_from_specification(@border_color).components,
524
+ C: border_color,
519
525
  }
520
526
  (page[:Annots] ||= []) << page.document.add(annot)
521
527
  end
@@ -395,7 +395,9 @@ module HexaPDF
395
395
 
396
396
  # Adobe seems to be vertically centering based on the cap height, if enough space is
397
397
  # available
398
- cap_height = style.font.wrapped_font.cap_height * style.font.scaling_factor / 1000.0 *
398
+ tmp_cap_height = style.font.wrapped_font.cap_height ||
399
+ style.font.pdf_object.font_descriptor&.[](:CapHeight)
400
+ cap_height = tmp_cap_height * style.font.scaling_factor / 1000.0 *
399
401
  style.font_size
400
402
  y = padding + (height - 2 * padding - cap_height) / 2.0
401
403
  y = padding - style.scaled_font_descender if y < 0
@@ -53,6 +53,13 @@ module HexaPDF
53
53
  define_field :FontDescriptor, type: :FontDescriptor, indirect: true
54
54
  define_field :Encoding, type: [Dictionary, Symbol]
55
55
 
56
+ # Returns the font descriptor. May be +nil+ for a standard 14 font.
57
+ #
58
+ # The font descriptor is required except for the standard 14 fonts in PDF version up to 1.7.
59
+ def font_descriptor
60
+ self[:FontDescriptor]
61
+ end
62
+
56
63
  # Returns the encoding object used for this font.
57
64
  #
58
65
  # Note that the encoding is cached internally when accessed the first time.
@@ -63,6 +63,11 @@ module HexaPDF
63
63
  end
64
64
  end
65
65
 
66
+ # Returns the font descriptor of the descendant font.
67
+ def font_descriptor
68
+ descendant_font[:FontDescriptor]
69
+ end
70
+
66
71
  # Returns the writing mode which is either :horizontal or :vertical.
67
72
  def writing_mode
68
73
  cmap.wmode == 0 ? :horizontal : :vertical
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.32.0'
40
+ VERSION = '0.32.1'
41
41
 
42
42
  end
@@ -1280,4 +1280,30 @@ describe HexaPDF::Content::Canvas do
1280
1280
  end
1281
1281
  end
1282
1282
  end
1283
+
1284
+ describe "color_from_specification "do
1285
+ it "accepts a color string" do
1286
+ assert_equal([1, 0, 0], @canvas.color_from_specification("red").components)
1287
+ end
1288
+
1289
+ it "accepts a color string wrapped in an array" do
1290
+ assert_equal([1, 0, 0], @canvas.color_from_specification(["red"]).components)
1291
+ end
1292
+
1293
+ it "accepts a color object" do
1294
+ color = @canvas.color_from_specification("red")
1295
+ assert_equal(color, @canvas.color_from_specification(color))
1296
+ end
1297
+
1298
+ it "accepts a color object wrapped in an array" do
1299
+ color = @canvas.color_from_specification("red")
1300
+ assert_equal(color, @canvas.color_from_specification([color]))
1301
+ end
1302
+
1303
+ it "accepts an array with 1, 3, or 4 color values" do
1304
+ assert_equal([1], @canvas.color_from_specification([255]).components)
1305
+ assert_equal([1, 0, 0], @canvas.color_from_specification([255, 0, 0]).components)
1306
+ assert_equal([1, 0, 0, 0], @canvas.color_from_specification([100, 0, 0, 0]).components)
1307
+ end
1308
+ end
1283
1309
  end
@@ -141,6 +141,11 @@ describe HexaPDF::Encryption::SecurityHandler do
141
141
  @handler.set_up_encryption(key_length: key_length, algorithm: algorithm)
142
142
  assert(result == @handler.dict[:Length])
143
143
  end
144
+
145
+ # Work-around buggy software
146
+ @handler.set_up_encryption(key_length: 128, algorithm: :aes)
147
+ assert_equal(4, @handler.dict[:V])
148
+ assert_equal(128, @handler.dict[:Length])
144
149
  end
145
150
 
146
151
  it "calls the prepare_encryption method" do
@@ -573,10 +573,19 @@ describe HexaPDF::Layout::Style::LinkLayer do
573
573
  assert_equal([0, 0, 1], annot[:Border].value)
574
574
  end
575
575
 
576
- it "uses the specified border and border color" do
577
- annot = call_link(dest: true, border: [10, 10, 2], border_color: [255])
576
+ it "uses the specified border" do
577
+ annot = call_link(dest: true, border: [10, 10, 2])
578
578
  assert_equal([10, 10, 2], annot[:Border].value)
579
- assert_equal([1.0], annot[:C].value)
579
+ end
580
+
581
+ it "uses the specified border color" do
582
+ annot = call_link(dest: true, border_color: "red")
583
+ assert_equal([1.0, 0, 0], annot[:C].value)
584
+ end
585
+
586
+ it "works when the border color is transparent" do
587
+ annot = call_link(dest: true, border_color: [])
588
+ assert_equal([], annot[:C].value)
580
589
  end
581
590
 
582
591
  it "works for simple destinations" do
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.32.0)>>
43
+ <</Producer(HexaPDF version 0.32.1)>>
44
44
  endobj
45
45
  xref
46
46
  3 1
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
72
72
  141
73
73
  %%EOF
74
74
  6 0 obj
75
- <</Producer(HexaPDF version 0.32.0)>>
75
+ <</Producer(HexaPDF version 0.32.1)>>
76
76
  endobj
77
77
  2 0 obj
78
78
  <</Length 10>>stream
@@ -214,7 +214,7 @@ describe HexaPDF::Writer do
214
214
  <</Type/Page/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<<>>>>
215
215
  endobj
216
216
  5 0 obj
217
- <</Producer(HexaPDF version 0.32.0)>>
217
+ <</Producer(HexaPDF version 0.32.1)>>
218
218
  endobj
219
219
  4 0 obj
220
220
  <</Root 1 0 R/Info 5 0 R/Size 6/Type/XRef/W[1 1 2]/Index[0 6]/Filter/FlateDecode/DecodeParms<</Columns 4/Predictor 12>>/Length 33>>stream
@@ -519,6 +519,19 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
519
519
  range: 7)
520
520
  end
521
521
 
522
+ it "falls back to the cap height in the font descriptor for vertical alignment" do
523
+ font_metrics = @form.default_resources.font(:F1).font_wrapper.wrapped_font.metrics
524
+ cap_height = font_metrics.cap_height
525
+ font_metrics.cap_height = nil
526
+
527
+ @generator.create_appearances
528
+ assert_operators(@widget[:AP][:N].stream,
529
+ [:set_text_matrix, [1, 0, 0, 1, 2, 6.41]],
530
+ range: 7)
531
+ ensure
532
+ font_metrics.cap_height = cap_height
533
+ end
534
+
522
535
  it "vertically aligns to the font descender if the text is too high" do
523
536
  @widget[:Rect].height = 5
524
537
  @generator.create_appearances
@@ -13,15 +13,19 @@ describe HexaPDF::Type::FontSimple do
13
13
  <22> <0042>
14
14
  endbfchar
15
15
  EOF
16
- font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
17
- FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
18
- MissingWidth: 500, Descent: -100, CapHeight: 800, StemV: 20})
16
+ @font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
17
+ FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
18
+ MissingWidth: 500, Descent: -100, CapHeight: 800, StemV: 20})
19
19
  @font = @doc.add({Type: :Font, Encoding: :WinAnsiEncoding,
20
- BaseFont: :Embedded, FontDescriptor: font_descriptor, ToUnicode: cmap,
20
+ BaseFont: :Embedded, FontDescriptor: @font_descriptor, ToUnicode: cmap,
21
21
  FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]},
22
22
  type: HexaPDF::Type::FontSimple)
23
23
  end
24
24
 
25
+ it "returns the font descriptor of the font" do
26
+ assert_same(@font_descriptor, @font.font_descriptor)
27
+ end
28
+
25
29
  describe "encoding" do
26
30
  it "fails if /Encoding is absent because encoding_from_font is not implemented" do
27
31
  @font.delete(:Encoding)
@@ -7,8 +7,8 @@ require 'hexapdf/type/font_type0'
7
7
  describe HexaPDF::Type::FontType0 do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- fd = @doc.add({Type: :FontDescriptor, FontBBox: [0, 1, 2, 3]})
11
- @cid_font = @doc.wrap({Type: :Font, Subtype: :CIDFontType2, W: [633, [100]], FontDescriptor: fd,
10
+ @fd = @doc.add({Type: :FontDescriptor, FontBBox: [0, 1, 2, 3]})
11
+ @cid_font = @doc.wrap({Type: :Font, Subtype: :CIDFontType2, W: [633, [100]], FontDescriptor: @fd,
12
12
  CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1}})
13
13
  @font = @doc.wrap({Type: :Font, Subtype: :Type0, Encoding: :H, DescendantFonts: [@cid_font]})
14
14
  end
@@ -26,6 +26,10 @@ describe HexaPDF::Type::FontType0 do
26
26
  assert_equal(@cid_font.value, @font.descendant_font.value)
27
27
  end
28
28
 
29
+ it "returns the font descriptor of the descendant font" do
30
+ assert_same(@fd, @font.font_descriptor)
31
+ end
32
+
29
33
  it "uses the descendant font for getting the width of a code point" do
30
34
  assert_equal(100, @font.width(0x2121))
31
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 0.32.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-08 00:00:00.000000000 Z
11
+ date: 2023-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse