Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions src/Bidi.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Mpdf;

use Mpdf\Shaper\OtlData;
use Mpdf\Utils\UtfString;

/**
Expand All @@ -11,8 +12,9 @@
* resolved and in string form. Nothing here reads a font table - this is the Unicode algorithm over
* the classes Ucdn supplies, which is why it sits beside Ucdn rather than under Fonts.
*
* prepare() takes an Otl because resolving the explicit embedding controls means deleting them from
* the text afterwards, and removing a character from text and its OTLdata together is Otl's job.
* prepare() takes the document's text encoding because resolving the explicit embedding controls
* means deleting them from the text afterwards, which Shaper\OtlData does to the text and its OTLdata
* together, counting characters in that encoding.
*
* @see https://www.unicode.org/reports/tr9/
*
Expand Down Expand Up @@ -445,7 +447,7 @@ public static function sort($ta, $str, $dir, &$chunkOTLdata, $useGPOS)
* from Mpdf::printbuffer(); reorder() then rearranges, from WriteFlowingBlock() and
* finishFlowingBlock(), once line breaks have divided the paragraph into lines.
*/
public static function prepare(&$para, $dir, Otl $otl)
public static function prepare(&$para, $dir, $encoding)
{

// Set the initial paragraph embedding level
Expand Down Expand Up @@ -653,11 +655,11 @@ public static function prepare(&$para, $dir, Otl $otl)
// Paragraph separators are not included in the embedding.
// X9. Remove all RLE, LRE, RLO, LRO, and PDF codes.
if ($controlchars) {
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xaa");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xab");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xac");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xad");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xae");
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xaa", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xab", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xac", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xad", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xae", $encoding);
preg_replace("/\x{202a}-\x{202e}/u", '', $para[$nc][0]);
}
}
Expand Down Expand Up @@ -1011,10 +1013,10 @@ public static function prepare(&$para, $dir, Otl $otl)
$numchunks = count($para);
if ($controlchars) {
for ($nc = 0; $nc < $numchunks; $nc++) {
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa6");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa7");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa8");
$otl->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa9");
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa6", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa7", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa8", $encoding);
OtlData::removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa9", $encoding);
preg_replace("/\x{2066}-\x{2069}/u", '', $para[$nc][0]);
}
// Remove any blank chunks made by removing directional codes
Expand Down
62 changes: 30 additions & 32 deletions src/Mpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Mpdf\Output\Destination;
use Mpdf\PsrLogAwareTrait\MpdfPsrLogAwareTrait;
use Mpdf\QrCode;
use Mpdf\Shaper\OtlData;
use Mpdf\Utils\Arrays;
use Mpdf\Utils\NumericString;
use Mpdf\Utils\UtfString;
Expand Down Expand Up @@ -6141,8 +6142,8 @@ function MultiCell(

/* -- OTL -- */
if (isset($OTLdata)) {
$tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j);
$this->otl->trimOTLdata($tmpOTLdata, false, true);
$tmpOTLdata = OtlData::slice($OTLdata, $j, $i - $j);
OtlData::trim($tmpOTLdata, false, true);
$this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
}
/* -- END OTL -- */
Expand Down Expand Up @@ -6191,8 +6192,8 @@ function MultiCell(

/* -- OTL -- */
if (isset($OTLdata)) {
$tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j);
$this->otl->trimOTLdata($tmpOTLdata, false, true);
$tmpOTLdata = OtlData::slice($OTLdata, $j, $i - $j);
OtlData::trim($tmpOTLdata, false, true);
$this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
}
/* -- END OTL -- */
Expand All @@ -6206,8 +6207,8 @@ function MultiCell(

/* -- OTL -- */
if (isset($OTLdata)) {
$tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $sep - $j);
$this->otl->trimOTLdata($tmpOTLdata, false, true);
$tmpOTLdata = OtlData::slice($OTLdata, $j, $sep - $j);
OtlData::trim($tmpOTLdata, false, true);
}
/* -- END OTL -- */

