Css 如何制作自定义svg字体图示符?
我正在尝试为unicode盲文范围制作svg字体。 我希望黑点用点填充(#fontcolor),非点用圆线填充 "⠛" 成为以下svg:Css 如何制作自定义svg字体图示符?,css,c,svg,fonts,Css,C,Svg,Fonts,我正在尝试为unicode盲文范围制作svg字体。 我希望黑点用点填充(#fontcolor),非点用圆线填充 "⠛" 成为以下svg: <svg width="40" height="80"> <g style="fill-opacity:1;fill:#000000;stroke:#000000;stroke-width:2;stroke-opacity:1" >
<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,盲文字形看起来明显映射到一个8位二进制数
制作256个字形也需要很多工作。因此我编写了一些C来自动生成svg字形。但是,生成的svg字体似乎不正确,因为在使用它时,每个字形都被渲染为单个填充点,但我不知道问题出在哪里。这是编程错误吗?未能遵循svg字体规范
一个错误是,我手动将样式设置为“黑色”。我希望这是字体的css颜色,但我不知道如何从svg字体中“访问”该“变量”
在没有特殊标志的情况下编译并运行,将输出导入“font.svg”
#包括
#包括
#包括
#包括
typedef无符号字符u8;
void generateSVG(){
/*unicode盲文
每字形8“位”。
每个位放置在图示符中的模式:
0 3
1 4
2 5
6 7
*/
常量字符*前奏曲=
""
""
""
""
""
" "
""
"";
const char*postlude=“”;
printf(“%s\n”,前奏曲);
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=“”;
const char*gfmt=“”;
//[0]=将填充覆盖为“无”,[1]=不覆盖
常量字符*填充[2]={“样式=\”填充:无;\“”,“”};
u8 i=0;
做{
字符缓冲区[1024]={'\0'};
int pos=sprintf(缓冲区,gfmt,i,i);
u8位[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
};
//出于某种原因,位移位法(i&(1这里是“填充”和“空心”圆路径的示例:
外圈(顺时针):'M cx or,cy A or,或11 cx+or,cy A or,或11 cx or,cy'
内圈(逆时针方向):'M cx+ir,cy A ir 1 10 cx ir,cy A ir,ir 1 10 cx+ir,cy'
其中,cx,cy-中心点坐标,ir-内半径,或-外半径
填充圆仅为外部,空心是内部和外部的组合
我认为图标字体不支持“笔划”,只支持“填充”…因此对于黑色圆圈,您可以使用,对于白色圆圈,外部部分顺时针,内部部分逆时针-clockwise@MichaelRovinsky啊,我的意思是“白色”点是字体css颜色中的圆形,而“黑色”点是圆形"要在字体的css颜色中填充圆点。但是如果你是正确的,我只需要在圆和路径之间交替。你知道如何正确处理svg字体中的颜色吗?你不需要在图标字体本身中指定颜色。图标图示符只需要d和unicode属性:;当你在应用程序中使用它时,只需设置颜色风格:;你可以在FontAwesome中看到它是如何工作的reference@MichaelRovinskysvg路径似乎根本不支持圆。即使使用椭圆拱门制作圆,我也不知道如何填充1位的圆。谢谢!您是如何选择单位6、12、1、18、32等的?最后,如何设置字体宽度的笔划宽度?12,12是圆的中心点。6是外半径,4是内半径。32是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] = {'\0'};
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);
}