Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Allow renderer short-circuit if unable to render anything #200

Merged
merged 1 commit into from
Jan 22, 2023
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
2 changes: 1 addition & 1 deletion src/Rasterization/Renderers/EllipseRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class EllipseRenderer extends MultiPassRenderer
/**
* @inheritdoc
*/
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): array
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): ?array
{
$cx = $options['cx'];
$cy = $options['cy'];
Expand Down
2 changes: 1 addition & 1 deletion src/Rasterization/Renderers/LineRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class LineRenderer extends MultiPassRenderer
/**
* @inheritdoc
*/
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): array
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): ?array
{
$x1 = $options['x1'];
$y1 = $options['y1'];
Expand Down
17 changes: 10 additions & 7 deletions src/Rasterization/Renderers/MultiPassRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public function render(SVGRasterizer $rasterizer, array $options, SVGNode $conte
$transform = $rasterizer->getCurrentTransform();

$params = $this->prepareRenderParams($options, $transform, $rasterizer->getFontRegistry());
if (!isset($params)) {
return;
}

$paintOrder = self::getPaintOrder($context);
foreach ($paintOrder as $paint) {
Expand Down Expand Up @@ -75,19 +78,19 @@ private function paintFill(SVGRasterizer $rasterizer, SVGNode $context, $params)
}

/**
* Converts the options array into a new parameters array that the render
* methods can make more sense of.
* Converts the options array into a new parameters array that the render methods can make more sense of.
*
* Specifically, the intention is to allow subclasses to outsource coordinate translation, approximation of curves
* and the like to this method rather than dealing with it in the render methods. This shall encourage single passes
* over the input data (for performance reasons).
*
* Specifically, the intention is to allow subclasses to outsource
* coordinate translation, approximation of curves and the like to this
* method rather than dealing with it in the render methods. This shall
* encourage single passes over the input data (for performance reasons).
* If this method determines that rendering isn't possible (e.g. because the shape is empty), it shall return null.
*
* @param array $options The associative array of raw options.
* @param Transform $transform The coordinate transform to apply, to go from user to output coordinates.
* @param FontRegistry|null $fontRegistry The font registry to use for text rendering.
*
* @return array The new associative array of computed render parameters.
* @return array|null The new associative array of computed render parameters, if there is something to render.
*/
abstract protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry);

Expand Down
2 changes: 1 addition & 1 deletion src/Rasterization/Renderers/PathRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class PathRenderer extends MultiPassRenderer
/**
* @inheritdoc
*/
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): array
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): ?array
{
$approximator = new PathApproximator($transform);
$approximator->approximate($options['commands']);
Expand Down
2 changes: 1 addition & 1 deletion src/Rasterization/Renderers/PolygonRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PolygonRenderer extends MultiPassRenderer
/**
* @inheritdoc
*/
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): array
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): ?array
{
$points = [];
foreach ($options['points'] as $point) {
Expand Down
13 changes: 2 additions & 11 deletions src/Rasterization/Renderers/RectRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ class RectRenderer extends MultiPassRenderer
/**
* @inheritdoc
*/
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): array
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): ?array
{
$w = $options['width'];
$h = $options['height'];
$transform->resize($w, $h);

if ($w <= 0 || $h <= 0) {
return ['empty' => true];
return null;
}

$x1 = $options['x'];
Expand All @@ -54,7 +54,6 @@ protected function prepareRenderParams(array $options, Transform $transform, ?Fo
}

return [
'empty' => false,
'x1' => $x1,
'y1' => $y1,
'x2' => $x1 + $w - 1,
Expand All @@ -69,10 +68,6 @@ protected function prepareRenderParams(array $options, Transform $transform, ?Fo
*/
protected function renderFill($image, $params, int $color): void
{
if ($params['empty']) {
return;
}

if ($params['rx'] != 0 || $params['ry'] != 0) {
$this->renderFillRounded($image, $params, $color);
return;
Expand Down Expand Up @@ -133,10 +128,6 @@ private function renderFillRounded($image, array $params, int $color): void
*/
protected function renderStroke($image, $params, int $color, float $strokeWidth): void
{
if ($params['empty']) {
return;
}

imagesetthickness($image, round($strokeWidth));

if ($params['rx'] != 0 || $params['ry'] != 0) {
Expand Down
6 changes: 5 additions & 1 deletion src/Rasterization/Renderers/TextRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class TextRenderer extends MultiPassRenderer
/**
* @inheritdoc
*/
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): array
protected function prepareRenderParams(array $options, Transform $transform, ?FontRegistry $fontRegistry): ?array
{
// this assumes there is no rotation or skew, but that's fine, we can't deal with that anyway
$size1 = $options['fontSize'];
Expand All @@ -41,6 +41,10 @@ protected function prepareRenderParams(array $options, Transform $transform, ?Fo
}
}

if (!isset($fontPath)) {
return null;
}

// text-anchor
$anchorOffset = 0;
if ($options['anchor'] === 'middle' || $options['anchor'] === 'end') {
Expand Down
37 changes: 37 additions & 0 deletions tests/Rasterization/Renderers/TextRendererTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace SVG\Rasterization\Renderers;

use AssertGD\GDSimilarityConstraint;
use SVG\Rasterization\SVGRasterizer;

/**
* @requires extension gd
* @covers \SVG\Rasterization\Renderers\TextRenderer
*
* @SuppressWarnings(PHPMD)
*/
class TextRendererTest extends \PHPUnit\Framework\TestCase
{
public function testShouldNotFailWithoutRegisteredFont()
{
$obj = new TextRenderer();

$context = $this->getMockForAbstractClass('\SVG\Nodes\SVGNode');

$rasterizer = new SVGRasterizer('40px', '80px', null, 4, 8);
$obj->render($rasterizer, [
'x' => 10,
'y' => 10,
'fontFamily' => 'Roboto',
'fontWeight' => 'normal',
'fontStyle' => 'normal',
'fontSize' => 16,
'anchor' => 'middle',
'text' => 'foo',
], $context);
$img = $rasterizer->finish();

$this->assertThat($img, new GDSimilarityConstraint('./tests/images/empty-4x8.png'));
}
}