generated from jric11/baseProject
95 lines
2.5 KiB
PHP
95 lines
2.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* StepP.php
|
||
|
|
*
|
||
|
|
* @since 2011-05-23
|
||
|
|
* @category Library
|
||
|
|
* @package Unicode
|
||
|
|
* @author Nicola Asuni <info@tecnick.com>
|
||
|
|
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
|
||
|
|
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
|
||
|
|
* @link https://github.com/tecnickcom/tc-lib-unicode
|
||
|
|
*
|
||
|
|
* This file is part of tc-lib-unicode software library.
|
||
|
|
*/
|
||
|
|
|
||
|
|
namespace Com\Tecnick\Unicode\Bidi;
|
||
|
|
|
||
|
|
use Com\Tecnick\Unicode\Data\Constant as UniConstant;
|
||
|
|
use Com\Tecnick\Unicode\Data\Type as UniType;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Com\Tecnick\Unicode\Bidi\StepP
|
||
|
|
*
|
||
|
|
* @since 2015-07-13
|
||
|
|
* @category Library
|
||
|
|
* @package Unicode
|
||
|
|
* @author Nicola Asuni <info@tecnick.com>
|
||
|
|
* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD
|
||
|
|
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
|
||
|
|
* @link https://github.com/tecnickcom/tc-lib-unicode
|
||
|
|
*/
|
||
|
|
class StepP
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* P Steps for Bidirectional algorithm
|
||
|
|
*
|
||
|
|
* @param array<int> $ordarr Array of UTF-8 codepoints
|
||
|
|
*/
|
||
|
|
public function __construct(
|
||
|
|
/**
|
||
|
|
* Array of UTF-8 codepoints
|
||
|
|
*/
|
||
|
|
protected array $ordarr,
|
||
|
|
) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the Paragraph Embedding Level
|
||
|
|
*/
|
||
|
|
public function getPel(): int
|
||
|
|
{
|
||
|
|
// P2. In each paragraph, find the first character of type L, AL, or R
|
||
|
|
// while skipping over any characters between an isolate initiator and its matching PDI or,
|
||
|
|
// if it has no matching PDI, the end of the paragraph.
|
||
|
|
// P3. If a character is found in P2 and it is of type AL or R,
|
||
|
|
// then set the paragraph embedding level to one; otherwise, set it to zero.
|
||
|
|
$isolate = 0;
|
||
|
|
foreach ($this->ordarr as $ord) {
|
||
|
|
$isolate = $this->getIsolateLevel($ord, $isolate);
|
||
|
|
if ($isolate !== 0) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
$type = UniType::getType($ord);
|
||
|
|
if ($type === 'L') {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($type === 'R' || $type === 'AL') {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update the level of explicit directional isolates
|
||
|
|
*/
|
||
|
|
protected function getIsolateLevel(int $ord, int $isolate): int
|
||
|
|
{
|
||
|
|
if ($ord === UniConstant::LRI || $ord === UniConstant::RLI || $ord === UniConstant::FSI) {
|
||
|
|
++$isolate;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($ord === UniConstant::PDI) {
|
||
|
|
--$isolate;
|
||
|
|
}
|
||
|
|
|
||
|
|
return \max(0, $isolate);
|
||
|
|
}
|
||
|
|
}
|