Skip to content

Commit

Permalink
#251 Added Letter Spacing option
Browse files Browse the repository at this point in the history
  • Loading branch information
mpa12 committed Jul 1, 2024
1 parent 2349195 commit 0b126b2
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
vendor/
.vscode/
.env
.env
.idea
3 changes: 3 additions & 0 deletions src/demo/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ function gtag() {
<label for="size">Font size</label>
<input class="param" type="number" id="size" name="size" alt="Font size" placeholder="20" value="20">

<label for="letterSpacing">Font letter spacing</label>
<input class="param" type="text" id="letterSpacing" name="letterSpacing" alt="Font letter spacing" placeholder="normal" value="normal">

<label for="duration">Duration (ms per line)</label>
<input class="param" type="number" id="duration" name="duration" alt="Print duration (ms)" placeholder="5000" value="5000">

Expand Down
3 changes: 2 additions & 1 deletion src/demo/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ let preview = {
color: "36BCF7",
background: "00000000",
size: "20",
letterSpacing: "normal",
center: "false",
vCenter: "false",
multiline: "false",
Expand Down Expand Up @@ -230,5 +231,5 @@ window.addEventListener(
preview.addLine();
preview.update();
},
false
false,
);
47 changes: 47 additions & 0 deletions src/models/RendererModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class RendererModel
/** @var string $fontCSS CSS required for displaying the selected font */
public $fontCSS;

/** @var string $letterSpacing Font letter spacing */
public $letterSpacing;

/** @var string $template Path to template file */
public $template;

Expand All @@ -78,6 +81,7 @@ class RendererModel
"repeat" => "true",
"separator" => ";",
"random" => "false",
"letterSpacing" => "normal",
];

/**
Expand Down Expand Up @@ -106,6 +110,7 @@ public function __construct($template, $params)
$this->pause = $this->checkNumberNonNegative($params["pause"] ?? $this->DEFAULTS["pause"], "pause");
$this->repeat = $this->checkBoolean($params["repeat"] ?? $this->DEFAULTS["repeat"]);
$this->fontCSS = $this->fetchFontCSS($this->font, $this->weight, $params["lines"]);
$this->letterSpacing = $this->checkLetterSpacing($params["letterSpacing"] ?? $this->DEFAULTS["letterSpacing"]);
}

/**
Expand Down Expand Up @@ -224,4 +229,46 @@ private function fetchFontCSS($font, $weight, $text)
// font is not found
return "";
}

/**
* Validate unit for size properties
*
* This method validates if the given unit is a valid CSS size unit.
* It supports various units such as px, em, rem, pt, pc, in, cm, mm,
* ex, ch, vh, vw, vmin, vmax, and percentages.
*
* @param string $unit Unit for validation
* @return bool True if valid, false otherwise
*/
private function isValidUnit($unit)
{
return (bool) preg_match(
"/^(-?\\d+(\\.\\d+)?(px|em|rem|pt|pc|in|cm|mm|ex|ch|vh|vw|vmin|vmax|%))$/",
$unit
);
}

/**
* Validate font letter spacing
*
* This method validates the letter spacing property for fonts.
* It allows specific keywords (normal, inherit, initial, revert, revert-layer, unset)
* and valid CSS size units.
*
* @param string $letterSpacing Font letter spacing for validation
* @return string Validated font letter spacing
*/
private function checkLetterSpacing($letterSpacing)
{
// List of valid keywords for letter-spacing
$keywords = "normal|inherit|initial|revert|revert-layer|unset";

// Check if the input matches one of the keywords or a valid unit
if (preg_match("/^($keywords)$/", $letterSpacing) || $this->isValidUnit($letterSpacing)) {
return $letterSpacing;
}

// Return the default letter spacing value if the input is invalid
return $this->DEFAULTS['letterSpacing'];
}
}
3 changes: 2 additions & 1 deletion src/templates/main.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
</path>
<text font-family='"<?= $font ?>", monospace' fill='<?= $color ?>' font-size='<?= $size ?>'
dominant-baseline='<?= $vCenter ? "middle" : "auto" ?>'
x='<?= $center ? "50%" : "0%" ?>' text-anchor='<?= $center ? "middle" : "start" ?>'>
x='<?= $center ? "50%" : "0%" ?>' text-anchor='<?= $center ? "middle" : "start" ?>'
letter-spacing='<?= $letterSpacing ?>'>
<textPath xlink:href='#path<?= $i ?>'>
<?= $lines[$i] . "\n" ?>
</textPath>
Expand Down
1 change: 1 addition & 0 deletions src/views/RendererView.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function render()
"duration" => $this->model->duration,
"pause" => $this->model->pause,
"repeat" => $this->model->repeat,
"letterSpacing" => $this->model->letterSpacing,
]);
// render SVG with output buffering
ob_start();
Expand Down
29 changes: 29 additions & 0 deletions tests/OptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,33 @@ public function testRandom(): void
$model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals(false, $model->random);
}

/**
* Test Font Letter Spacing
*/
public function testLetterSpacing(): void
{
// default
$params = [
"lines" => "text",
];
$model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("normal", $model->letterSpacing);

// invalid
$params = [
"lines" => "text",
"letterSpacing" => "invalid",
];
$model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("normal", $model->letterSpacing);

// valid
$params = [
"lines" => "text",
"letterSpacing" => "10px",
];
$model = new RendererModel("src/templates/main.php", $params);
$this->assertEquals("10px", $model->letterSpacing);
}
}
23 changes: 23 additions & 0 deletions tests/RendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,27 @@ public function testRandom(): void
$this->assertStringContainsString("> $line </textPath>", $actualSVG);
}
}

/**
* Test Font Letter Spacing
*/
public function testLetterSpacing()
{
$params = [
"lines" => implode(";", [
"Full-stack web and app developer",
"Self-taught UI/UX Designer",
"10+ years of coding experience",
"Always learning new things",
]),
"letterSpacing" => "10px",
];
$controller = new RendererController($params);
$actualSVG = preg_replace("/\s+/", " ", $controller->render());
$this->assertStringContainsString(
"letter-spacing='10px'",
$actualSVG
);
$this->assertStringNotContainsString("letter-spacing='normal'", $actualSVG);
}
}
12 changes: 8 additions & 4 deletions tests/svg/test_normal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0b126b2

Please sign in to comment.