Expand Down Expand Up @@ -6382,8 +6383,8 @@ function MultiCell(

/* -- OTL -- */
if (isset($OTLdata)) {
$tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i - $j);
$this->otl->trimOTLdata($tmpOTLdata, false, true);
$tmpOTLdata = OtlData::slice($OTLdata, $j, $i - $j);
OtlData::trim($tmpOTLdata, false, true);
$this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
}
/* -- END OTL -- */
Expand Down Expand Up @@ -6646,7 +6647,7 @@ function finishFlowingBlock($endofblock = false, $next = '')
$content[count($content) - 1] = substr($content[count($content) - 1], 0, (strlen($content[count($content) - 1]) - $strip));
/* -- OTL -- */
if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
$this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], false, true);
OtlData::trim($cOTLdata[count($cOTLdata) - 1], false, true);
}
/* -- END OTL -- */
}
Expand Down Expand Up @@ -6735,9 +6736,9 @@ function finishFlowingBlock($endofblock = false, $next = '')
/* -- OTL -- */
// mPDF 5.7.1
if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
$this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad");
$this->otl->removeChar($chunk, $cOTLdata[$k], "\xe2\x80\x8b");
$this->otl->replaceSpace($chunk, $cOTLdata[$k]);
OtlData::removeChar($chunk, $cOTLdata[$k], "\xc2\xad", $this->mb_enc);
OtlData::removeChar($chunk, $cOTLdata[$k], "\xe2\x80\x8b", $this->mb_enc);
OtlData::nbspToSpace($chunk, $cOTLdata[$k], $this->mb_enc);
$content[$k] = $chunk;
} /* -- END OTL -- */ else { // *OTL*
$content[$k] = $chunk = str_replace("\xc2\xad", '', $chunk);
Expand Down Expand Up @@ -8381,7 +8382,7 @@ function WriteFlowingBlock($s, $sOTLdata)
$savedPreFont[] = $font[$cutcontentctr];
/* -- OTL -- */
if (!empty($sOTLdata)) {
$savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[$cutcontentctr], $cutcharctr, $cutcharctr);
$savedPreOTLdata[] = OtlData::split($cOTLdata[$cutcontentctr], $cutcharctr, $cutcharctr);
}
/* -- END OTL -- */

Expand All @@ -8402,7 +8403,7 @@ function WriteFlowingBlock($s, $sOTLdata)
}

if (!empty($sOTLdata)) {
$savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent, $this->mb_enc));
$savedPreOTLdata[] = OtlData::split($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent, $this->mb_enc));
}

if (strpos($contentB[(count($contentB) - 1)], 'R') !== false) { // ???
Expand All @@ -8427,7 +8428,7 @@ function WriteFlowingBlock($s, $sOTLdata)
$next = count($savedPreContent) - 1;
$savedPreContent[$next] = '-' . $savedPreContent[$next];
if (!empty($savedPreOTLdata[$next])) {
$this->otl->prependOTLchar($savedPreOTLdata[$next], $charData, 'C');
OtlData::prependChar($savedPreOTLdata[$next], $charData, 'C');
}
}
}
Expand All @@ -8445,7 +8446,7 @@ function WriteFlowingBlock($s, $sOTLdata)
if (!is_array($breakfound)) {
$savedFont = $this->saveFont();
if (!empty($sOTLdata)) {
$savedOTLdata = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent, $this->mb_enc));
$savedOTLdata = OtlData::split($cOTLdata[(count($cOTLdata) - 1)], mb_strlen($currContent, $this->mb_enc));
}
}

Expand All @@ -8465,7 +8466,7 @@ function WriteFlowingBlock($s, $sOTLdata)
} // *CJK-FONTS*
/* -- OTL -- */
if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
$this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], false, true); // NB also does U+3000
OtlData::trim($cOTLdata[count($cOTLdata) - 1], false, true); // NB also does U+3000
}
/* -- END OTL -- */

