-
Notifications
You must be signed in to change notification settings - Fork 93
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
feat!: Implement a font registry for text rendering #191
Conversation
For reference, here is a sample image: Generated by this code: <?php
require __DIR__ . '/vendor/autoload.php';
use SVG\SVG;
const FONTS_DIR = __DIR__.'/fonts/';
SVG::addFont(FONTS_DIR . 'Ubuntu-Regular.ttf');
SVG::addFont(FONTS_DIR . 'Ubuntu-Bold.ttf');
SVG::addFont(FONTS_DIR . 'Ubuntu-Italic.ttf');
SVG::addFont(FONTS_DIR . 'Ubuntu-BoldItalic.ttf');
SVG::addFont(FONTS_DIR . 'Ubuntu-Light.ttf');
SVG::addFont(FONTS_DIR . 'Ubuntu-LightItalic.ttf');
SVG::addFont(FONTS_DIR . 'UbuntuMono-Regular.ttf');
SVG::addFont(FONTS_DIR . 'UbuntuMono-Bold.ttf');
SVG::addFont(FONTS_DIR . 'UbuntuMono-Italic.ttf');
SVG::addFont(FONTS_DIR . 'UbuntuMono-BoldItalic.ttf');
$image = SVG::fromString('
<svg width="220" height="220">
<rect x="0" y="0" width="100%" height="100%" fill="lightgray"/>
<g font-size="15">
<text y="20">regular</text>
<text y="40" font-weight="100">light</text>
<text y="60" font-weight="100" font-style="italic">light italic</text>
<text y="80" font-weight="bold">bold</text>
<text y="100" font-style="italic">italic</text>
<text y="120" font-weight="bold" font-style="italic">bold italic</text>
<text y="140" font-family="Ubuntu Mono">monospace</text>
<text y="160" font-size="15" font-family="Ubuntu Mono" font-weight="bold">monospace bold</text>
<text y="180" font-size="15" style="font-family: Ubuntu Mono; font-style: italic">monospace italic</text>
<text y="200" font-size="15" style="font-family: Ubuntu Mono; font-weight: bold; font-style: italic">monospace bold italic</text>
</g>
</svg>
');
header('Content-Type: image/png');
$doc = $image->getDocument();
imagepng($image->toRasterImage($doc->getWidth(), $doc->getHeight())); |
Fixes #82, #168, #171. This patch removes the artificial `SVGFont` class as well as the `SVGText::setFont(SVGFont $font)` method. Instead, it is now possible to register TrueType (`.ttf`) font files by calling `SVG::addFont()` with a file path. A TrueType font file parser is implemented based on Microsoft's OpenType specification. This allows us to choose the best matching font file for a given text element automatically, just like a browser would, based on algorithms from CSS. Currently, TTF files are supported in the "Regular", "Bold", "Italic", and "Bold Italic" variants. The simple algorithm implemented here tries to match the font family exactly, if possible, falling back to any other font. Generic font families such as "serif" or "monospace" aren't supported yet and will trigger the fallback. Also, the relative weights "bolder" and "lighter" aren't computed and fall back to normal weight. BREAKING CHANGE: `SVGFont` class and some methods on `SVGText` removed.
By looking at the "OS/2" TTF table in addition to the "name" table, we can gather additional info about the font weight besides whether a font is bold or not. By doing so, we gain support for every weight level! :)
Hi @meyfa, |
@KWcDP6hz3 This is correct. The previous approach did not make sense from an API design perspective, since the If embedding the entire font data within the SVG is something you need, you will have to create a style element containing |
Fixes #82
Fixes #168
Fixes #171
This patch removes the artificial
SVGFont
class as well as theSVGText::setFont(SVGFont $font)
method. Instead, it is now possible to register TrueType (.ttf
) font files by callingSVG::addFont()
with a file path.A TrueType font file parser is implemented based on Microsoft's OpenType specification. This allows us to choose the best matching font file for a given text element automatically, just like a browser would, based on algorithms from CSS.
Currently, TTF files are supported with all weight levels, and in the italic and non-italic styles. The simple algorithm implemented here tries to match the font family exactly, if possible, falling back to any other font. Generic font families such as "serif" or "monospace" aren't supported yet and will trigger the fallback. Also, the relative weights "bolder" and "lighter" aren't computed and fall back to normal weight.
BREAKING CHANGE:
SVGFont
class and some methods onSVGText
removed.