Skip to content

Commit 2409850

Browse files
committed
Simplify CIDFontWidth parsing and allow multiple consecutive closing brackets
1 parent a2b2bd9 commit 2409850

4 files changed

Lines changed: 37 additions & 22 deletions

File tree

src/Document/Dictionary/DictionaryValue/Array/ArrayValue.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ public static function fromValue(string $valueString): self|ReferenceValueArray|
2626
return null;
2727
}
2828

29+
$sanitizedValueString = substr($sanitizedValueString, 1, -1);
2930
$sanitizedValueString = preg_replace('/(<[^>]*>)(?=<[^>]*>)/', '$1 $2', $sanitizedValueString)
3031
?? throw new RuntimeException('An error occurred while sanitizing array value');
31-
$sanitizedValueString = str_replace(['/', "\n"], [' /', ' '], rtrim(ltrim($sanitizedValueString, '[ '), ' ]'));
32+
$sanitizedValueString = str_replace(['/', "\n"], [' /', ' '], $sanitizedValueString);
3233
$sanitizedValueString = preg_replace('/\s+/', ' ', $sanitizedValueString)
3334
?? throw new RuntimeException('An error occurred while removing duplicate spaces from array value');
3435

src/Document/Dictionary/DictionaryValue/Array/CIDFontWidths.php

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Array\Item\ConsecutiveCIDWidth;
77
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Array\Item\RangeCIDWidth;
88
use PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\DictionaryValue;
9-
use PrinsFrank\PdfParser\Exception\RuntimeException;
109

1110
/** @see 9.7.4.3 Glyph metrics in CIDFonts */
1211
class CIDFontWidths implements DictionaryValue {
@@ -37,37 +36,33 @@ public static function fromValue(string $valueString): ?self {
3736
return new self();
3837
}
3938

40-
if (preg_match_all('/(?<startingCID>[0-9]+)\s*(?<CIDS>[0-9]+\s*[0-9.]+|\[[0-9. ]+\])/', $valueString, $matches, PREG_SET_ORDER) <= 0) {
39+
if (($arrayValue = ArrayValue::fromValue($valueString)) instanceof ArrayValue === false) {
4140
return null;
4241
}
4342

4443
$widths = [];
45-
foreach ($matches as $match) {
46-
if ((string) ($startingCID = (int) $match['startingCID']) !== $match['startingCID']) {
44+
$nrOfTopLevelItems = count($arrayValue->value);
45+
for ($i = 0; $i < $nrOfTopLevelItems; $i++) {
46+
$item = $arrayValue->value[$i];
47+
if (is_int($item) === false) {
4748
return null;
4849
}
4950

50-
if (str_starts_with($match['CIDS'], '[') && str_ends_with($match['CIDS'], ']')) {
51-
$cidWidths = preg_split('/\s+/', trim(rtrim(ltrim($match['CIDS'], '['), ']')), -1, PREG_SPLIT_NO_EMPTY);
52-
if ($cidWidths === false) {
53-
throw new RuntimeException('Something went wrong while splitting');
51+
if (($nextItem = $arrayValue->value[$i + 1] ?? null) instanceof ArrayValue) {
52+
foreach ($nextItem->value as $itemValue) {
53+
if (is_string($itemValue) === false && is_int($itemValue) === false) {
54+
return null;
55+
}
5456
}
5557

56-
$widths[] = new ConsecutiveCIDWidth($startingCID, array_map('floatval', $cidWidths));
57-
58-
continue;
59-
}
60-
61-
$arguments = explode(' ', $match['CIDS']);
62-
if (count($arguments) !== 2) {
58+
$widths[] = new ConsecutiveCIDWidth($item, array_map(fn(string|int $value) => is_string($value) ? (float) $value : $value, $nextItem->value));
59+
$i++;
60+
} elseif (is_int($nextItem) && (is_string($secondNextItem = $arrayValue->value[$i + 2] ?? null) || is_int($secondNextItem))) {
61+
$widths[] = new RangeCIDWidth($item, $nextItem, (float) $secondNextItem);
62+
$i += 2;
63+
} else {
6364
return null;
6465
}
65-
66-
if ((string) ($endCID = (int) $arguments[0]) !== $arguments[0] || (string) ($width = (float) $arguments[1]) !== $arguments[1]) {
67-
return null;
68-
}
69-
70-
$widths[] = new RangeCIDWidth($startingCID, $endCID, $width);
7166
}
7267

7368
return new self(... $widths);

tests/Unit/Document/Dictionary/DictionaryValue/Array/ArrayValueTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public function testFromValue(): void {
2121
new ArrayValue([42, 43]),
2222
ArrayValue::fromValue('[42 43]'),
2323
);
24+
static::assertEquals(
25+
new ArrayValue([new ArrayValue([42, 43])]),
26+
ArrayValue::fromValue('[[42 43]]'),
27+
);
2428
static::assertEquals(
2529
new ArrayValue([42, 43]),
2630
ArrayValue::fromValue(' [42 43] '),

tests/Unit/Document/Dictionary/DictionaryValue/Array/CIDFontWidthsTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ public function testFromValueWithPaddedBrackets(): void {
6060
);
6161
}
6262

63+
public function testFromValueWithCompactBrackets(): void {
64+
static::assertEquals(
65+
new CIDFontWidths(
66+
new ConsecutiveCIDWidth(3, [278]),
67+
new ConsecutiveCIDWidth(18, [278]),
68+
new ConsecutiveCIDWidth(46, [722]),
69+
new ConsecutiveCIDWidth(72, [556]),
70+
new ConsecutiveCIDWidth(80, [889]),
71+
new RangeCIDWidth(81, 82, 611),
72+
new ConsecutiveCIDWidth(88, [611]),
73+
),
74+
CIDFontWidths::fromValue('[3[278] 18[278] 46[722] 72[556] 80[889] 81 82 611 88[611]]'),
75+
);
76+
}
77+
6378
public function testFromValueAcceptsEmptyArray(): void {
6479
static::assertEquals(
6580
new CIDFontWidths(),

0 commit comments

Comments
 (0)