-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from kellegous/drawing
added basic drawing
- Loading branch information
Showing
10 changed files
with
475 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: PHP Composer | ||
name: Validation | ||
|
||
on: | ||
push: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
], | ||
"require": { | ||
"php": "^8.3", | ||
"ext-gd": "*", | ||
"symfony/console": "^7.0" | ||
}, | ||
"require-dev": { | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kellegous\Algs4\Graphics; | ||
|
||
/** | ||
* Representation of an RGBA color. | ||
*/ | ||
final readonly class Color | ||
{ | ||
/** | ||
* @param int $id | ||
*/ | ||
private function __construct( | ||
private int $id | ||
) { | ||
} | ||
|
||
/** | ||
* Create a new opaque color from the given RGB values. | ||
* @param Drawing $drawing | ||
* @param int<0,255> $r | ||
* @param int<0,255> $g | ||
* @param int<0,255> $b | ||
* @return self | ||
* @throws Exception | ||
* @see Drawing::colorFromRGB() | ||
*/ | ||
public static function fromRGB( | ||
Drawing $drawing, | ||
int $r, | ||
int $g, | ||
int $b, | ||
): self { | ||
$c = imagecolorallocate($drawing->getImage(), $r, $g, $b); | ||
if ($c === false) { | ||
throw new Exception('unable to allocate color'); | ||
} | ||
return new self($c); | ||
} | ||
|
||
/** | ||
* Create a new opaque color from the given RGB values. | ||
* @param Drawing $drawing | ||
* @param int<0,255> $r | ||
* @param int<0,255> $g | ||
* @param int<0,255> $b | ||
* @param int<0,255> $a | ||
* @return self | ||
* @throws Exception | ||
*/ | ||
public static function fromRGBA( | ||
Drawing $drawing, | ||
int $r, | ||
int $g, | ||
int $b, | ||
int $a, | ||
): self { | ||
$c = imagecolorallocatealpha($drawing->getImage(), $r, $g, $b, $a >> 1); | ||
if ($c === false) { | ||
throw new Exception('unable to allocate color'); | ||
} | ||
return new self($c); | ||
} | ||
|
||
/** | ||
* Get the GD color index. This will be the color as an integer. | ||
* @return int | ||
* @internal | ||
*/ | ||
public function getID(): int | ||
{ | ||
return $this->id; | ||
} | ||
|
||
/** | ||
* Get the red component of the color. | ||
* @return int<0,255> | ||
*/ | ||
public function red(): int | ||
{ | ||
return ($this->id >> 16) & 0xff; | ||
} | ||
|
||
/** | ||
* Get the green component of the color. | ||
* @return int<0,255> | ||
*/ | ||
public function green(): int | ||
{ | ||
return ($this->id >> 8) & 0xff; | ||
} | ||
|
||
/** | ||
* Get the blue component of the color. | ||
* @return int<0,255> | ||
*/ | ||
public function blue(): int | ||
{ | ||
return $this->id & 0xff; | ||
} | ||
|
||
/** | ||
* Get the alpha component of the color. | ||
* @return int<0,255> | ||
*/ | ||
public function alpha(): int | ||
{ | ||
$a = (($this->id >> 24) & 0xff) << 1; | ||
assert($a >= 0 && $a <= 255); | ||
return $a; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kellegous\Algs4\Graphics; | ||
|
||
/** | ||
* An ouput destination for a drawing. | ||
*/ | ||
final readonly class Destination | ||
{ | ||
/** | ||
* @param resource|string $destination | ||
*/ | ||
private function __construct(private mixed $destination) | ||
{ | ||
} | ||
|
||
/** | ||
* Create a destination that writes to the given stream. | ||
* @param resource $destination | ||
* @return self | ||
*/ | ||
public static function toStream(mixed $destination): self | ||
{ | ||
return new self($destination); | ||
} | ||
|
||
/** | ||
* Create a destination that writes to the given file. | ||
* @param string $path | ||
* @return self | ||
*/ | ||
public static function toFile(string $path): self | ||
{ | ||
return new self($path); | ||
} | ||
|
||
/** | ||
* @return resource|string | ||
* @internal | ||
*/ | ||
public function get(): mixed | ||
{ | ||
return $this->destination; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kellegous\Algs4\Graphics; | ||
|
||
use GdImage; | ||
|
||
/** | ||
* | ||
*/ | ||
final readonly class Drawing | ||
{ | ||
/** | ||
* @var GdImage | ||
*/ | ||
private GdImage $im; | ||
|
||
/** | ||
* @param int $width | ||
* @param int $height | ||
* @param bool $with_alpha_blending | ||
* @param bool $with_antialiasing | ||
* @throws Exception | ||
*/ | ||
public function __construct( | ||
int $width, | ||
int $height, | ||
bool $with_alpha_blending = true, | ||
bool $with_antialiasing = true | ||
) { | ||
$im = imagecreatetruecolor($width, $height); | ||
if ($im === false) { | ||
throw new Exception('unable to create image'); | ||
} | ||
|
||
if (!imagealphablending($im, $with_alpha_blending)) { | ||
throw new Exception('unable to set alpha blending'); | ||
} | ||
|
||
if (!imageantialias($im, $with_antialiasing)) { | ||
throw new Exception('unable to set antialiasing'); | ||
} | ||
$this->im = $im; | ||
} | ||
|
||
/** | ||
* @return GdImage | ||
* @internal | ||
*/ | ||
public function getImage(): GdImage | ||
{ | ||
return $this->im; | ||
} | ||
|
||
/** | ||
* @param Destination $dest | ||
* @param int $quality | ||
* @param int $filters | ||
* @return void | ||
* @throws Exception | ||
*/ | ||
public function writePNG( | ||
Destination $dest, | ||
int $quality = -1, | ||
int $filters = -1, | ||
): void { | ||
if (!imagepng($this->im, $dest->get(), $quality, $filters)) { | ||
throw new Exception('unable to write PNG'); | ||
} | ||
} | ||
|
||
/** | ||
* @param Destination $dest | ||
* @param int $quality | ||
* @return void | ||
* @throws Exception | ||
*/ | ||
public function writeJPEG( | ||
Destination $dest, | ||
int $quality = -1, | ||
): void { | ||
if (!imagejpeg($this->im, $dest->get(), $quality)) { | ||
throw new Exception('unable to write JPEG'); | ||
} | ||
} | ||
|
||
/** | ||
* @param int<0,255> $r | ||
* @param int<0,255> $g | ||
* @param int<0,255> $b | ||
* @return Color | ||
* @throws Exception | ||
*/ | ||
public function colorFromRGB(int $r, int $g, int $b): Color | ||
{ | ||
return Color::fromRGB($this, $r, $g, $b); | ||
} | ||
|
||
/** | ||
* @param int<0,255> $r | ||
* @param int<0,255> $g | ||
* @param int<0,255> $b | ||
* @param int<0,255> $a | ||
* @return Color | ||
* @throws Exception | ||
*/ | ||
public function colorFromRGBA(int $r, int $g, int $b, int $a): Color | ||
{ | ||
return Color::fromRGBA($this, $r, $g, $b, $a); | ||
} | ||
|
||
/** | ||
* @param int $x1 | ||
* @param int $y1 | ||
* @param int $x2 | ||
* @param int $y2 | ||
* @return Rectangle | ||
*/ | ||
public function rectangle(int $x1, int $y1, int $x2, int $y2): Rectangle | ||
{ | ||
return new Rectangle($this, $x1, $y1, $x2, $y2); | ||
} | ||
|
||
/** | ||
* @param int $center_x | ||
* @param int $center_y | ||
* @param int $width | ||
* @param int $height | ||
* @return Ellipse | ||
*/ | ||
public function ellipse(int $center_x, int $center_y, int $width, int $height): Ellipse | ||
{ | ||
return new Ellipse($this, $center_x, $center_y, $width, $height); | ||
} | ||
|
||
/** | ||
* @param int $x | ||
* @param int $y | ||
* @param Color $color | ||
* @return void | ||
* @throws Exception | ||
*/ | ||
public function floodFill(int $x, int $y, Color $color): void | ||
{ | ||
if (!imagefill($this->im, $x, $y, $color->getID())) { | ||
throw new Exception('unable to flood fill'); | ||
} | ||
} | ||
} |
Oops, something went wrong.