Expand Down Expand Up @@ -8515,9 +8516,9 @@ function WriteFlowingBlock($s, $sOTLdata)
if (!$this->usingCoreFont) {
/* -- OTL -- */
if ((isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) || !empty($sOTLdata)) {
$this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad");
$this->otl->removeChar($chunk, $cOTLdata[$k], "\xe2\x80\x8b");
$this->otl->replaceSpace($chunk, $cOTLdata[$k]); // NBSP -> space
OtlData::removeChar($chunk, $cOTLdata[$k], "\xc2\xad", $this->mb_enc);
OtlData::removeChar($chunk, $cOTLdata[$k], "\xe2\x80\x8b", $this->mb_enc);
OtlData::nbspToSpace($chunk, $cOTLdata[$k], $this->mb_enc);
if (preg_match("/([" . $this->pregCURSchars . "])/u", $chunk)) {
$inclCursive = true;
}
Expand Down Expand Up @@ -8938,7 +8939,7 @@ function WriteFlowingBlock($s, $sOTLdata)
if ($this->checkCJK && $currContent == "\xe3\x80\x80") {
$currContent = '';
if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
$this->otl->trimOTLdata($cOTLdata[count($cOTLdata) - 1], true, false); // left trim U+3000
OtlData::trim($cOTLdata[count($cOTLdata) - 1], true, false); // left trim U+3000
}
}
/* -- END CJK-FONTS -- */
Expand Down Expand Up @@ -13734,7 +13735,7 @@ function WriteHTML($html, $mode = HTMLParserMode::DEFAULT_MODE, $init = true, $c
}
$e = $this->otl->applyOTL($e, $this->CurrentFont['useOTL']);
$this->OTLdata = $this->otl->OTLdata;
$this->otl->removeChar($e, $this->OTLdata, "\xef\xbb\xbf"); // Remove ZWNBSP (also Byte order mark FEFF)
OtlData::removeChar($e, $this->OTLdata, "\xef\xbb\xbf", $this->mb_enc); // Remove ZWNBSP (also Byte order mark FEFF)
} /* -- END OTL -- */
else {
// removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
Expand All @@ -13758,7 +13759,7 @@ function WriteHTML($html, $mode = HTMLParserMode::DEFAULT_MODE, $init = true, $c
if ($this->specialcontent == "type=select") {
$e = ltrim($e);
if (!empty($this->OTLdata)) {
$this->otl->trimOTLdata($this->OTLdata, true, false);
OtlData::trim($this->OTLdata, true, false);
} // *OTL*
$stringwidth = $this->GetStringWidth($e);
if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) {
Expand Down Expand Up @@ -13796,7 +13797,7 @@ function WriteHTML($html, $mode = HTMLParserMode::DEFAULT_MODE, $init = true, $c
if (($this->ignorefollowingspaces) && !$this->ispre) {
$e = ltrim($e);
if (!empty($this->OTLdata)) {
$this->otl->trimOTLdata($this->OTLdata, true, false);
OtlData::trim($this->OTLdata, true, false);
} // *OTL*
}
if ($e || $e === '0') {
Expand Down Expand Up @@ -13862,7 +13863,7 @@ function WriteHTML($html, $mode = HTMLParserMode::DEFAULT_MODE, $init = true, $c
if ($this->ignorefollowingspaces && !$this->ispre) {
$e = ltrim($e);
if (!empty($this->OTLdata)) {
$this->otl->trimOTLdata($this->OTLdata, true, false);
OtlData::trim($this->OTLdata, true, false);
} // *OTL*
}
if ($e || $e === '0') {
Expand Down Expand Up @@ -16259,10 +16260,7 @@ function printbuffer($arrayaux, $blockstate = 0, $is_table = false, $table_draft
// mPDF 6
// Process bidirectional text ready for bidi-re-ordering (which is done after line-breaks are established in WriteFlowingBlock etc.)
if (($blockdir == 'rtl' || $this->biDirectional) && !$table_draft) {
if (empty($this->otl)) {
$this->otl = new Otl($this, $this->fontCache);
}
Bidi::prepare($arrayaux, $blockdir, $this->otl);
Bidi::prepare($arrayaux, $blockdir, $this->mb_enc);
$array_size = count($arrayaux);
}

Expand Down Expand Up @@ -16310,7 +16308,7 @@ function printbuffer($arrayaux, $blockstate = 0, $is_table = false, $table_draft
if ($i == 0 && $vetor[0] != "\n" && ! $this->ispre) {
$vetor[0] = ltrim($vetor[0]);
if (!empty($vetor[18])) {
$this->otl->trimOTLdata($vetor[18], true, false);
OtlData::trim($vetor[18], true, false);
} // *OTL*
}

Expand Down Expand Up @@ -17055,7 +17053,7 @@ function PaintDivBB($divider = '', $blockstate = 0, $blvl = 0)
$legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
$txt = $legend[0] = ltrim($legend[0]);
if (!empty($legend[18])) {
$this->otl->trimOTLdata($legend[18], true, false);
OtlData::trim($legend[18], true, false);
} // *OTL*
// Set font, size, style, color
$this->SetFont($legend[4], $legend[2], $legend[11]);
Expand Down Expand Up @@ -19207,7 +19205,7 @@ function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer = [], $checkl
}
$line = trim($line);
if (!empty($OTLdata)) {
$this->otl->trimOTLdata($OTLdata, true, true);
OtlData::trim($OTLdata, true, true);
} // *OTL*
// SET FONT SIZE/STYLE from $chunk[n]
// FONTSIZE
Expand Down
Loading
Loading