Browse Source

implement custom word wrap for text blocks

PHP-GTK3
yggverse 4 months ago
parent
commit
7ec3d06db9
  1. 72
      src/Abstract/Entity/Browser/Container/Page/Content/Markup.php
  2. 69
      src/Abstract/Model/Gtk/Pango/Markup.php
  3. 3
      src/Entity/Browser/Container/Page/Content/Gemtext.php
  4. 6
      src/Interface/Model/Gtk/Pango/Markup.php

72
src/Abstract/Entity/Browser/Container/Page/Content/Markup.php

@ -18,11 +18,7 @@ abstract class Markup @@ -18,11 +18,7 @@ abstract class Markup
// Dependencies
public Content $content;
// Defaults
public const WRAP = 140;
// Extras
protected int $_wrap = self::WRAP;
protected ?string $_source = null;
public function __construct(
@ -113,11 +109,18 @@ abstract class Markup @@ -113,11 +109,18 @@ abstract class Markup
return false;
}
// Require custom wordwrap implementation on widget resize
abstract protected function _onSizeAllocate(
// Custom wordwrap on widget resize
protected function _onSizeAllocate(
GtkLabel $label,
GdkEvent $event
): bool;
): bool
{
$this->set( // @TODO Gtk::timeout_add
$this->_source
);
return false;
}
// Require custom layout implementation
abstract public function set(
@ -125,61 +128,6 @@ abstract class Markup @@ -125,61 +128,6 @@ abstract class Markup
): void;
// Tools
protected function _line(
int $offset
): ?string
{
if (is_null($this->_source))
{
return null;
}
$start = strrpos(
substr(
$this->_source,
0,
$offset
),
PHP_EOL
) + 1;
$end = strpos(
$this->_source,
PHP_EOL,
$offset
);
if ($end === false)
{
$end = strlen(
$this->_source
);
}
return substr(
$this->_source,
$start,
$end - $start
);
}
protected function _wrap(
string $source
): string
{
if ($wrap = $this->_wrap ? $this->_wrap : $this::WRAP)
{
return wordwrap(
$source,
$wrap,
PHP_EOL,
false
);
}
throw new Exception;
}
protected function _url(
string $link
): ?string

69
src/Abstract/Model/Gtk/Pango/Markup.php

@ -4,6 +4,9 @@ declare(strict_types=1); @@ -4,6 +4,9 @@ declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Model\Gtk\Pango;
use \PangoLayout;
use \GtkDrawingArea;
class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup
{
public static function code(
@ -99,11 +102,15 @@ class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup @@ -99,11 +102,15 @@ class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup
}
public static function text(
string $value
string $value,
int $width = self::WRAP_WIDTH
): string
{
return htmlspecialchars(
$value
self::_wrap(
$value,
$width
)
);
}
@ -131,4 +138,62 @@ class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup @@ -131,4 +138,62 @@ class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup
throw new Exception;
}
public static function width(
string $markup
): ?int
{
$layout = new PangoLayout(
(new GtkDrawingArea)->create_pango_context()
);
$layout->set_markup(
$markup,
mb_strlen(
$markup,
'UTF-8'
)
);
if ($size = $layout->get_pixel_size())
{
return $size['width'];
}
return null;
}
protected static function _wrap(
string $string,
int $width = self::WRAP_WIDTH,
int $line = 1
): string
{
$words = [];
foreach (explode(' ', $string) as $word)
{
if (isset($words[$line]) && Markup::width(implode(' ', $words[$line])) > $width)
{
$line++;
}
$words[$line][] = $word;
}
$lines = [];
foreach ($words as $values)
{
$lines[] = implode(
' ',
$values
);
}
return implode(
PHP_EOL,
$lines
);
}
}

3
src/Entity/Browser/Container/Page/Content/Gemtext.php

@ -180,7 +180,8 @@ class Gemtext extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Page\Cont @@ -180,7 +180,8 @@ class Gemtext extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Page\Cont
else
{
$line[] = Markup::text(
$entity->getData()
$entity->getData(),
$this->content->page->gtk->get_allocated_width()
);
}

6
src/Interface/Model/Gtk/Pango/Markup.php

@ -12,6 +12,8 @@ interface Markup @@ -12,6 +12,8 @@ interface Markup
{
public const TAG_CODE = 'tt';
public const WRAP_WIDTH = 140;
public static function code(
string $value
): string;
@ -54,4 +56,8 @@ interface Markup @@ -54,4 +56,8 @@ interface Markup
string $const,
bool $close
): string;
public static function width(
string $markup
): ?int;
}
Loading…
Cancel
Save