如何将文本转换为 SVG 路径?

2024-02-15

我在 ttf 文件中有一个字体,想要生成 SVG,并将文本转换为路径。我不需要图像(因此使用 imagettftext 或 Image Magick 字体渲染功能是不够的),我需要可以放大和缩小的形状,我想丢失有关所用字体的信息,并且不想在中引用它SVG 文件(因此此处不能使用字体声明)。是否可以?


我创建了自己的类来处理 SVG 字体文件并将文本转换为字形。使用示例:

include "SVGFont.php";
$svgFont = new SVGFont();
$svgFont->load("/path/to/font.svg");
$result = $svgFont->textToPaths("Simple text", 20);

结果示例:

<g transform="scale(0.009765625) translate(0, 0)"><path transform="translate(0,0) rotate(180) scale(-1, 1)" d="M92 471l183 16q13 -110 60.5 -180.5t147.5 -114t225 -43.5q111 0 196 33t126.5 90.5t41.5 125.5q0 69 -40 120.5t-132 86.5q-59 23 -261 71.5t-283 91.5q-105 55 -156.5 136.5t-51.5 182.5q0 111 63 207.5t184 146.5t269 50q163 0 287.5 -52.5t191.5 -154.5t72 -231 l-186 -14q-15 139 -101.5 210t-255.5 71q-176 0 -256.5 -64.5t-80.5 -155.5q0 -79 57 -130q56 -51 292.5 -104.5t324.5 -93.5q128 -59 189 -149.5t61 -208.5q0 -117 -67 -220.5t-192.5 -161t-282.5 -57.5q-199 0 -333.5 58t-211 174.5t-80.5 263.5z" /><path transform="translate(1366,0) rotate(180) scale(-1, 1)" d="M136 0v1062h180v-1062h-180zM136 1259v207h180v-207h-180z" /><path transform="translate(1821,0) rotate(180) scale(-1, 1)" d="M135 0v1062h161v-149q50 78 133 125.5t189 47.5q118 0 193.5 -49t106.5 -137q126 186 328 186q158 0 243 -87.5t85 -269.5v-729h-179v669q0 108 -17.5 155.5t-63.5 76.5t-108 29q-112 0 -186 -74.5t-74 -238.5v-617h-180v690q0 120 -44 180t-144 60q-76 0 -140.5 -40 t-93.5 -117t-29 -222v-551h-180z" /><path transform="translate(3527,0) rotate(180) scale(-1, 1)" d="M135 -407v1469h164v-138q58 81 131 121.5t177 40.5q136 0 240 -70t157 -197.5t53 -279.5q0 -163 -58.5 -293.5t-170 -200t-234.5 -69.5q-90 0 -161.5 38t-117.5 96v-517h-180zM298 525q0 -205 83 -303t201 -98q120 0 205.5 101.5t85.5 314.5q0 203 -83.5 304t-199.5 101 q-115 0 -203.5 -107.5t-88.5 -312.5z" /><path transform="translate(4666,0) rotate(180) scale(-1, 1)" d="M131 0v1466h180v-1466h-180z" /><path transform="translate(5121,0) rotate(180) scale(-1, 1)" d="M75 522q0 268 138 416t358 148q213 0 348 -145t135 -408q0 -16 -1 -48h-792q10 -175 99 -268t222 -93q99 0 169 52t111 166l186 -23q-44 -163 -163 -253t-304 -90q-233 0 -369.5 143.5t-136.5 402.5zM271 633h593q-12 134 -68 201q-86 104 -223 104q-124 0 -208.5 -83 t-93.5 -222z" /><path transform="translate(6260,0) rotate(180) scale(-1, 1)" d="" /><path transform="translate(6829,0) rotate(180) scale(-1, 1)" d="M36 922v140h132v263l179 108v-371h181v-140h-181v-621q0 -77 9.5 -99t31 -35t61.5 -13q30 0 79 7l26 -159q-76 -16 -136 -16q-98 0 -152 31t-76 81.5t-22 212.5v611h-132z" /><path transform="translate(7398,0) rotate(180) scale(-1, 1)" d="M75 522q0 268 138 416t358 148q213 0 348 -145t135 -408q0 -16 -1 -48h-792q10 -175 99 -268t222 -93q99 0 169 52t111 166l186 -23q-44 -163 -163 -253t-304 -90q-233 0 -369.5 143.5t-136.5 402.5zM271 633h593q-12 134 -68 201q-86 104 -223 104q-124 0 -208.5 -83 t-93.5 -222z" /><path transform="translate(8537,0) rotate(180) scale(-1, 1)" d="M15 0l388 552l-359 510h225l163 -249q46 -71 74 -119q44 66 81 117l179 251h215l-367 -500l395 -562h-221l-218 330l-58 89l-279 -419h-218z" /><path transform="translate(9561,0) rotate(180) scale(-1, 1)" d="M36 922v140h132v263l179 108v-371h181v-140h-181v-621q0 -77 9.5 -99t31 -35t61.5 -13q30 0 79 7l26 -159q-76 -16 -136 -16q-98 0 -152 31t-76 81.5t-22 212.5v611h-132z" /></g>

我的班级代码:

<?php

/**
 * This class represents SVG pa
 * @author Łukasz Ledóchowski [email protected] /cdn-cgi/l/email-protection
 * @version 0.1
 */
class SVGFont {

    protected $id = '';
    protected $horizAdvX = 0;
    protected $unitsPerEm = 0;
    protected $ascent = 0;
    protected $descent = 0;
    protected $glyphs = array();

    /**
     * Function takes UTF-8 encoded string and returns unicode number for every character.
     * Copied somewhere from internet, thanks.
     */
    function utf8ToUnicode( $str ) {
        $unicode = array();
        $values = array();
        $lookingFor = 1;

        for ($i = 0; $i < strlen( $str ); $i++ ) {
            $thisValue = ord( $str[ $i ] );
            if ( $thisValue < 128 ) $unicode[] = $thisValue;
            else {
                if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3;
                $values[] = $thisValue;
                if ( count( $values ) == $lookingFor ) {
                    $number = ( $lookingFor == 3 ) ?
                        ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ):
                        ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 );

                    $unicode[] = $number;
                    $values = array();
                    $lookingFor = 1;
                }
            }
        }

        return $unicode;
    }

    /**
     * Function takes path to SVG font (local path) and processes its xml
     * to get path representation of every character and additional
     * font parameters
     */
    public function load($filename) {
        $this->glyphs = array();
        $z = new XMLReader;
        $z->open($filename);

        // move to the first <product /> node
        while ($z->read()) {
            $name = $z->name;

            if ($z->nodeType == XMLReader::ELEMENT) {
                if ($name == 'font') {
                    $this->id = $z->getAttribute('id');
                    $this->horizAdvX = $z->getAttribute('horiz-adv-x');
                }

                if ($name == 'font-face') {
                    $this->unitsPerEm = $z->getAttribute('units-per-em');
                    $this->ascent = $z->getAttribute('ascent');
                    $this->descent = $z->getAttribute('descent');
                }

                if ($name == 'glyph') {
                    $unicode = $z->getAttribute('unicode');
                    $unicode = $this->utf8ToUnicode($unicode);
                    $unicode = $unicode[0];

                    $this->glyphs[$unicode] = new stdClass();
                    $this->glyphs[$unicode]->horizAdvX = $z->getAttribute('horiz-adv-x');
                    if (empty($this->glyphs[$unicode]->horizAdvX)) {
                        $this->glyphs[$unicode]->horizAdvX = $this->horizAdvX;
                    }
                    $this->glyphs[$unicode]->d = $z->getAttribute('d');
                }
            }
        }

    }

    /**
     * Function takes UTF-8 encoded string and size, returns xml for SVG paths representing this string.
     * @param string $text UTF-8 encoded text
     * @param int $asize size of requested text
     * @return string xml for text converted into SVG paths
     */
    public function textToPaths($text, $asize) {
        $lines = explode("\n", $text);
        $result = "";
        $horizAdvY = 0;
        foreach($lines as $text) {
            $text = $this->utf8ToUnicode($text);
            $size =  ((float)$asize) / $this->unitsPerEm;
            $result .= "<g transform=\"scale({$size}) translate(0, {$horizAdvY})\">";
            $horizAdvX = 0;
            for($i = 0; $i < count($text); $i++) {
                $letter = $text[$i];
                $result .= "<path transform=\"translate({$horizAdvX},{$horizAdvY}) rotate(180) scale(-1, 1)\" d=\"{$this->glyphs[$letter]->d}\" />";
                $horizAdvX += $this->glyphs[$letter]->horizAdvX;
            }
            $result .= "</g>";
            $horizAdvY += $this->ascent + $this->descent;
        }

        return $result;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将文本转换为 SVG 路径? 的相关文章

随机推荐

  • CSS Margin: 0 未设置为 0

    我是网页设计的新手 我使用 CSS 和 HTML 创建了网页布局 如下所示 问题是 即使我将边距设置为 0 上边距也没有设置为 0 并留下了一些空间 我怎样才能清除这个空白区域 问题的屏幕截图 样式表
  • 使用 php 为 apache 日志设置 REMOTE_USER

    在 mod perl 中我可以做类似的事情 r gt user username 然后用户名将显示在日志的用户名部分中 有没有办法在 php 中做到这一点 无需修改apache Edit 到目前为止我已经尝试过两种 SERVER REMOT
  • 为什么 string.split() 结果包含未定义?

    我想在其中一个上分割一个字符串 d or n 我能够成功地分割这两者之一 但不能同时分割 gt msg foo 1 bar n baz 2 gt msg split d foo 1 bar baz 2 gt msg split n foo
  • 在 POST 负载中使用环境变量

    我可以在我发布的有效负载中使用先前测试中设置的环境变量吗 eg POST list some key environment saved value 是的 你可以这么做 你这样发送 some key environment variable
  • Python print 语句在参数之间添加空格

    我正在编写一个非常基本的 hello 程序 但我在名称和第一个感叹号之间不断出现空格 而我在代码中没有看到该空格 我尝试用几种不同的方式重新格式化字符串部分来连接间距 但我无法弄清楚是什么导致了额外的空间 我尝试过单独使用感叹号 或者将其作
  • 在 CUDA 内核中声明变量

    假设您在 CUDA 内核中声明一个新变量 然后在多个线程中使用它 例如 global void kernel float delt float deltb int i blockIdx x blockDim x threadIdx x fl
  • 为数据类型定义自己的 Ord

    我正在尝试制作一些数据结构来解决图形难题 我正在尝试定义边缘的比较标准 但我不确定如何定义 迄今为止 data Edge Edge Set String Bool 如果边缘具有相同的字符串集 并且相等与布尔值没有任何关系 我如何 通知 编译
  • unordered_map 具有三个元素

    我试图在一个元素中包含三个元素unordered map 我尝试了以下代码 include
  • 如何解除对 Java 启动进程的阻止?

    当从命令行执行某些命令 比如说 x 时 我收到以下消息 按任意键继续 因此它会等待用户输入来解锁 但是当我从 java 执行相同的命令 x 时 Process p Runtime getRuntime exec cmd null cmdDi
  • C# 数组的协变和逆变 [重复]

    这个问题在这里已经有答案了 在阅读一本section http en wikipedia org wiki Covariance and contravariance 28computer science 29 Arrays在维基百科上一篇
  • Html IFrame 标签未在电子邮件正文中解释

    我需要在电子邮件正文中发送一个 html 文件 其中包含 iframe 该 html 文件在浏览器中工作正常并播放视频 但是当我在电子邮件正文中发送它时 iframe 标记不会被解释 因此不会表现在身体上 这是 html 文件 b Aman
  • 分配给位置参数[重复]

    这个问题在这里已经有答案了 如何在 Bash 中为位置参数赋值 我想为默认参数分配一个值 if z 4 then 4 3 fi 表明4不是命令 The set内置是设置位置参数的唯一方法 set this is a test echo 1
  • Scylladb:聚类键笛卡尔乘积大小 600 大于最大值 100

    我正在使用 data stax java 驱动程序来查询 scylladb 我在从 scylla 读取数据时看到此错误 RequestHandler ip 9042 回复服务器错误 集群键笛卡尔乘积大小 600 大于最大值 100 连接失效
  • Node.js - 服务器关闭了连接?

    我正在 Node js 服务器上运行一个 Web 应用程序 并且需要它始终在线 因此我将永远使用它 但这是我在一段时间后得到的结果 Error Connection lost The server closed the connection
  • 如何改变ios中源图像的脸部肤色?

    我的代码 如何管理不同肤色的RGB值 以及如何应用 这段代码将改变脸部和头发的颜色 但我想要 1 仅脸部着色 不包括头发 void changeSkinColorValue float value WithImage UIImage nee
  • Angular:将参数传递给另一个组件

    我被 Angular2 困住了 我想从 a 传递参数产品页面 例如 产品 ID 到支付页面 这是我迄今为止尝试过的 付款 html Message message
  • 覆盖对象时的 Perl 内存管理

    我的问题是关于 Perl 如何在内部管理对象的数据 当在 Perl 中创建对象时 新的子例程通常会返回对受祝福的对象的引用 以下面的代码为例 Create a new object my object Object gt new data1
  • 如何找到当前系统时区?

    在 Linux 上 我需要找到当前配置的时区作为 Olson 位置 我希望我的 C 或 C 代码能够移植到尽可能多的 Linux 系统 例如 我住在伦敦 所以我当前的奥尔森位置是 欧洲 伦敦 我是not对 BST EST 等时区 ID 感兴
  • SQL代码转换为C#数据类型问题

    我试图回答这个问题所以问题 https stackoverflow com questions 58726514 sp execution time is extremely slow 给出以下 SQL 代码 DECLARE input1
  • 如何将文本转换为 SVG 路径?

    我在 ttf 文件中有一个字体 想要生成 SVG 并将文本转换为路径 我不需要图像 因此使用 imagettftext 或 Image Magick 字体渲染功能是不够的 我需要可以放大和缩小的形状 我想丢失有关所用字体的信息 并且不想在中