Skip to content

Commit

Permalink
Get dimensions to split a string
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaasuni committed Jan 27, 2024
1 parent 69c38da commit c651c16
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
48 changes: 42 additions & 6 deletions src/Stack.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace Com\Tecnick\Pdf\Font;

use Com\Tecnick\Unicode\Data\Type as UnicodeType;
use Com\Tecnick\Pdf\Font\Exception as FontException;

/**
Expand All @@ -31,11 +32,22 @@
*
* @phpstan-import-type TFontData from Load
*
* @phpstan-type TTextSplit array{
* 'pos': int,
* 'ord': int,
* 'wordwidth': float,
* 'spaces': int,
* 'totwidth': float,
* 'totspacewidth': float,
* }
*
* @phpstan-type TTextDims array{
* 'chars': int,
* 'spaces': int,
* 'totwidth': float,
* 'totspacewidth': float,
* 'words': int,
* 'split': array<int, TTextSplit>,
* }
*
* @phpstan-type TBBox array{float, float, float, float}
Expand Down Expand Up @@ -308,8 +320,9 @@ public function isCharDefined(int $ord): bool
*/
public function getCharWidth(int $ord): float
{
if ($ord == 173) {
// SHY character is not printed, as it is used for text hyphenation
if (($ord == 173) || ($ord == 8203)) {
// 173 = SHY character is not printed, as it is used for text hyphenation
// 8203 = ZWSP character
return 0;
}

Expand Down Expand Up @@ -340,23 +353,46 @@ public function getOrdArrDims(array $uniarr): array
$spaces = 0; // total number of spaces
$totwidth = 0; // total string width
$totspacewidth = 0; // total space width
$words = 0; // total number of words
$spw = $this->getCharWidth(32); // width of a single space
foreach ($uniarr as $ord) {
$totwidth += $this->getCharWidth($ord);
$fact = ($this->stack[$this->index]['spacing'] * $this->stack[$this->index]['stretching']);
$uniarr[] = 8203; // add null at the end to ensure that the last word is processed
$split = [];
foreach ($uniarr as $idx => $ord) {
$unitype = UnicodeType::UNI[$ord];
// 'B' Paragraph Separator
// 'S' Segment Separator
// 'WS' Whitespace
// 'BN' Boundary Neutral
if (($unitype == 'B') || ($unitype == 'S') || ($unitype == 'WS') || ($unitype == 'BN')) {
$split[$words] = [
'pos' => $idx,
'ord' => $ord,
'wordwidth' => 0,
'spaces' => $spaces,
'totwidth' => ($totwidth + ($fact * ($idx - 1))),
'totspacewidth' => ($totspacewidth + ($fact * ($spaces - 1))),
];
if ($words > 0) {
$split[$words]['wordwidth'] = ($split[$words]['totwidth'] - $split[($words - 1)]['totwidth']);
}
$words++;
}
if ($ord == 32) {
++$spaces;
$totspacewidth += $spw;
}
$totwidth += $this->getCharWidth($ord);
}

$fact = ($this->stack[$this->index]['spacing'] * $this->stack[$this->index]['stretching']);
$totwidth += ($fact * ($chars - 1));
$totspacewidth += ($fact * ($spaces - 1));
return [
'chars' => $chars,
'spaces' => $spaces,
'totwidth' => $totwidth,
'totspacewidth' => $totspacewidth,
'words' => $words,
'split' => $split,
];
}

Expand Down
8 changes: 8 additions & 0 deletions test/StackTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ public function testStack(): void
$this->assertEquals(2, $widths['spaces']);
$this->bcAssertEqualsWithDelta(60.9384, $widths['totwidth'], 0.0001);
$this->bcAssertEqualsWithDelta(8.76, $widths['totspacewidth'], 0.0001);
$this->assertEquals(6, $widths['words']);

$this->assertEquals(11, $widths['split'][5]['pos']);
$this->assertEquals(8203, $widths['split'][5]['ord']);
$this->bcAssertEqualsWithDelta(4.92, $widths['split'][5]['wordwidth'], 0.0001);
$this->assertEquals(2, $widths['split'][5]['spaces']);
$this->bcAssertEqualsWithDelta(60.9384, $widths['split'][5]['totwidth'], 0.0001);
$this->bcAssertEqualsWithDelta(8.76, $widths['split'][5]['totspacewidth'], 0.0001);

$outfont = $stack->getOutCurrentFont();
$this->assertEquals("BT /F2 14.000000 Tf ET\r", $outfont);
Expand Down

0 comments on commit c651c16

Please sign in to comment.