first commit -> move some files from one-api

This commit is contained in:
2026-05-06 13:37:10 +07:00
parent a3144382c5
commit 55c6ed9779
7940 changed files with 628870 additions and 0 deletions

View File

@@ -0,0 +1,160 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Color;
use BaconQrCode\Exception;
/**
* CMYK color.
*/
class Cmyk implements ColorInterface
{
/**
* Cyan value.
*
* @var integer
*/
protected $cyan;
/**
* Magenta value.
*
* @var integer
*/
protected $magenta;
/**
* Yellow value.
*
* @var integer
*/
protected $yellow;
/**
* Black value.
*
* @var integer
*/
protected $black;
/**
* Creates a new CMYK color.
*
* @param integer $cyan
* @param integer $magenta
* @param integer $yellow
* @param integer $black
*/
public function __construct($cyan, $magenta, $yellow, $black)
{
if ($cyan < 0 || $cyan > 100) {
throw new Exception\InvalidArgumentException('Cyan must be between 0 and 100');
}
if ($magenta < 0 || $magenta > 100) {
throw new Exception\InvalidArgumentException('Magenta must be between 0 and 100');
}
if ($yellow < 0 || $yellow > 100) {
throw new Exception\InvalidArgumentException('Yellow must be between 0 and 100');
}
if ($black < 0 || $black > 100) {
throw new Exception\InvalidArgumentException('Black must be between 0 and 100');
}
$this->cyan = (int) $cyan;
$this->magenta = (int) $magenta;
$this->yellow = (int) $yellow;
$this->black = (int) $black;
}
/**
* Returns the cyan value.
*
* @return integer
*/
public function getCyan()
{
return $this->cyan;
}
/**
* Returns the magenta value.
*
* @return integer
*/
public function getMagenta()
{
return $this->magenta;
}
/**
* Returns the yellow value.
*
* @return integer
*/
public function getYellow()
{
return $this->yellow;
}
/**
* Returns the black value.
*
* @return integer
*/
public function getBlack()
{
return $this->black;
}
/**
* toRgb(): defined by ColorInterface.
*
* @see ColorInterface::toRgb()
* @return Rgb
*/
public function toRgb()
{
$k = $this->black / 100;
$c = (-$k * $this->cyan + $k * 100 + $this->cyan) / 100;
$m = (-$k * $this->magenta + $k * 100 + $this->magenta) / 100;
$y = (-$k * $this->yellow + $k * 100 + $this->yellow) / 100;
return new Rgb(
-$c * 255 + 255,
-$m * 255 + 255,
-$y * 255 + 255
);
}
/**
* toCmyk(): defined by ColorInterface.
*
* @see ColorInterface::toCmyk()
* @return Cmyk
*/
public function toCmyk()
{
return $this;
}
/**
* toGray(): defined by ColorInterface.
*
* @see ColorInterface::toGray()
* @return Gray
*/
public function toGray()
{
return $this->toRgb()->toGray();
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Color;
/**
* Color interface.
*/
interface ColorInterface
{
/**
* Converts the color to RGB.
*
* @return Rgb
*/
public function toRgb();
/**
* Converts the color to CMYK.
*
* @return Cmyk
*/
public function toCmyk();
/**
* Converts the color to gray.
*
* @return Gray
*/
public function toGray();
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Color;
use BaconQrCode\Exception;
/**
* Gray color.
*/
class Gray implements ColorInterface
{
/**
* Gray value.
*
* @var integer
*/
protected $gray;
/**
* Creates a new gray color.
*
* A low gray value means black, while a high value means white.
*
* @param integer $gray
*/
public function __construct($gray)
{
if ($gray < 0 || $gray > 100) {
throw new Exception\InvalidArgumentException('Gray must be between 0 and 100');
}
$this->gray = (int) $gray;
}
/**
* Returns the gray value.
*
* @return integer
*/
public function getGray()
{
return $this->gray;
}
/**
* toRgb(): defined by ColorInterface.
*
* @see ColorInterface::toRgb()
* @return Rgb
*/
public function toRgb()
{
return new Rgb($this->gray * 2.55, $this->gray * 2.55, $this->gray * 2.55);
}
/**
* toCmyk(): defined by ColorInterface.
*
* @see ColorInterface::toCmyk()
* @return Cmyk
*/
public function toCmyk()
{
return new Cmyk(0, 0, 0, 100 - $this->gray);
}
/**
* toGray(): defined by ColorInterface.
*
* @see ColorInterface::toGray()
* @return Gray
*/
public function toGray()
{
return $this;
}
}

View File

@@ -0,0 +1,148 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Color;
use BaconQrCode\Exception;
/**
* RGB color.
*/
class Rgb implements ColorInterface
{
/**
* Red value.
*
* @var integer
*/
protected $red;
/**
* Green value.
*
* @var integer
*/
protected $green;
/**
* Blue value.
*
* @var integer
*/
protected $blue;
/**
* Creates a new RGB color.
*
* @param integer $red
* @param integer $green
* @param integer $blue
*/
public function __construct($red, $green, $blue)
{
if ($red < 0 || $red > 255) {
throw new Exception\InvalidArgumentException('Red must be between 0 and 255');
}
if ($green < 0 || $green > 255) {
throw new Exception\InvalidArgumentException('Green must be between 0 and 255');
}
if ($blue < 0 || $blue > 255) {
throw new Exception\InvalidArgumentException('Blue must be between 0 and 255');
}
$this->red = (int) $red;
$this->green = (int) $green;
$this->blue = (int) $blue;
}
/**
* Returns the red value.
*
* @return integer
*/
public function getRed()
{
return $this->red;
}
/**
* Returns the green value.
*
* @return integer
*/
public function getGreen()
{
return $this->green;
}
/**
* Returns the blue value.
*
* @return integer
*/
public function getBlue()
{
return $this->blue;
}
/**
* Returns a hexadecimal string representation of the RGB value.
*
* @return string
*/
public function __toString()
{
return sprintf('%02x%02x%02x', $this->red, $this->green, $this->blue);
}
/**
* toRgb(): defined by ColorInterface.
*
* @see ColorInterface::toRgb()
* @return Rgb
*/
public function toRgb()
{
return $this;
}
/**
* toCmyk(): defined by ColorInterface.
*
* @see ColorInterface::toCmyk()
* @return Cmyk
*/
public function toCmyk()
{
$c = 1 - ($this->red / 255);
$m = 1 - ($this->green / 255);
$y = 1 - ($this->blue / 255);
$k = min($c, $m, $y);
return new Cmyk(
100 * ($c - $k) / (1 - $k),
100 * ($m - $k) / (1 - $k),
100 * ($y - $k) / (1 - $k),
100 * $k
);
}
/**
* toGray(): defined by ColorInterface.
*
* @see ColorInterface::toGray()
* @return Gray
*/
public function toGray()
{
return new Gray(($this->red * 0.21 + $this->green * 0.71 + $this->blue * 0.07) / 2.55);
}
}

View File

@@ -0,0 +1,338 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image;
use BaconQrCode\Encoder\QrCode;
use BaconQrCode\Renderer\Color;
use BaconQrCode\Renderer\Image\Decorator\DecoratorInterface;
use BaconQrCode\Exception;
/**
* Image renderer, supporting multiple backends.
*/
abstract class AbstractRenderer implements RendererInterface
{
/**
* Margin around the QR code, also known as quiet zone.
*
* @var integer
*/
protected $margin = 4;
/**
* Requested width of the rendered image.
*
* @var integer
*/
protected $width = 0;
/**
* Requested height of the rendered image.
*
* @var integer
*/
protected $height = 0;
/**
* Whether dimensions should be rounded down.
*
* @var boolean
*/
protected $roundDimensions = true;
/**
* Final width of the image.
*
* @var integer
*/
protected $finalWidth;
/**
* Final height of the image.
*
* @var integer
*/
protected $finalHeight;
/**
* Size of each individual block.
*
* @var integer
*/
protected $blockSize;
/**
* Background color.
*
* @var Color\ColorInterface
*/
protected $backgroundColor;
/**
* Whether dimensions should be rounded down
*
* @var boolean
*/
protected $floorToClosestDimension;
/**
* Foreground color.
*
* @var Color\ColorInterface
*/
protected $foregroundColor;
/**
* Decorators used on QR codes.
*
* @var array
*/
protected $decorators = array();
/**
* Sets the margin around the QR code.
*
* @param integer $margin
* @return AbstractRenderer
* @throws Exception\InvalidArgumentException
*/
public function setMargin($margin)
{
if ($margin < 0) {
throw new Exception\InvalidArgumentException('Margin must be equal to greater than 0');
}
$this->margin = (int) $margin;
return $this;
}
/**
* Gets the margin around the QR code.
*
* @return integer
*/
public function getMargin()
{
return $this->margin;
}
/**
* Sets the height around the renderd image.
*
* If the width is smaller than the matrix width plus padding, the renderer
* will automatically use that as the width instead of the specified one.
*
* @param integer $width
* @return AbstractRenderer
*/
public function setWidth($width)
{
$this->width = (int) $width;
return $this;
}
/**
* Gets the width of the rendered image.
*
* @return integer
*/
public function getWidth()
{
return $this->width;
}
/**
* Sets the height around the renderd image.
*
* If the height is smaller than the matrix height plus padding, the
* renderer will automatically use that as the height instead of the
* specified one.
*
* @param integer $height
* @return AbstractRenderer
*/
public function setHeight($height)
{
$this->height = (int) $height;
return $this;
}
/**
* Gets the height around the rendered image.
*
* @return integer
*/
public function getHeight()
{
return $this->height;
}
/**
* Sets whether dimensions should be rounded down.
*
* @param boolean $flag
* @return AbstractRenderer
*/
public function setRoundDimensions($flag)
{
$this->floorToClosestDimension = $flag;
return $this;
}
/**
* Gets whether dimensions should be rounded down.
*
* @return boolean
*/
public function shouldRoundDimensions()
{
return $this->floorToClosestDimension;
}
/**
* Sets background color.
*
* @param Color\ColorInterface $color
* @return AbstractRenderer
*/
public function setBackgroundColor(Color\ColorInterface $color)
{
$this->backgroundColor = $color;
return $this;
}
/**
* Gets background color.
*
* @return Color\ColorInterface
*/
public function getBackgroundColor()
{
if ($this->backgroundColor === null) {
$this->backgroundColor = new Color\Gray(100);
}
return $this->backgroundColor;
}
/**
* Sets foreground color.
*
* @param Color\ColorInterface $color
* @return AbstractRenderer
*/
public function setForegroundColor(Color\ColorInterface $color)
{
$this->foregroundColor = $color;
return $this;
}
/**
* Gets foreground color.
*
* @return Color\ColorInterface
*/
public function getForegroundColor()
{
if ($this->foregroundColor === null) {
$this->foregroundColor = new Color\Gray(0);
}
return $this->foregroundColor;
}
/**
* Adds a decorator to the renderer.
*
* @param DecoratorInterface $decorator
* @return AbstractRenderer
*/
public function addDecorator(DecoratorInterface $decorator)
{
$this->decorators[] = $decorator;
return $this;
}
/**
* render(): defined by RendererInterface.
*
* @see RendererInterface::render()
* @param QrCode $qrCode
* @return string
*/
public function render(QrCode $qrCode)
{
$input = $qrCode->getMatrix();
$inputWidth = $input->getWidth();
$inputHeight = $input->getHeight();
$qrWidth = $inputWidth + ($this->getMargin() << 1);
$qrHeight = $inputHeight + ($this->getMargin() << 1);
$outputWidth = max($this->getWidth(), $qrWidth);
$outputHeight = max($this->getHeight(), $qrHeight);
$multiple = (int) min($outputWidth / $qrWidth, $outputHeight / $qrHeight);
if ($this->shouldRoundDimensions()) {
$outputWidth -= $outputWidth % $multiple;
$outputHeight -= $outputHeight % $multiple;
}
// Padding includes both the quiet zone and the extra white pixels to
// accommodate the requested dimensions. For example, if input is 25x25
// the QR will be 33x33 including the quiet zone. If the requested size
// is 200x160, the multiple will be 4, for a QR of 132x132. These will
// handle all the padding from 100x100 (the actual QR) up to 200x160.
$leftPadding = (int) (($outputWidth - ($inputWidth * $multiple)) / 2);
$topPadding = (int) (($outputHeight - ($inputHeight * $multiple)) / 2);
// Store calculated parameters
$this->finalWidth = $outputWidth;
$this->finalHeight = $outputHeight;
$this->blockSize = $multiple;
$this->init();
$this->addColor('background', $this->getBackgroundColor());
$this->addColor('foreground', $this->getForegroundColor());
$this->drawBackground('background');
foreach ($this->decorators as $decorator) {
$decorator->preProcess(
$qrCode,
$this,
$outputWidth,
$outputHeight,
$leftPadding,
$topPadding,
$multiple
);
}
for ($inputY = 0, $outputY = $topPadding; $inputY < $inputHeight; $inputY++, $outputY += $multiple) {
for ($inputX = 0, $outputX = $leftPadding; $inputX < $inputWidth; $inputX++, $outputX += $multiple) {
if ($input->get($inputX, $inputY) === 1) {
$this->drawBlock($outputX, $outputY, 'foreground');
}
}
}
foreach ($this->decorators as $decorator) {
$decorator->postProcess(
$qrCode,
$this,
$outputWidth,
$outputHeight,
$leftPadding,
$topPadding,
$multiple
);
}
return $this->getByteStream();
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image\Decorator;
use BaconQrCode\Encoder\QrCode;
use BaconQrCode\Renderer\Image\RendererInterface;
/**
* Decorator interface.
*/
interface DecoratorInterface
{
/**
* Pre-process a QR code.
*
* @param QrCode $qrCode
* @param RendererInterface $renderer
* @param integer $outputWidth
* @param integer $outputHeight
* @param integer $leftPadding
* @param integer $topPadding
* @param integer $multiple
* @return void
*/
public function preProcess(
QrCode $qrCode,
RendererInterface $renderer,
$outputWidth,
$outputHeight,
$leftPadding,
$topPadding,
$multiple
);
/**
* Post-process a QR code.
*
* @param QrCode $qrCode
* @param RendererInterface $renderer
* @param integer $outputWidth
* @param integer $outputHeight
* @param integer $leftPadding
* @param integer $topPadding
* @param integer $multiple
* @return void
*/
public function postProcess(
QrCode $qrCode,
RendererInterface $renderer,
$outputWidth,
$outputHeight,
$leftPadding,
$topPadding,
$multiple
);
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image\Decorator;
use BaconQrCode\Encoder\QrCode;
use BaconQrCode\Renderer\Image\RendererInterface;
use BaconQrCode\Renderer\Color;
/**
* Finder pattern decorator.
*/
class FinderPattern implements DecoratorInterface
{
/**
* @var Color\ColorInterface
*/
protected $innerColor;
/**
* @varColor\ColorInterface
*/
protected $outerColor;
/**
* Outer position detection pattern.
*
* @var array
*/
protected static $outerPositionDetectionPattern = array(
array(1, 1, 1, 1, 1, 1, 1),
array(1, 0, 0, 0, 0, 0, 1),
array(1, 0, 0, 0, 0, 0, 1),
array(1, 0, 0, 0, 0, 0, 1),
array(1, 0, 0, 0, 0, 0, 1),
array(1, 0, 0, 0, 0, 0, 1),
array(1, 1, 1, 1, 1, 1, 1),
);
/**
* Inner position detection pattern.
*
* @var array
*/
protected static $innerPositionDetectionPattern = array(
array(0, 0, 0, 0, 0, 0, 0),
array(0, 0, 0, 0, 0, 0, 0),
array(0, 0, 1, 1, 1, 0, 0),
array(0, 0, 1, 1, 1, 0, 0),
array(0, 0, 1, 1, 1, 0, 0),
array(0, 0, 0, 0, 0, 0, 0),
array(0, 0, 0, 0, 0, 0, 0),
);
/**
* Sets outer color.
*
* @param Color\ColorInterface $color
* @return FinderPattern
*/
public function setOuterColor(Color\ColorInterface $color)
{
$this->outerColor = $color;
return $this;
}
/**
* Gets outer color.
*
* @return Color\ColorInterface
*/
public function getOuterColor()
{
if ($this->outerColor === null) {
$this->outerColor = new Color\Gray(100);
}
return $this->outerColor;
}
/**
* Sets inner color.
*
* @param Color\ColorInterface $color
* @return FinderPattern
*/
public function setInnerColor(Color\ColorInterface $color)
{
$this->innerColor = $color;
return $this;
}
/**
* Gets inner color.
*
* @return Color\ColorInterface
*/
public function getInnerColor()
{
if ($this->innerColor === null) {
$this->innerColor = new Color\Gray(0);
}
return $this->innerColor;
}
/**
* preProcess(): defined by DecoratorInterface.
*
* @see DecoratorInterface::preProcess()
* @param QrCode $qrCode
* @param RendererInterface $renderer
* @param integer $outputWidth
* @param integer $outputHeight
* @param integer $leftPadding
* @param integer $topPadding
* @param integer $multiple
* @return void
*/
public function preProcess(
QrCode $qrCode,
RendererInterface $renderer,
$outputWidth,
$outputHeight,
$leftPadding,
$topPadding,
$multiple
) {
$matrix = $qrCode->getMatrix();
$positions = array(
array(0, 0),
array($matrix->getWidth() - 7, 0),
array(0, $matrix->getHeight() - 7),
);
foreach (self::$outerPositionDetectionPattern as $y => $row) {
foreach ($row as $x => $isSet) {
foreach ($positions as $position) {
$matrix->set($x + $position[0], $y + $position[1], 0);
}
}
}
}
/**
* postProcess(): defined by DecoratorInterface.
*
* @see DecoratorInterface::postProcess()
*
* @param QrCode $qrCode
* @param RendererInterface $renderer
* @param integer $outputWidth
* @param integer $outputHeight
* @param integer $leftPadding
* @param integer $topPadding
* @param integer $multiple
* @return void
*/
public function postProcess(
QrCode $qrCode,
RendererInterface $renderer,
$outputWidth,
$outputHeight,
$leftPadding,
$topPadding,
$multiple
) {
$matrix = $qrCode->getMatrix();
$positions = array(
array(0, 0),
array($matrix->getWidth() - 7, 0),
array(0, $matrix->getHeight() - 7),
);
$renderer->addColor('finder-outer', $this->getOuterColor());
$renderer->addColor('finder-inner', $this->getInnerColor());
foreach (self::$outerPositionDetectionPattern as $y => $row) {
foreach ($row as $x => $isOuterSet) {
$isInnerSet = self::$innerPositionDetectionPattern[$y][$x];
if ($isOuterSet) {
foreach ($positions as $position) {
$renderer->drawBlock(
$leftPadding + $x * $multiple + $position[0] * $multiple,
$topPadding + $y * $multiple + $position[1] * $multiple,
'finder-outer'
);
}
}
if ($isInnerSet) {
foreach ($positions as $position) {
$renderer->drawBlock(
$leftPadding + $x * $multiple + $position[0] * $multiple,
$topPadding + $y * $multiple + $position[1] * $multiple,
'finder-inner'
);
}
}
}
}
}
}

View File

@@ -0,0 +1,152 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image;
use BaconQrCode\Renderer\Color\ColorInterface;
use BaconQrCode\Renderer\Color\Rgb;
use BaconQrCode\Renderer\Color\Cmyk;
use BaconQrCode\Renderer\Color\Gray;
/**
* EPS backend.
*/
class Eps extends AbstractRenderer
{
/**
* EPS string.
*
* @var string
*/
protected $eps;
/**
* Colors used for drawing.
*
* @var array
*/
protected $colors = array();
/**
* Current color.
*
* @var string
*/
protected $currentColor;
/**
* init(): defined by RendererInterface.
*
* @see ImageRendererInterface::init()
* @return void
*/
public function init()
{
$this->eps = "%!PS-Adobe-3.0 EPSF-3.0\n"
. "%%BoundingBox: 0 0 " . $this->finalWidth . " " . $this->finalHeight . "\n"
. "/F { rectfill } def\n";
}
/**
* addColor(): defined by RendererInterface.
*
* @see ImageRendererInterface::addColor()
* @param string $id
* @param ColorInterface $color
* @return void
*/
public function addColor($id, ColorInterface $color)
{
if (
!$color instanceof Rgb
&& !$color instanceof Cmyk
&& !$color instanceof Gray
) {
$color = $color->toCmyk();
}
$this->colors[$id] = $color;
}
/**
* drawBackground(): defined by RendererInterface.
*
* @see ImageRendererInterface::drawBackground()
* @param string $colorId
* @return void
*/
public function drawBackground($colorId)
{
$this->setColor($colorId);
$this->eps .= "0 0 " . $this->finalWidth . " " . $this->finalHeight . " F\n";
}
/**
* drawBlock(): defined by RendererInterface.
*
* @see ImageRendererInterface::drawBlock()
* @param integer $x
* @param integer $y
* @param string $colorId
* @return void
*/
public function drawBlock($x, $y, $colorId)
{
$this->setColor($colorId);
$this->eps .= $x . " " . ($this->finalHeight - $y - $this->blockSize) . " " . $this->blockSize . " " . $this->blockSize . " F\n";
}
/**
* getByteStream(): defined by RendererInterface.
*
* @see ImageRendererInterface::getByteStream()
* @return string
*/
public function getByteStream()
{
return $this->eps;
}
/**
* Sets color to use.
*
* @param string $colorId
* @return void
*/
protected function setColor($colorId)
{
if ($colorId !== $this->currentColor) {
$color = $this->colors[$colorId];
if ($color instanceof Rgb) {
$this->eps .= sprintf(
"%F %F %F setrgbcolor\n",
$color->getRed() / 100,
$color->getGreen() / 100,
$color->getBlue() / 100
);
} elseif ($color instanceof Cmyk) {
$this->eps .= sprintf(
"%F %F %F %F setcmykcolor\n",
$color->getCyan() / 100,
$color->getMagenta() / 100,
$color->getYellow() / 100,
$color->getBlack() / 100
);
} elseif ($color instanceof Gray) {
$this->eps .= sprintf(
"%F setgray\n",
$color->getGray() / 100
);
}
$this->currentColor = $colorId;
}
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image;
use BaconQrCode\Exception;
use BaconQrCode\Renderer\Color\ColorInterface;
/**
* PNG backend.
*/
class Png extends AbstractRenderer
{
/**
* Image resource used when drawing.
*
* @var resource
*/
protected $image;
/**
* Colors used for drawing.
*
* @var array
*/
protected $colors = array();
/**
* init(): defined by RendererInterface.
*
* @see ImageRendererInterface::init()
* @return void
*/
public function init()
{
$this->image = imagecreatetruecolor($this->finalWidth, $this->finalHeight);
}
/**
* addColor(): defined by RendererInterface.
*
* @see ImageRendererInterface::addColor()
* @param string $id
* @param ColorInterface $color
* @return void
* @throws Exception\RuntimeException
*/
public function addColor($id, ColorInterface $color)
{
if ($this->image === null) {
throw new Exception\RuntimeException('Colors can only be added after init');
}
$color = $color->toRgb();
$this->colors[$id] = imagecolorallocate(
$this->image,
$color->getRed(),
$color->getGreen(),
$color->getBlue()
);
}
/**
* drawBackground(): defined by RendererInterface.
*
* @see ImageRendererInterface::drawBackground()
* @param string $colorId
* @return void
*/
public function drawBackground($colorId)
{
imagefill($this->image, 0, 0, $this->colors[$colorId]);
}
/**
* drawBlock(): defined by RendererInterface.
*
* @see ImageRendererInterface::drawBlock()
* @param integer $x
* @param integer $y
* @param string $colorId
* @return void
*/
public function drawBlock($x, $y, $colorId)
{
imagefilledrectangle(
$this->image,
$x,
$y,
$x + $this->blockSize - 1,
$y + $this->blockSize - 1,
$this->colors[$colorId]
);
}
/**
* getByteStream(): defined by RendererInterface.
*
* @see ImageRendererInterface::getByteStream()
* @return string
*/
public function getByteStream()
{
ob_start();
imagepng($this->image);
return ob_get_clean();
}
}

View File

@@ -0,0 +1,61 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image;
use BaconQrCode\Renderer\Color\ColorInterface;
use BaconQrCode\Renderer\RendererInterface as GeneralRendererInterface;
/**
* Renderer interface.
*/
interface RendererInterface extends GeneralRendererInterface
{
/**
* Initiates the drawing area.
*
* @return void
*/
public function init();
/**
* Adds a color to the drawing area.
*
* @param string $id
* @param ColorInterface $color
* @return void
*/
public function addColor($id, ColorInterface $color);
/**
* Draws the background.
*
* @param string $colorId
* @return void
*/
public function drawBackground($colorId);
/**
* Draws a block at a specified position.
*
* @param integer $x
* @param integer $y
* @param string $colorId
* @return void
*/
public function drawBlock($x, $y, $colorId);
/**
* Returns the byte stream representing the QR code.
*
* @return string
*/
public function getByteStream();
}

View File

@@ -0,0 +1,146 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Image;
use BaconQrCode\Exception;
use BaconQrCode\Renderer\Color\ColorInterface;
use SimpleXMLElement;
/**
* SVG backend.
*/
class Svg extends AbstractRenderer
{
/**
* SVG resource.
*
* @var SimpleXMLElement
*/
protected $svg;
/**
* Colors used for drawing.
*
* @var array
*/
protected $colors = array();
/**
* Prototype IDs.
*
* @var array
*/
protected $prototypeIds = array();
/**
* init(): defined by RendererInterface.
*
* @see ImageRendererInterface::init()
* @return void
*/
public function init()
{
$this->svg = new SimpleXMLElement(
'<?xml version="1.0" encoding="UTF-8"?>'
. '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>'
);
$this->svg->addAttribute('version', '1.1');
$this->svg->addAttribute('width', $this->finalWidth . 'px');
$this->svg->addAttribute('height', $this->finalHeight . 'px');
$this->svg->addAttribute('viewBox', '0 0 ' . $this->finalWidth . ' ' . $this->finalHeight);
$this->svg->addChild('defs');
}
/**
* addColor(): defined by RendererInterface.
*
* @see ImageRendererInterface::addColor()
* @param string $id
* @param ColorInterface $color
* @return void
* @throws Exception\InvalidArgumentException
*/
public function addColor($id, ColorInterface $color)
{
$this->colors[$id] = (string) $color->toRgb();
}
/**
* drawBackground(): defined by RendererInterface.
*
* @see ImageRendererInterface::drawBackground()
* @param string $colorId
* @return void
*/
public function drawBackground($colorId)
{
$rect = $this->svg->addChild('rect');
$rect->addAttribute('x', 0);
$rect->addAttribute('y', 0);
$rect->addAttribute('width', $this->finalWidth);
$rect->addAttribute('height', $this->finalHeight);
$rect->addAttribute('fill', '#' . $this->colors[$colorId]);
}
/**
* drawBlock(): defined by RendererInterface.
*
* @see ImageRendererInterface::drawBlock()
* @param integer $x
* @param integer $y
* @param string $colorId
* @return void
*/
public function drawBlock($x, $y, $colorId)
{
$use = $this->svg->addChild('use');
$use->addAttribute('x', $x);
$use->addAttribute('y', $y);
$use->addAttribute(
'xlink:href',
$this->getRectPrototypeId($colorId),
'http://www.w3.org/1999/xlink'
);
}
/**
* getByteStream(): defined by RendererInterface.
*
* @see ImageRendererInterface::getByteStream()
* @return string
*/
public function getByteStream()
{
return $this->svg->asXML();
}
/**
* Get the prototype ID for a color.
*
* @param integer $colorId
* @return string
*/
protected function getRectPrototypeId($colorId)
{
if (!isset($this->prototypeIds[$colorId])) {
$id = 'r' . dechex(count($this->prototypeIds));
$rect = $this->svg->defs->addChild('rect');
$rect->addAttribute('id', $id);
$rect->addAttribute('width', $this->blockSize);
$rect->addAttribute('height', $this->blockSize);
$rect->addAttribute('fill', '#' . $this->colors[$colorId]);
$this->prototypeIds[$colorId] = '#' . $id;
}
return $this->prototypeIds[$colorId];
}
}

View File

@@ -0,0 +1,26 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer;
use BaconQrCode\Encoder\QrCode;
/**
* Renderer interface.
*/
interface RendererInterface
{
/**
* Renders a QR code.
*
* @param QrCode $qrCode
* @return string
*/
public function render(QrCode $qrCode);
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Text;
use BaconQrCode\Encoder\QrCode;
/**
* Html renderer.
*/
class Html extends Plain
{
/**
* HTML CSS class attribute value.
*
* @var string
*/
protected $class = '';
/**
* HTML CSS style definition for the code element.
*
* @var string
*/
protected $style = 'font-family: monospace; line-height: 0.65em; letter-spacing: -1px';
/**
* Set CSS class name.
*
* @param string $class
*/
public function setClass($class)
{
$this->class = $class;
}
/**
* Get CSS class name.
*
* @return string
*/
public function getClass()
{
return $this->class;
}
/**
* Set CSS style value.
*
* @param string $style
*/
public function setStyle($style)
{
$this->style = $style;
}
/**
* Get CSS style value.
*
* @return string
*/
public function getStyle()
{
return $this->style;
}
/**
* render(): defined by RendererInterface.
*
* @see RendererInterface::render()
* @param QrCode $qrCode
* @return string
*/
public function render(QrCode $qrCode)
{
$textCode = parent::render($qrCode);
$result = '<pre'
. ' style="' . htmlspecialchars($this->style, ENT_QUOTES, 'utf-8') . '"'
. ' class="' . htmlspecialchars($this->class, ENT_QUOTES, 'utf-8') . '"'
. '>' . $textCode . '</pre>';
return $result;
}
}

View File

@@ -0,0 +1,150 @@
<?php
/**
* BaconQrCode
*
* @link http://github.com/Bacon/BaconQrCode For the canonical source repository
* @copyright 2013 Ben 'DASPRiD' Scholzen
* @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
*/
namespace BaconQrCode\Renderer\Text;
use BaconQrCode\Exception;
use BaconQrCode\Encoder\QrCode;
use BaconQrCode\Renderer\RendererInterface;
/**
* Plaintext renderer.
*/
class Plain implements RendererInterface
{
/**
* Margin around the QR code, also known as quiet zone.
*
* @var integer
*/
protected $margin = 1;
/**
* Char used for full block.
*
* UTF-8 FULL BLOCK (U+2588)
*
* @var string
* @link http://www.fileformat.info/info/unicode/char/2588/index.htm
*/
protected $fullBlock = "\xE2\x96\x88";
/**
* Char used for empty space
*
* @var string
*/
protected $emptyBlock = ' ';
/**
* Set char used as full block (occupied space, "black").
*
* @param string $fullBlock
*/
public function setFullBlock($fullBlock)
{
$this->fullBlock = $fullBlock;
}
/**
* Get char used as full block (occupied space, "black").
*
* @return string
*/
public function getFullBlock()
{
return $this->fullBlock;
}
/**
* Set char used as empty block (empty space, "white").
*
* @param string $emptyBlock
*/
public function setEmptyBlock($emptyBlock)
{
$this->emptyBlock = $emptyBlock;
}
/**
* Get char used as empty block (empty space, "white").
*
* @return string
*/
public function getEmptyBlock()
{
return $this->emptyBlock;
}
/**
* Sets the margin around the QR code.
*
* @param integer $margin
* @return AbstractRenderer
* @throws Exception\InvalidArgumentException
*/
public function setMargin($margin)
{
if ($margin < 0) {
throw new Exception\InvalidArgumentException('Margin must be equal to greater than 0');
}
$this->margin = (int) $margin;
return $this;
}
/**
* Gets the margin around the QR code.
*
* @return integer
*/
public function getMargin()
{
return $this->margin;
}
/**
* render(): defined by RendererInterface.
*
* @see RendererInterface::render()
* @param QrCode $qrCode
* @return string
*/
public function render(QrCode $qrCode)
{
$result = '';
$matrix = $qrCode->getMatrix();
$width = $matrix->getWidth();
// Top margin
for ($x = 0; $x < $this->margin; $x++) {
$result .= str_repeat($this->emptyBlock, $width + 2 * $this->margin)."\n";
}
// Body
$array = $matrix->getArray();
foreach ($array as $row) {
$result .= str_repeat($this->emptyBlock, $this->margin); // left margin
foreach ($row as $byte) {
$result .= $byte ? $this->fullBlock : $this->emptyBlock;
}
$result .= str_repeat($this->emptyBlock, $this->margin); // right margin
$result .= "\n";
}
// Bottom margin
for ($x = 0; $x < $this->margin; $x++) {
$result .= str_repeat($this->emptyBlock, $width + 2 * $this->margin)."\n";
}
return $result;
}
}