Skip to content

Commit 494c4a0

Browse files
committed
feat: add png Exporter class
1 parent 09feb82 commit 494c4a0

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

src/Exporter.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the CLI-SYNTAX package.
7+
*
8+
* (c) Jitendra Adhikari <[email protected]>
9+
* <https://github.com/adhocore>
10+
*
11+
* Licensed under MIT license.
12+
*/
13+
14+
namespace Ahc\CliSyntax;
15+
16+
class Exporter extends Pretty
17+
{
18+
/** @var integer Font size */
19+
protected $size = 16;
20+
21+
/** @var string Font path */
22+
protected $font = __DIR__ . '/../font/dejavu.ttf';
23+
24+
/** @var resource The image */
25+
protected $image;
26+
27+
/** @var array */
28+
protected $imgSize = [];
29+
30+
/** @var array Colors cached for each types. */
31+
protected static $colors = [];
32+
33+
/** @var array Lengths of each line */
34+
protected static $lengths = [];
35+
36+
public function __destruct()
37+
{
38+
if (\is_resource($this->image)) {
39+
\imagedestroy($this->image);
40+
}
41+
}
42+
43+
public function export(string $output)
44+
{
45+
$this->imgSize = $this->estimateSize($this->code, 25);
46+
$this->image = \imagecreate($this->imgSize['x'], $this->imgSize['y']);
47+
48+
\imagecolorallocate($this->image, 0, 0, 0);
49+
50+
$this->parse();
51+
52+
\imagepng($this->image, $output);
53+
}
54+
55+
protected function estimateSize(string $for, int $pad = 0): array
56+
{
57+
$eol = \substr_count($for, "\n") ?: 1;
58+
$box = \imagettfbbox($this->size, 0, $this->font, $for);
59+
60+
return ['x' => $box[2] + $pad, 'y' => $box[1] + $pad, 'y1' => \intval($box[1] / $eol)];
61+
}
62+
63+
protected function visit(\DOMElement $el)
64+
{
65+
$lineNo = $el->getLineNo() - 1;
66+
$type = $el->getAttribute('data-type');
67+
$color = $this->colorCode($type);
68+
$text = \str_replace(['&nbsp;', '&lt;', '&gt;'], [' ', '<', '>'], $el->textContent);
69+
70+
foreach (\explode("\n", \rtrim($text, "\r\n")) as $line) {
71+
++$lineNo;
72+
73+
$xlen = static::$lengths[$lineNo] ?? 0;
74+
$xpos = 12 + $xlen;
75+
$ypos = $this->imgSize['y1'] * $lineNo;
76+
77+
\imagefttext($this->image, $this->size, 0, $xpos, $ypos, $color, $this->font, $line);
78+
79+
static::$lengths[$lineNo] = $xlen + $this->estimateSize($line)['x'];
80+
}
81+
}
82+
83+
protected function colorCode(string $type): int
84+
{
85+
if (isset(static::$colors[$type])) {
86+
return static::$colors[$type];
87+
}
88+
89+
$palette = [
90+
'comment' => [0, 96, 192],
91+
'default' => [0, 192, 0],
92+
'keyword' => [192, 0, 0],
93+
'string' => [192, 192, 0],
94+
];
95+
96+
return static::$colors[$type] = \imagecolorallocate($this->image, ...$palette[$type]);
97+
}
98+
}

0 commit comments

Comments
 (0)