Skip to content

Commit

Permalink
Add a RendererInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
casperbakker committed Sep 22, 2024
1 parent 5fd1162 commit 8fdf289
Show file tree
Hide file tree
Showing 52 changed files with 308 additions and 291 deletions.
4 changes: 2 additions & 2 deletions generate-verified-files.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
file_put_contents('tests/verified-files/081231723897-ean13-fractional-width.svg', $svgRenderer->render($barcode, $barcode->getWidth() * 0.25, 25.75));

$svgRendererRed = new Picqer\Barcode\Renderers\SvgRenderer();
$svgRendererRed->setBackgroundColor('red');
$svgRendererRed->setBackgroundColor([255, 0, 0]);
file_put_contents('tests/verified-files/081231723897-ean13-red-background.svg', $svgRendererRed->render($barcode, $barcode->getWidth() * 2));

$barcode = $typeEncoderCode128->getBarcode('081231723897');
file_put_contents('tests/verified-files/081231723897-code128.html', $htmlRenderer->render($barcode, $barcode->getWidth() * 2));
$htmlRendererRed = new Picqer\Barcode\Renderers\HtmlRenderer();
$htmlRendererRed->setBackgroundColor('red');
$htmlRendererRed->setBackgroundColor([255, 0, 0]);
file_put_contents('tests/verified-files/081231723897-code128-red-background.html', $htmlRendererRed->render($barcode, $barcode->getWidth() * 2));

$barcode = $typeEncoderIMB->getBarcode('12345678903');
Expand Down
19 changes: 9 additions & 10 deletions src/Renderers/DynamicHtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
use Picqer\Barcode\Barcode;
use Picqer\Barcode\BarcodeBar;

