Css 如何制作自定义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" >

我正在尝试为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,盲文字形看起来明显映射到一个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'

其中,cxcy-中心点坐标,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=\"&#x28%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);
}