如何制作自定义 svg 字体字形?
How to make custom svg font glyphs?
我正在尝试为 unicode 盲文范围制作 svg 字体。
我希望黑点是(#fontcolor)中的填充点,非点是圆线。
"⠛" 变成下面的 svg:
<svg width="40" height="80">
<g
style="fill-opacity:1;fill:#000000;stroke:#000000;stroke-width:2;stroke-opacity:1"
>
<circle id="c0"
cx="10" cy="10" r="9" />
<circle id="c1"
cx="10" cy="30" r="9" />
<circle id="c2"
style="fill:none;"
cx="10" cy="50" r="9" />
<circle id="c3"
cx="30" cy="10" r="9" />
<circle id="c4"
cx="30" cy="30" r="9" />
<circle id="c5"
style="fill:none;"
cx="30" cy="50" r="9" />
<circle id="c6"
style="fill:none;"
cx="10" cy="70" r="9" />
<circle id="c7"
style="fill:none;"
cx="30" cy="70" r="9" />
</g>
</svg>
这是我要复制的图像:
如您所知,盲文字形之间的关系是高度父系的。一个盲文字形有 8 个可能的点,每个点就像一个位:从 2800 到 28ff,或 00 到 ff,盲文 glpyhs 似乎明显映射到一个 8 位二进制数。
制作 256 个字形也是一项艰巨的工作。所以我写了一些 C 来自动生成 svg 字形。但是,生成的 svg 字体似乎不正确,因为在使用它时,每个字形都呈现为单个填充点,但我不知道问题出在哪里。这是一个编程错误吗?未能遵循 svg 字体规范?
一个错误是我手动将样式设置为“黑色”。我希望这是字体的 css 颜色,但我不知道如何从 svg 字体中“访问”该“变量”。
编译并 运行 没有特殊标志,将输出通过管道传输到“font.svg”。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef unsigned char u8;
void generateSVG(){
/* unicode braille
8 "bits" per glyph.
pattern where each bit gets placed in the glyph:
0 3
1 4
2 5
6 7
*/
const char* prelude =
"<svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">"
"<defs>"
"<font id=\"Braille-font\" horiz-adv-x=\"40\">"
"<font-face"
" units-per-em=\"40\""
" cap-height=\"80\""
" x-height=\"80\""
" ascent=\"80\""
" descent=\"0\""
" bbox=\"0, 0, 40, 80\""
" unicode-range=\"U+2800-28ff\""
" font-variant = \"normal\""
">"
"<font-face-src>"
" <font-face-name name=\"Braille Font\" />"
"</font-face-src>"
"</font-face>";
const char* postlude = "</font></defs></svg>";
printf("%s\n", prelude);
const int poslut[8][2] = {
{10,10},
{10,30},
{10,50},
{30,10},
{30,30},
{30,50},
{10,70},
{30,70}
}; // {x,y}[]
const char* cfmt = "<circle cx=\"%d\" cy=\"%d\" r=\"9\" %s/>";
const char* gfmt = "<glyph glyph-name=\"uni28%02x\" unicode=\"(%02x;\" horiz-adv-x=\"40\">";
// [0] = override the fill to "none", [1] = don't override
const char* fills[2] = {"style=\"fill:none;\" ",""};
u8 i = 0;
do {
char buffer[1024] = {'[=11=]'};
int pos = sprintf(buffer, gfmt, i,i);
u8 bits[8] = {
[0] = i & 0b00000001,
[1] = i & 0b00000010,
[2] = i & 0b00000100,
[3] = i & 0b00001000,
[4] = i & 0b00010000,
[5] = i & 0b00100000,
[6] = i & 0b01000000,
[7] = i & 0b10000000
};
// for some reason the bit shift method (i&(1<<bit)) does not work, so an ugly lut is required
for (u8 bit = 0; bit < 8; ++bit)
{
int x = poslut[bit][0];
int y = poslut[bit][1];
//const char* fill = i&(1<<bit) ? fills[1] : fills[0] ;
//const char* fill = fills[ i&(1<<bit) != 0 ];
const char* fill = fills[bits[bit] != 0];
pos += sprintf(&buffer[pos], cfmt,
x, y, fill
);
}
pos += sprintf(&buffer[pos], "</glyph>");
printf("%s\n", buffer);
i++;
} while (i != 0); // 256 mod 256 = 0
printf("%s\n", postlude);
}
这里是 'filled' 和 'hollow' 圆形路径的示例:
外圈(顺时针):'M cx-or,cy A or,or 1 1 1 cx+or,cy A or,or 1 1 1 cx-or,cy'
内圈(逆时针):'M cx+ir,cy A ir ir 1 1 0 cx-ir,cy A ir,ir 1 1 0 cx+ir,cy'
其中 cx,cy - 中心点坐标,ir - 内半径,或 - 外半径
实心圆只是外圆,空心圆是内外圆的组合。
<svg width="32" height="32">
<path d="M 6,12 A 6,6 1 1 1 18,12 A 6,6 1 1 1 6,12"/>
</svg>
<svg width="32" height="32">
<path d="M 6,12 A 6,6 1 1 1 18,12 A 6,6 1 1 1 6,12 M 16,12 A 4,4 1 1 0 8,12 A 4,4 1 1 0 16,12"/>
</svg>
我正在尝试为 unicode 盲文范围制作 svg 字体。 我希望黑点是(#fontcolor)中的填充点,非点是圆线。
"⠛" 变成下面的 svg:
<svg width="40" height="80">
<g
style="fill-opacity:1;fill:#000000;stroke:#000000;stroke-width:2;stroke-opacity:1"
>
<circle id="c0"
cx="10" cy="10" r="9" />
<circle id="c1"
cx="10" cy="30" r="9" />
<circle id="c2"
style="fill:none;"
cx="10" cy="50" r="9" />
<circle id="c3"
cx="30" cy="10" r="9" />
<circle id="c4"
cx="30" cy="30" r="9" />
<circle id="c5"
style="fill:none;"
cx="30" cy="50" r="9" />
<circle id="c6"
style="fill:none;"
cx="10" cy="70" r="9" />
<circle id="c7"
style="fill:none;"
cx="30" cy="70" r="9" />
</g>
</svg>
这是我要复制的图像:
如您所知,盲文字形之间的关系是高度父系的。一个盲文字形有 8 个可能的点,每个点就像一个位:从 2800 到 28ff,或 00 到 ff,盲文 glpyhs 似乎明显映射到一个 8 位二进制数。
制作 256 个字形也是一项艰巨的工作。所以我写了一些 C 来自动生成 svg 字形。但是,生成的 svg 字体似乎不正确,因为在使用它时,每个字形都呈现为单个填充点,但我不知道问题出在哪里。这是一个编程错误吗?未能遵循 svg 字体规范?
一个错误是我手动将样式设置为“黑色”。我希望这是字体的 css 颜色,但我不知道如何从 svg 字体中“访问”该“变量”。
编译并 运行 没有特殊标志,将输出通过管道传输到“font.svg”。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef unsigned char u8;
void generateSVG(){
/* unicode braille
8 "bits" per glyph.
pattern where each bit gets placed in the glyph:
0 3
1 4
2 5
6 7
*/
const char* prelude =
"<svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">"
"<defs>"
"<font id=\"Braille-font\" horiz-adv-x=\"40\">"
"<font-face"
" units-per-em=\"40\""
" cap-height=\"80\""
" x-height=\"80\""
" ascent=\"80\""
" descent=\"0\""
" bbox=\"0, 0, 40, 80\""
" unicode-range=\"U+2800-28ff\""
" font-variant = \"normal\""
">"
"<font-face-src>"
" <font-face-name name=\"Braille Font\" />"
"</font-face-src>"
"</font-face>";
const char* postlude = "</font></defs></svg>";
printf("%s\n", prelude);
const int poslut[8][2] = {
{10,10},
{10,30},
{10,50},
{30,10},
{30,30},
{30,50},
{10,70},
{30,70}
}; // {x,y}[]
const char* cfmt = "<circle cx=\"%d\" cy=\"%d\" r=\"9\" %s/>";
const char* gfmt = "<glyph glyph-name=\"uni28%02x\" unicode=\"(%02x;\" horiz-adv-x=\"40\">";
// [0] = override the fill to "none", [1] = don't override
const char* fills[2] = {"style=\"fill:none;\" ",""};
u8 i = 0;
do {
char buffer[1024] = {'[=11=]'};
int pos = sprintf(buffer, gfmt, i,i);
u8 bits[8] = {
[0] = i & 0b00000001,
[1] = i & 0b00000010,
[2] = i & 0b00000100,
[3] = i & 0b00001000,
[4] = i & 0b00010000,
[5] = i & 0b00100000,
[6] = i & 0b01000000,
[7] = i & 0b10000000
};
// for some reason the bit shift method (i&(1<<bit)) does not work, so an ugly lut is required
for (u8 bit = 0; bit < 8; ++bit)
{
int x = poslut[bit][0];
int y = poslut[bit][1];
//const char* fill = i&(1<<bit) ? fills[1] : fills[0] ;
//const char* fill = fills[ i&(1<<bit) != 0 ];
const char* fill = fills[bits[bit] != 0];
pos += sprintf(&buffer[pos], cfmt,
x, y, fill
);
}
pos += sprintf(&buffer[pos], "</glyph>");
printf("%s\n", buffer);
i++;
} while (i != 0); // 256 mod 256 = 0
printf("%s\n", postlude);
}
这里是 'filled' 和 'hollow' 圆形路径的示例:
外圈(顺时针):'M cx-or,cy A or,or 1 1 1 cx+or,cy A or,or 1 1 1 cx-or,cy'
内圈(逆时针):'M cx+ir,cy A ir ir 1 1 0 cx-ir,cy A ir,ir 1 1 0 cx+ir,cy'
其中 cx,cy - 中心点坐标,ir - 内半径,或 - 外半径
实心圆只是外圆,空心圆是内外圆的组合。
<svg width="32" height="32">
<path d="M 6,12 A 6,6 1 1 1 18,12 A 6,6 1 1 1 6,12"/>
</svg>
<svg width="32" height="32">
<path d="M 6,12 A 6,6 1 1 1 18,12 A 6,6 1 1 1 6,12 M 16,12 A 4,4 1 1 0 8,12 A 4,4 1 1 0 16,12"/>
</svg>