class DynamicHtmlRenderer
class DynamicHtmlRenderer implements RendererInterface
{
protected const WIDTH_PRECISION = 6;

protected string $foregroundColor = 'black';
protected ?string $backgroundColor = null;
protected array $foregroundColor = [0, 0, 0];
protected ?array $backgroundColor = null;

public function render(Barcode $barcode): string
// Width and height are ignored in this renderer
public function render(Barcode $barcode, float $width = 200, float $height = 30): string
{
$html = '<div style="font-size:0;position:relative;width:100%;height:100%' . ($this->backgroundColor ? ';background-color:' . $this->backgroundColor : '') . '">' . PHP_EOL;
$html = '<div style="font-size:0;position:relative;width:100%;height:100%' . ($this->backgroundColor ? ';background-color:rgb(' . implode(',', $this->backgroundColor) . ')' : '') . '">' . PHP_EOL;

$positionHorizontal = 0;
/** @var BarcodeBar $bar */
Expand All @@ -26,7 +27,7 @@ public function render(Barcode $barcode): string
$positionVertical = round(($bar->getPositionVertical() / $barcode->getHeight() * 100), 3);

// draw a vertical bar
$html .= '<div style="background-color:' . $this->foregroundColor . ';width:' . round($barWidth, self::WIDTH_PRECISION) . '%;height:' . $barHeight . '%;position:absolute;left:' . round($positionHorizontal, self::WIDTH_PRECISION) . '%;top:' . $positionVertical . (($positionVertical > 0) ? '%' : '') . '">&nbsp;</div>' . PHP_EOL;
$html .= '<div style="background-color:rgb(' . implode(',', $this->foregroundColor) . ');width:' . round($barWidth, self::WIDTH_PRECISION) . '%;height:' . $barHeight . '%;position:absolute;left:' . round($positionHorizontal, self::WIDTH_PRECISION) . '%;top:' . $positionVertical . (($positionVertical > 0) ? '%' : '') . '">&nbsp;</div>' . PHP_EOL;
}

$positionHorizontal += $barWidth;
Expand All @@ -37,15 +38,13 @@ public function render(Barcode $barcode): string
return $html;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setForegroundColor(string $color): self
public function setForegroundColor(array $color): self
{
$this->foregroundColor = $color;
return $this;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setBackgroundColor(?string $color): self
public function setBackgroundColor(?array $color): self
{
$this->backgroundColor = $color;
return $this;
Expand Down
16 changes: 7 additions & 9 deletions src/Renderers/HtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
use Picqer\Barcode\Barcode;
use Picqer\Barcode\BarcodeBar;

class HtmlRenderer
class HtmlRenderer implements RendererInterface
{
protected string $foregroundColor = 'black';
protected ?string $backgroundColor = null;
protected array $foregroundColor = [0, 0, 0];
protected ?array $backgroundColor = null;

public function render(Barcode $barcode, float $width = 200, float $height = 30): string
{
$widthFactor = $width / $barcode->getWidth();

$html = '<div style="font-size:0;position:relative;width:' . $width . 'px;height:' . ($height) . 'px;' . ($this->backgroundColor ? 'background-color:' . $this->backgroundColor . ';' : '') . '">' . PHP_EOL;
$html = '<div style="font-size:0;position:relative;width:' . $width . 'px;height:' . ($height) . 'px;' . ($this->backgroundColor ? 'background-color:rgb(' . implode(',', $this->backgroundColor) . ');' : '') . '">' . PHP_EOL;

$positionHorizontal = 0;
/** @var BarcodeBar $bar */
Expand All @@ -26,7 +26,7 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
$positionVertical = round(($bar->getPositionVertical() * $height / $barcode->getHeight()), 3);

// draw a vertical bar
$html .= '<div style="background-color:' . $this->foregroundColor . ';width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . (($positionVertical > 0) ? 'px' : '') . '">&nbsp;</div>' . PHP_EOL;
$html .= '<div style="background-color:rgb(' . implode(',', $this->foregroundColor) . ');width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . (($positionVertical > 0) ? 'px' : '') . '">&nbsp;</div>' . PHP_EOL;
}

$positionHorizontal += $barWidth;
Expand All @@ -37,15 +37,13 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
return $html;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setForegroundColor(string $color): self
public function setForegroundColor(array $color): self
{
$this->foregroundColor = $color;
return $this;
}

// Use HTML color definitions, like 'red' or '#ff0000'
public function setBackgroundColor(?string $color): self
public function setBackgroundColor(?array $color): self
{
$this->backgroundColor = $color;
return $this;
Expand Down
18 changes: 12 additions & 6 deletions src/Renderers/PngRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Picqer\Barcode\BarcodeBar;
use Picqer\Barcode\Exceptions\BarcodeException;

class PngRenderer
class PngRenderer implements RendererInterface
{
protected array $foregroundColor = [0, 0, 0];
protected ?array $backgroundColor = null;
Expand Down Expand Up @@ -49,9 +49,15 @@ public function useGd(): self
return $this;
}

public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30): string
// Floats in width and height will be rounded to integers
// For best (and valid) result, use a width as a factor of the width of the Barcode object
// Example: $width = $barcode->getWidth() * 3
public function render(Barcode $barcode, float $width = 200, float $height = 30): string
{
$width = (int)round($barcode->getWidth() * $widthFactor);
$width = round($width);
$height = round($height);

$widthFactor = $width / $barcode->getWidth();

if ($this->useImagick) {
$image = $this->createImagickImageObject($width, $height);

Check failure on line 63 in src/Renderers/PngRenderer.php

View workflow job for this annotation

GitHub Actions / build

Parameter #1 $width of method Picqer\Barcode\Renderers\PngRenderer::createImagickImageObject() expects int, float given.

Check failure on line 63 in src/Renderers/PngRenderer.php

View workflow job for this annotation

GitHub Actions / build

Parameter #2 $height of method Picqer\Barcode\Renderers\PngRenderer::createImagickImageObject() expects int, float given.
Expand All @@ -66,17 +72,17 @@ public function render(Barcode $barcode, int $widthFactor = 2, int $height = 30)
$positionHorizontal = 0;
/** @var BarcodeBar $bar */
foreach ($barcode->getBars() as $bar) {
$barWidth = (int)round(($bar->getWidth() * $widthFactor));
$barWidth = $bar->getWidth() * $widthFactor;

if ($bar->isBar() && $barWidth > 0) {
$y = (int)round(($bar->getPositionVertical() * $height / $barcode->getHeight()));
$barHeight = (int)round(($bar->getHeight() * $height / $barcode->getHeight()));

// draw a vertical bar
if ($this->useImagick) {
$imagickBarsShape->rectangle($positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight));
$imagickBarsShape->rectangle(round($positionHorizontal), $y, round($positionHorizontal + $barWidth - 1), ($y + $barHeight));
} else {
\imagefilledrectangle($image, $positionHorizontal, $y, ($positionHorizontal + $barWidth - 1), ($y + $barHeight), $gdForegroundColor);
\imagefilledrectangle($image, round($positionHorizontal), $y, round($positionHorizontal + $barWidth - 1), ($y + $barHeight), $gdForegroundColor);

Check failure on line 85 in src/Renderers/PngRenderer.php

View workflow job for this annotation

GitHub Actions / build

Parameter #2 $x1 of function imagefilledrectangle expects int, float given.

Check failure on line 85 in src/Renderers/PngRenderer.php

View workflow job for this annotation

GitHub Actions / build

Parameter #4 $x2 of function imagefilledrectangle expects int, float given.
}
}
$positionHorizontal += $barWidth;
Expand Down
14 changes: 14 additions & 0 deletions src/Renderers/RendererInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Picqer\Barcode\Renderers;

use Picqer\Barcode\Barcode;

interface RendererInterface
{
public function render(Barcode $barcode, float $width = 200, float $height = 30): string;

public function setForegroundColor(array $color): self;

public function setBackgroundColor(?array $color): self;
}
14 changes: 7 additions & 7 deletions src/Renderers/SvgRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
use Picqer\Barcode\BarcodeBar;
use Picqer\Barcode\Exceptions\InvalidOptionException;

class SvgRenderer
class SvgRenderer implements RendererInterface
{
protected string $foregroundColor = 'black';
protected ?string $backgroundColor = null;
protected array $foregroundColor = [0, 0, 0];
protected ?array $backgroundColor = null;
protected string $svgType = self::TYPE_SVG_STANDALONE;

public const TYPE_SVG_STANDALONE = 'standalone';
Expand All @@ -29,10 +29,10 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)

// Add background rectangle if backgroundColor is set
if ($this->backgroundColor !== null) {
$svg .= "\t" . '<rect id="background" width="100%" height="100%" fill="' . $this->backgroundColor . '"/>' . PHP_EOL;
$svg .= "\t" . '<rect id="background" width="100%" height="100%" fill="rgb(' . implode(',', $this->backgroundColor) . ')"/>' . PHP_EOL;
}

$svg .= "\t" . '<g id="bars" fill="' . $this->foregroundColor . '" stroke="none">' . PHP_EOL;
$svg .= "\t" . '<g id="bars" fill="rgb(' . implode(',', $this->foregroundColor) . ')" stroke="none">' . PHP_EOL;

// print bars
$positionHorizontal = 0;
Expand All @@ -56,13 +56,13 @@ public function render(Barcode $barcode, float $width = 200, float $height = 30)
return $svg;
}

public function setForegroundColor(string $color): self
public function setForegroundColor(array $color): self
{
$this->foregroundColor = $color;
return $this;
}

public function setBackgroundColor(?string $color): self
public function setBackgroundColor(?array $color): self
{
$this->backgroundColor = $color;
return $this;
Expand Down
2 changes: 1 addition & 1 deletion tests/verified-files/0049000004632-ean13.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 29 additions & 29 deletions tests/verified-files/081231723897-code128-red-background.html
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<div style="font-size:0;position:relative;width:202px;height:30px;background-color:red;">
<div style="background-color:black;width:4px;height:30px;position:absolute;left:0px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:6px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:12px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:22px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:30px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:38px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:44px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:48px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:56px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:66px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:72px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:82px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:88px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:94px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:106px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:110px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:118px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:128px;top:0">&nbsp;</div>
<div style="background-color:black;width:8px;height:30px;position:absolute;left:132px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:142px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:146px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:154px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:162px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:166px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:176px;top:0">&nbsp;</div>
<div style="background-color:black;width:6px;height:30px;position:absolute;left:186px;top:0">&nbsp;</div>
<div style="background-color:black;width:2px;height:30px;position:absolute;left:194px;top:0">&nbsp;</div>
<div style="background-color:black;width:4px;height:30px;position:absolute;left:198px;top:0">&nbsp;</div>
<div style="font-size:0;position:relative;width:202px;height:30px;background-color:rgb(255,0,0);">
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:0px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:6px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:6px;height:30px;position:absolute;left:12px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:22px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:30px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:38px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:44px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:48px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:6px;height:30px;position:absolute;left:56px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:66px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:72px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:82px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:88px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:94px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:106px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:110px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:118px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:128px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:8px;height:30px;position:absolute;left:132px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:142px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:146px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:6px;height:30px;position:absolute;left:154px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:162px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:166px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:176px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:6px;height:30px;position:absolute;left:186px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:2px;height:30px;position:absolute;left:194px;top:0">&nbsp;</div>
<div style="background-color:rgb(0,0,0);width:4px;height:30px;position:absolute;left:198px;top:0">&nbsp;</div>
</div>
Loading

0 comments on commit 8fdf289

Please sign in to comment.