Skip to content

Instantly share code, notes, and snippets.

@matthewjberger
Last active April 28, 2021 05:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewjberger/92eb3c83a1a2d48153602b3100d9c226 to your computer and use it in GitHub Desktop.
Save matthewjberger/92eb3c83a1a2d48153602b3100d9c226 to your computer and use it in GitHub Desktop.
Notes on using vulkan to render SDF
// struct Vertex {
// pos: [f32; 3],
// uv: [f32; 2],
//}
// AngelCode .fnt format structs and classes
// http://www.angelcode.com/products/bmfont/doc/file_format.html
// struct bmchar {
// x: u32,
// y: u32,
// width: u32,
// height: u32,
// x_offset: i32,
// y_offset: i32,
// x_advance: i32,
// page: u32,
// };
// Quick and dirty : complete ASCII table
// Only chars present in the .fnt are filled with data!
// fontChars: [bmchar; 255]
// TODO: Store and apply kerning!
int32_t nextValuePair(std::stringstream *stream)
{
std::string pair;
*stream >> pair;
uint32_t spos = pair.find("=");
std::string value = pair.substr(spos + 1);
int32_t val = std::stoi(value);
return val;
}
// Basic parser for AngelCode bitmap font format files
// See http://www.angelcode.com/products/bmfont/doc/file_format.html for details
void parsebmFont()
{
std::string fileName = getAssetPath() + "font.fnt";
std::filebuf fileBuffer;
fileBuffer.open(fileName, std::ios::in);
std::istream istream(&fileBuffer);
assert(istream.good());
while (!istream.eof())
{
std::string line;
std::stringstream lineStream;
std::getline(istream, line);
lineStream << line;
std::string info;
lineStream >> info;
if (info == "char")
{
// char id
uint32_t charid = nextValuePair(&lineStream);
// Char properties
fontChars[charid].x = nextValuePair(&lineStream);
fontChars[charid].y = nextValuePair(&lineStream);
fontChars[charid].width = nextValuePair(&lineStream);
fontChars[charid].height = nextValuePair(&lineStream);
fontChars[charid].xoffset = nextValuePair(&lineStream);
fontChars[charid].yoffset = nextValuePair(&lineStream);
fontChars[charid].xadvance = nextValuePair(&lineStream);
fontChars[charid].page = nextValuePair(&lineStream);
}
}
}
// Load an sdf font from a .fnt file by parsing the angelcode .fnt format into the ascii_table
// Geometry
// Create a vertex buffer containing quads for the passed text
// Creates a vertex buffer containing quads for the passed text
fn generateText(text
: &str)
{
// vec of Vertex
let indexOffset : u32 = 0;
let w : f32 = textures.fontSDF.width;
let posx = 0.0f;
let posy = 0.0f;
// Iterate over chars
for (uint32_t i = 0; i < text.size(); i++)
{
// Lookup corresponding char in ascii_table for info
bmchar *charInfo = &fontChars[(int)text[i]];
// Default to width of 36 if width is 0
if (charInfo->width == 0)
charInfo->width = 36;
// Calculate width, height, and dimensions for quad
float charw = ((float)(charInfo->width) / 36.0f);
float dimx = 1.0f * charw;
float charh = ((float)(charInfo->height) / 36.0f);
float dimy = 1.0f * charh;
float us = charInfo->x / w;
float ue = (charInfo->x + charInfo->width) / w;
float ts = charInfo->y / w;
float te = (charInfo->y + charInfo->height) / w;
float xo = charInfo->xoffset / 36.0f;
float yo = charInfo->yoffset / 36.0f;
posy = yo;
// Push the calculated vertex into the buffer
vertices.push_back({{posx + dimx + xo, posy + dimy, 0.0f}, {ue, te}});
vertices.push_back({{posx + xo, posy + dimy, 0.0f}, {us, te}});
vertices.push_back({{posx + xo, posy, 0.0f}, {us, ts}});
vertices.push_back({{posx + dimx + xo, posy, 0.0f}, {ue, ts}});
// Push 6 indices in, incrementing by the indexOffset
std::array<uint32_t, 6> letterIndices = {0, 1, 2, 2, 3, 0};
for (auto &index : letterIndices)
{
indices.push_back(indexOffset + index);
}
// Increment the index offset
indexOffset += 4;
// Advance the x pos
float advance = ((float)(charInfo->xadvance) / 36.0f);
posx += advance;
}
indexCount = indices.size();
// Center vertices
for (auto &v : vertices)
{
v.pos[0] -= posx / 2.0f;
v.pos[1] -= 0.5f;
}
// Generate host accessible buffers for the text vertices and indices and upload the data
}
// Vertex description
// size of Vertex
// Attribute descriptions
// location 0: position
// offset 0, vk::Format::R32G32B32_SFLOAT
// location 1 : Texture coordinates
// offset (sizeof(float) * 3), vk::Format::R32G32_SFLOAT
// Descriptor pool sizes
// 4 uniform buffer
// 2 combined image sampler
//
// max set size 2
// Descriptor set layout
// binding 0: vertex shader uniform buffer
// uniform buffer, vertex stage
// binding 1: fragment shader image sampler
// combined image sampler, fragment stage
// binding 2: fragment shader uniform buffer
// uniform buffer, fragment stage
// Descriptor Set
// allocate the descriptor set
// textureDescriptor image info
// fontSdf texture sampler/view, shader read only optimal layout
// write descriptor sets
// binding 0: vertex shader uniform buffer
// descriptor type uniform buffer, uniformBufferVs
// binding 1: fragment shader texture sampler
// descriptor type combined image sampler, textureDescriptor
// binding 2: fragment shader uniform buffer
// descriptor type uniform buffer, uniformBufferFs
// update descriptor sets using the write descriptor sets
// SDF
// bind descriptor set
// bind pipeline
// bind vertex buffers
// bind index buffers
// draw indexed quads
// Uniform Buffer Vertex Shader
// struct VertexShaderUbo
// {
// projection: glm::Mat4,
// modelView: glm::Mat4,
// }
//
// Uniform Buffer Fragment Shader
// struct FragmentShaderUbo
// {
// outlineColor: glm::Vec4, // 1.0, 0.0, 0.0, 0.0
// outlineWidth: f32, // 0.6
// ouline: bool, // true
// }
// SDF Pipeline
//
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST (primitive topology)
// rasterization state, polygon mode fill, cull mode none, front face counter clockwise
// blending enabled, color write mask = 0xF
//
// blendAttachmentState.blendEnable = VK_TRUE;
// blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
// blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
// blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
// blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
// blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
// blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
// blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
//
// depth test disabled
// depth write enabled
// depth compare op less or equal
//
// multisampling SampleCountFlags TYPE_1
// dynamic viewport and scissor
//
// sdf.vert.spv
// sdf.frag.spv
// vertex shader
//
// #version 450
// layout (location = 0) in vec3 inPos;
// layout (location = 1) in vec2 inUV;
// layout (binding = 0) uniform UBO
// {
// mat4 projection;
// mat4 model;
// } ubo;
// layout (location = 0) out vec2 outUV;
// void main()
// {
// outUV = inUV;
// gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
// }
// fragment shader
//
// #version 450
// layout (binding = 1) uniform sampler2D samplerColor;
// layout (binding = 2) uniform UBO
// {
// vec4 outlineColor;
// float outlineWidth;
// float outline;
// } ubo;
// layout (location = 0) in vec2 inUV;
// layout (location = 0) out vec4 outFragColor;
// void main()
// {
// float distance = texture(samplerColor, inUV).a;
// float smoothWidth = fwidth(distance);
// float alpha = smoothstep(0.5 - smoothWidth, 0.5 + smoothWidth, distance);
// vec3 rgb = vec3(alpha);
// if (ubo.outline > 0.0)
// {
// float w = 1.0 - ubo.outlineWidth;
// alpha = smoothstep(w - smoothWidth, w + smoothWidth, distance);
// rgb += mix(vec3(alpha), ubo.outlineColor.rgb, alpha);
// }
// outFragColor = vec4(rgb, alpha);
// }
info face="Arial Black Standard" size=32 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=4,4,4,4 spacing=-8,-8
common lineHeight=46 base=36 scaleW=512 scaleH=512 pages=1 packed=0
page id=0 file="sdf.png"
chars count=97
char id=0 x=237 y=102 width=25 height=29 xoffset=-4 yoffset=11 xadvance=24 page=0 chnl=0
char id=10 x=0 y=0 width=0 height=0 xoffset=-4 yoffset=0 xadvance=0 page=0 chnl=0
char id=32 x=0 y=0 width=0 height=0 xoffset=-4 yoffset=0 xadvance=11 page=0 chnl=0
char id=33 x=27 y=102 width=15 height=32 xoffset=-4 yoffset=8 xadvance=11 page=0 chnl=0
char id=34 x=298 y=134 width=24 height=17 xoffset=-4 yoffset=8 xadvance=16 page=0 chnl=0
char id=35 x=154 y=102 width=28 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=36 x=150 y=0 width=28 height=37 xoffset=-4 yoffset=6 xadvance=21 page=0 chnl=0
char id=37 x=117 y=102 width=37 height=32 xoffset=-4 yoffset=8 xadvance=32 page=0 chnl=0
char id=38 x=182 y=102 width=34 height=32 xoffset=-4 yoffset=8 xadvance=28 page=0 chnl=0
char id=39 x=322 y=134 width=15 height=17 xoffset=-4 yoffset=8 xadvance=9 page=0 chnl=0
char id=40 x=20 y=0 width=18 height=38 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=41 x=38 y=0 width=19 height=38 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=42 x=279 y=134 width=19 height=21 xoffset=-4 yoffset=8 xadvance=18 page=0 chnl=0
char id=43 x=186 y=134 width=26 height=26 xoffset=-4 yoffset=11 xadvance=21 page=0 chnl=0
char id=44 x=264 y=134 width=15 height=21 xoffset=-4 yoffset=25 xadvance=11 page=0 chnl=0
char id=45 x=394 y=134 width=18 height=14 xoffset=-4 yoffset=20 xadvance=11 page=0 chnl=0
char id=46 x=363 y=134 width=15 height=15 xoffset=-4 yoffset=25 xadvance=11 page=0 chnl=0
char id=47 x=83 y=102 width=17 height=32 xoffset=-4 yoffset=8 xadvance=9 page=0 chnl=0
char id=48 x=0 y=102 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=49 x=261 y=70 width=22 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=50 x=283 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=51 x=310 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=52 x=337 y=70 width=29 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=53 x=366 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=54 x=393 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=55 x=420 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=56 x=447 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=57 x=474 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=58 x=171 y=134 width=15 height=26 xoffset=-4 yoffset=14 xadvance=11 page=0 chnl=0
char id=59 x=68 y=102 width=15 height=32 xoffset=-4 yoffset=14 xadvance=11 page=0 chnl=0
char id=60 x=262 y=102 width=26 height=27 xoffset=-4 yoffset=11 xadvance=21 page=0 chnl=0
char id=61 x=238 y=134 width=26 height=22 xoffset=-4 yoffset=13 xadvance=21 page=0 chnl=0
char id=62 x=288 y=102 width=26 height=27 xoffset=-4 yoffset=11 xadvance=21 page=0 chnl=0
char id=63 x=42 y=102 width=26 height=32 xoffset=-4 yoffset=8 xadvance=20 page=0 chnl=0
char id=64 x=178 y=0 width=33 height=35 xoffset=-4 yoffset=8 xadvance=24 page=0 chnl=0
char id=65 x=244 y=0 width=33 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=66 x=277 y=0 width=30 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=67 x=307 y=0 width=30 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=68 x=337 y=0 width=30 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=69 x=367 y=0 width=28 height=32 xoffset=-4 yoffset=8 xadvance=23 page=0 chnl=0
char id=70 x=395 y=0 width=26 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=71 x=421 y=0 width=33 height=32 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=72 x=454 y=0 width=31 height=32 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=73 x=485 y=0 width=16 height=32 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=74 x=0 y=38 width=26 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=75 x=26 y=38 width=33 height=32 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=76 x=59 y=38 width=26 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=77 x=85 y=38 width=34 height=32 xoffset=-4 yoffset=8 xadvance=30 page=0 chnl=0
char id=78 x=119 y=38 width=31 height=32 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=79 x=150 y=38 width=33 height=32 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=80 x=183 y=38 width=27 height=32 xoffset=-4 yoffset=8 xadvance=23 page=0 chnl=0
char id=81 x=211 y=0 width=33 height=34 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=82 x=210 y=38 width=31 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=83 x=241 y=38 width=30 height=32 xoffset=-4 yoffset=8 xadvance=23 page=0 chnl=0
char id=84 x=271 y=38 width=30 height=32 xoffset=-4 yoffset=8 xadvance=23 page=0 chnl=0
char id=85 x=301 y=38 width=31 height=32 xoffset=-4 yoffset=8 xadvance=27 page=0 chnl=0
char id=86 x=332 y=38 width=33 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=87 x=365 y=38 width=41 height=32 xoffset=-4 yoffset=8 xadvance=32 page=0 chnl=0
char id=88 x=406 y=38 width=33 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=89 x=439 y=38 width=33 height=32 xoffset=-4 yoffset=8 xadvance=25 page=0 chnl=0
char id=90 x=472 y=38 width=29 height=32 xoffset=-4 yoffset=8 xadvance=23 page=0 chnl=0
char id=91 x=57 y=0 width=19 height=38 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=92 x=100 y=102 width=17 height=32 xoffset=-4 yoffset=8 xadvance=9 page=0 chnl=0
char id=93 x=76 y=0 width=19 height=38 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=94 x=212 y=134 width=26 height=22 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=95 x=412 y=134 width=25 height=11 xoffset=-4 yoffset=33 xadvance=16 page=0 chnl=0
char id=96 x=378 y=134 width=16 height=14 xoffset=-4 yoffset=8 xadvance=11 page=0 chnl=0
char id=97 x=314 y=102 width=26 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=98 x=0 y=70 width=26 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=99 x=340 y=102 width=26 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=100 x=26 y=70 width=26 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=101 x=366 y=102 width=27 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=102 x=52 y=70 width=21 height=32 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=103 x=73 y=70 width=26 height=32 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=104 x=99 y=70 width=25 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=105 x=124 y=70 width=15 height=32 xoffset=-4 yoffset=8 xadvance=11 page=0 chnl=0
char id=106 x=0 y=0 width=20 height=38 xoffset=-4 yoffset=8 xadvance=11 page=0 chnl=0
char id=107 x=139 y=70 width=27 height=32 xoffset=-4 yoffset=8 xadvance=21 page=0 chnl=0
char id=108 x=166 y=70 width=15 height=32 xoffset=-4 yoffset=8 xadvance=11 page=0 chnl=0
char id=109 x=393 y=102 width=37 height=26 xoffset=-4 yoffset=14 xadvance=32 page=0 chnl=0
char id=110 x=430 y=102 width=25 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=111 x=455 y=102 width=27 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=112 x=181 y=70 width=26 height=32 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=113 x=207 y=70 width=26 height=32 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=114 x=482 y=102 width=22 height=26 xoffset=-4 yoffset=14 xadvance=14 page=0 chnl=0
char id=115 x=0 y=134 width=27 height=26 xoffset=-4 yoffset=14 xadvance=20 page=0 chnl=0
char id=116 x=216 y=102 width=21 height=31 xoffset=-4 yoffset=9 xadvance=14 page=0 chnl=0
char id=117 x=27 y=134 width=25 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=118 x=52 y=134 width=27 height=26 xoffset=-4 yoffset=14 xadvance=20 page=0 chnl=0
char id=119 x=79 y=134 width=39 height=26 xoffset=-4 yoffset=14 xadvance=30 page=0 chnl=0
char id=120 x=118 y=134 width=29 height=26 xoffset=-4 yoffset=14 xadvance=21 page=0 chnl=0
char id=121 x=233 y=70 width=28 height=32 xoffset=-4 yoffset=14 xadvance=20 page=0 chnl=0
char id=122 x=147 y=134 width=24 height=26 xoffset=-4 yoffset=14 xadvance=18 page=0 chnl=0
char id=123 x=95 y=0 width=21 height=38 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=124 x=137 y=0 width=13 height=38 xoffset=-4 yoffset=8 xadvance=9 page=0 chnl=0
char id=125 x=116 y=0 width=21 height=38 xoffset=-4 yoffset=8 xadvance=12 page=0 chnl=0
char id=126 x=337 y=134 width=26 height=17 xoffset=-4 yoffset=15 xadvance=21 page=0 chnl=0
kernings count=241
kerning first=102 second=101 amount=-1
kerning first=76 second=89 amount=-2
kerning first=76 second=79 amount=-1
kerning first=80 second=65 amount=-3
kerning first=102 second=111 amount=-1
kerning first=86 second=97 amount=-1
kerning first=84 second=114 amount=-1
kerning first=119 second=44 amount=-2
kerning first=65 second=79 amount=-1
kerning first=86 second=67 amount=-1
kerning first=66 second=44 amount=1
kerning first=84 second=45 amount=-2
kerning first=80 second=46 amount=-6
kerning first=65 second=89 amount=-3
kerning first=67 second=46 amount=1
kerning first=112 second=119 amount=-1
kerning first=84 second=67 amount=-1
kerning first=84 second=58 amount=-1
kerning first=84 second=59 amount=-1
kerning first=114 second=113 amount=1
kerning first=102 second=63 amount=3
kerning first=80 second=111 amount=-1
kerning first=86 second=114 amount=-1
kerning first=89 second=67 amount=-2
kerning first=114 second=111 amount=1
kerning first=88 second=71 amount=-1
kerning first=80 second=101 amount=-1
kerning first=87 second=46 amount=-2
kerning first=75 second=117 amount=-1
kerning first=114 second=100 amount=1
kerning first=86 second=117 amount=-1
kerning first=87 second=79 amount=-1
kerning first=86 second=79 amount=-1
kerning first=81 second=86 amount=-1
kerning first=82 second=81 amount=-1
kerning first=115 second=119 amount=-1
kerning first=65 second=85 amount=-1
kerning first=68 second=87 amount=1
kerning first=112 second=46 amount=-1
kerning first=81 second=89 amount=-2
kerning first=114 second=97 amount=1
kerning first=84 second=97 amount=-2
kerning first=65 second=86 amount=-2
kerning first=84 second=99 amount=-2
kerning first=89 second=100 amount=-3
kerning first=102 second=102 amount=1
kerning first=114 second=103 amount=1
kerning first=87 second=104 amount=1
kerning first=86 second=105 amount=1
kerning first=114 second=106 amount=1
kerning first=74 second=111 amount=-1
kerning first=99 second=108 amount=-1
kerning first=84 second=109 amount=-1
kerning first=114 second=110 amount=2
kerning first=118 second=111 amount=-1
kerning first=89 second=112 amount=-2
kerning first=70 second=114 amount=-1
kerning first=97 second=116 amount=-1
kerning first=89 second=117 amount=-2
kerning first=76 second=119 amount=-1
kerning first=101 second=120 amount=-1
kerning first=99 second=121 amount=-1
kerning first=82 second=119 amount=1
kerning first=66 second=65 amount=-1
kerning first=81 second=84 amount=-1
kerning first=80 second=44 amount=-6
kerning first=97 second=103 amount=1
kerning first=111 second=120 amount=-1
kerning first=65 second=112 amount=1
kerning first=84 second=46 amount=-5
kerning first=86 second=101 amount=-2
kerning first=119 second=104 amount=1
kerning first=114 second=117 amount=1
kerning first=121 second=44 amount=-3
kerning first=121 second=46 amount=-3
kerning first=89 second=97 amount=-3
kerning first=75 second=101 amount=-1
kerning first=65 second=118 amount=-1
kerning first=70 second=97 amount=-1
kerning first=119 second=113 amount=-1
kerning first=75 second=111 amount=-1
kerning first=75 second=71 amount=-1
kerning first=87 second=97 amount=-1
kerning first=101 second=103 amount=1
kerning first=87 second=105 amount=1
kerning first=81 second=46 amount=1
kerning first=86 second=71 amount=-1
kerning first=67 second=44 amount=1
kerning first=114 second=99 amount=1
kerning first=70 second=44 amount=-5
kerning first=66 second=85 amount=-1
kerning first=76 second=86 amount=-2
kerning first=89 second=59 amount=-2
kerning first=84 second=44 amount=-5
kerning first=120 second=101 amount=-1
kerning first=108 second=121 amount=1
kerning first=89 second=101 amount=-3
kerning first=114 second=46 amount=-2
kerning first=121 second=99 amount=-1
kerning first=114 second=101 amount=1
kerning first=101 second=118 amount=-1
kerning first=81 second=44 amount=1
kerning first=74 second=121 amount=-1
kerning first=82 second=79 amount=-1
kerning first=89 second=113 amount=-3
kerning first=119 second=46 amount=-3
kerning first=68 second=89 amount=-1
kerning first=119 second=111 amount=-1
kerning first=102 second=46 amount=-2
kerning first=86 second=44 amount=-4
kerning first=114 second=109 amount=2
kerning first=79 second=89 amount=-2
kerning first=86 second=65 amount=-2
kerning first=103 second=114 amount=1
kerning first=102 second=33 amount=3
kerning first=84 second=122 amount=-1
kerning first=86 second=46 amount=-4
kerning first=70 second=101 amount=-1
kerning first=99 second=104 amount=-1
kerning first=89 second=44 amount=-5
kerning first=68 second=86 amount=-1
kerning first=88 second=79 amount=-1
kerning first=82 second=89 amount=-1
kerning first=75 second=67 amount=-1
kerning first=98 second=118 amount=-1
kerning first=89 second=65 amount=-3
kerning first=114 second=107 amount=1
kerning first=84 second=101 amount=-2
kerning first=89 second=79 amount=-2
kerning first=114 second=118 amount=2
kerning first=84 second=111 amount=-2
kerning first=120 second=111 amount=-1
kerning first=82 second=111 amount=-1
kerning first=79 second=87 amount=-1
kerning first=84 second=71 amount=-1
kerning first=118 second=100 amount=-1
kerning first=74 second=97 amount=-1
kerning first=89 second=45 amount=-3
kerning first=84 second=81 amount=-1
kerning first=114 second=115 amount=1
kerning first=68 second=46 amount=-1
kerning first=79 second=44 amount=-1
kerning first=121 second=100 amount=-1
kerning first=114 second=112 amount=1
kerning first=87 second=71 amount=-1
kerning first=89 second=83 amount=-1
kerning first=86 second=111 amount=-2
kerning first=87 second=111 amount=-1
kerning first=70 second=46 amount=-5
kerning first=81 second=65 amount=1
kerning first=114 second=58 amount=1
kerning first=84 second=104 amount=1
kerning first=114 second=116 amount=2
kerning first=87 second=101 amount=-1
kerning first=65 second=67 amount=-1
kerning first=70 second=65 amount=-3
kerning first=65 second=81 amount=-1
kerning first=118 second=46 amount=-3
kerning first=103 second=121 amount=1
kerning first=87 second=67 amount=-1
kerning first=74 second=46 amount=-1
kerning first=76 second=67 amount=-1
kerning first=75 second=79 amount=-1
kerning first=87 second=44 amount=-1
kerning first=89 second=58 amount=-2
kerning first=86 second=59 amount=-1
kerning first=114 second=121 amount=2
kerning first=121 second=97 amount=-1
kerning first=76 second=87 amount=-1
kerning first=118 second=44 amount=-3
kerning first=79 second=84 amount=-1
kerning first=111 second=119 amount=-1
kerning first=111 second=118 amount=-1
kerning first=84 second=108 amount=1
kerning first=82 second=117 amount=-1
kerning first=89 second=46 amount=-5
kerning first=111 second=122 amount=1
kerning first=84 second=65 amount=-2
kerning first=74 second=117 amount=-1
kerning first=107 second=111 amount=-1
kerning first=85 second=65 amount=-1
kerning first=111 second=121 amount=-1
kerning first=114 second=59 amount=1
kerning first=65 second=84 amount=-2
kerning first=89 second=118 amount=-1
kerning first=86 second=58 amount=-1
kerning first=87 second=100 amount=-1
kerning first=76 second=84 amount=-2
kerning first=102 second=32 amount=2
kerning first=111 second=46 amount=-1
kerning first=114 second=114 amount=1
kerning first=82 second=86 amount=-1
kerning first=74 second=44 amount=-1
kerning first=118 second=99 amount=-1
kerning first=86 second=81 amount=-1
kerning first=79 second=88 amount=-2
kerning first=85 second=44 amount=-1
kerning first=118 second=101 amount=-1
kerning first=88 second=67 amount=-1
kerning first=79 second=86 amount=-1
kerning first=75 second=118 amount=-1
kerning first=76 second=85 amount=-1
kerning first=107 second=101 amount=-1
kerning first=84 second=117 amount=-1
kerning first=120 second=99 amount=-1
kerning first=75 second=121 amount=-1
kerning first=84 second=115 amount=-2
kerning first=114 second=44 amount=-2
kerning first=82 second=71 amount=-1
kerning first=85 second=46 amount=-1
kerning first=70 second=111 amount=-1
kerning first=97 second=118 amount=-1
kerning first=121 second=111 amount=-1
kerning first=79 second=65 amount=-1
kerning first=82 second=101 amount=-1
kerning first=65 second=71 amount=-1
kerning first=102 second=44 amount=-2
kerning first=112 second=121 amount=-1
kerning first=74 second=101 amount=-1
kerning first=86 second=45 amount=-1
kerning first=121 second=101 amount=-1
kerning first=84 second=79 amount=-1
kerning first=89 second=111 amount=-3
kerning first=118 second=113 amount=-1
kerning first=74 second=65 amount=-1
kerning first=76 second=71 amount=-1
kerning first=79 second=46 amount=-1
kerning first=68 second=65 amount=-1
kerning first=114 second=108 amount=1
kerning first=71 second=44 amount=1
kerning first=110 second=118 amount=-1
kerning first=82 second=85 amount=-1
kerning first=87 second=117 amount=-1
kerning first=120 second=100 amount=-1
kerning first=80 second=97 amount=-1
kerning first=99 second=107 amount=-1
kerning first=66 second=46 amount=1
kerning first=89 second=71 amount=-2
kerning first=107 second=121 amount=1
kerning first=82 second=67 amount=-1
kerning first=84 second=121 amount=-1
https://i.imgur.com/ltrnufN.png
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment