Skip to content

Instantly share code, notes, and snippets.

@hwei
Last active September 29, 2015 02:18
Show Gist options
  • Save hwei/9e318860174eac9fc809 to your computer and use it in GitHub Desktop.
Save hwei/9e318860174eac9fc809 to your computer and use it in GitHub Desktop.
Signed Distance Field Font Tools
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define STBI_ONLY_PNG
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
double double_round (double v)
{
double floor_value;
floor_value = floor (v);
return (v > floor_value + 0.5) ? ceil (v) : floor_value;
}
int main (int argc, char *argv[])
{
int width, height, comp;
unsigned char *data;
int max_distance;
unsigned char *mask_outter_data;
unsigned char *mask_inner_data;
unsigned char *new_data;
unsigned char *p0, *p1, *p2;
int mask_width;
int i, j, k, l, w, h, s0, e0, s1, e1;
double d;
double max_distance_1;
unsigned char v, t;
max_distance = strtol (argv[3], NULL, 10);
mask_width = max_distance + max_distance + 1;
mask_outter_data = (unsigned char *) malloc (mask_width * mask_width);
max_distance_1 = (double) (max_distance + 1);
for (i = 0; i < mask_width; ++i)
{
p0 = mask_outter_data + i * mask_width;
for (j = 0; j < mask_width; ++j)
{
w = i - max_distance;
h = j - max_distance;
d = min (sqrt ((double) (w * w + h * h)), max_distance_1);
p0[j] = (unsigned char) double_round (128.0 * d / max_distance_1);
}
}
mask_inner_data = (unsigned char *) malloc (mask_width * mask_width);
for (i = 0; i < mask_width; ++i)
{
p0 = mask_inner_data + i * mask_width;
for (j = 0; j < mask_width; ++j)
{
w = i - max_distance;
h = j - max_distance;
d = max (0, min (sqrt ((double) (w * w + h * h)) - 1.0, max_distance));
p0[j] = (unsigned char) double_round (127.0 * d / max_distance_1);
}
}
data = stbi_load (argv[1], &width, &height, &comp, 1);
new_data = malloc (width * height);
for (i = 0; i < height; ++i)
{
p0 = data + i * width;
p2 = new_data + i * width;
for (j = 0; j < width; ++j)
{
v = p0[j];
s0 = max (i - max_distance, 0);
e0 = min (i + max_distance + 1, height);
if (v < 128)
{ // black
t = 128;
for (k = s0; k < e0; ++k)
{
s1 = max (j - max_distance, 0);
e1 = min (j + max_distance + 1, width);
p1 = data + k * width;
for (l = s1; l < e1; ++l)
{
if (p1[l] >= 128)
t = min (t, mask_outter_data[(k - s0) * mask_width + l - s1]);
}
}
p2[j] = 128 - t;
}
else
{ // white
t = 127;
for (k = s0; k < e0; ++k)
{
s1 = max (j - max_distance, 0);
e1 = min (j + max_distance + 1, width);
p1 = data + k * width;
for (l = s1; l < e1; ++l)
{
if (p1[l] < 128)
t = min (t, mask_inner_data[(k - s0) * mask_width + l - s1]);
}
}
p2[j] = t + 128;
}
}
}
stbi_write_png (argv[2], width, height, comp, new_data, width * sizeof (unsigned char));
stbi_image_free (data);
free (mask_outter_data);
free (mask_inner_data);
free (new_data);
return 0;
}
Shader "Custom/distance_field" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Sharpen ("Sharpen", Float) = 2
}
SubShader {
Tags { "RenderType"="Transparent" "Queue"="Overlay" "IgnoreProjector"="True" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
half4 _MainTex_ST;
half _Sharpen;
struct appdata {
half4 vertex : POSITION;
half4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert (appdata i) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
o.uv = TRANSFORM_TEX(i.texcoord, _MainTex);
o.color = i.color;
return o;
}
fixed4 frag(v2f i) : COLOR {
fixed4 c = tex2D(_MainTex, i.uv) * i.color;
return fixed4 (c.rgb, (c.a - 0.5) * _Sharpen +0.5);
}
ENDCG
}
}
FallBack "Unlit/Transparent"
}
// generate chars settings for Bitmap font generator
var chars = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~的一是了我不人在他有这个上们来到时大地为子中你说生国年着就那和要她出也得里后自以会家可下而过天去能对小多然于心学么之都好看起发当没成只如事把还用第样道想作种开见明问力理尔点文几定本公特做外孩相西果走将月十实向声车全信重三机工物气每并别真打太新比才便夫再书部水像眼等体却加电主界门利海受听表德少克代员许稜先口由死安写性马光白或住难望教命花结乐色更拉东神记处让母父应直字场平报友关放至张认接告入笑内英军候民岁往何度山觉路带万男边风解叫任金快原吃妈变通师立象数四失满战远格士音轻目条呢病始达深完今提求清王化空业思切怎非找片罗钱紶吗语元喜曾离飞科言干流欢约各即指合反题必该论交终林请医晚制球决窢传画保读运及则房早院量苦火布品近坐产答星精视五连司巴奇管类未朋且婚台夜青北队久乎越观落尽形影红爸百令周吧识步希亚术留市半热送兴造谈容极随演收首根讲整式取照办强石古华諣拿计您装似足双妻尼转诉米称丽客南领节衣站黑刻统断福城故历惊脸选包紧争另建维绝树系伤示愿持千史谁准联妇纪基买志静阿诗独复痛消社算算义竟确酒需单治卡幸兰念举仅钟怕共毛句息功官待究跟穿室易游程号居考突皮哪费倒价图具刚脑永歌响商礼细专黄块脚味灵改据般破引食仍存众注笔甚某沉血备习校默务土微娘须试怀料调广蜖苏显赛查密议底列富梦错座参八除跑亮假印设线温虽掉京初养香停际致阳纸李纳验助激够严证帝饭忘趣支春集丈木研班普导顿睡展跳获艺六波察群皇段急庭创区奥器谢弟店否害草排背止组州朝封睛板角况曲馆育忙质河续哥呼若推境遇雨标姐充围案伦护冷警贝著雪索剧啊船险烟依斗值帮汉慢佛肯闻唱沙局伯族低玩资屋击速顾泪洲团圣旁堂兵七露园牛哭旅街劳型烈姑陈莫鱼异抱宝权鲁简态级票怪寻杀律胜份汽右洋范床舞秘午登楼贵吸责例追较职属渐左录丝牙党继托赶章智冲叶胡吉卖坚喝肉遗救修松临藏担戏善卫药悲敢靠伊村戴词森耳差短祖云规窗散迷油旧适乡架恩投弹铁博雷府压超负勒杂醒洗采毫嘴毕九冰既状乱景席珍童顶派素脱农疑练野按犯拍征坏骨余承置臓彩灯巨琴免环姆暗换技翻束增忍餐洛塞缺忆判欧层付阵玛批岛项狗休懂武革良恶恋委拥娜妙探呀营退摇弄桌熟诺宣银势奖宫忽套康供优课鸟喊降夏困刘罪亡鞋健模败伴守挥鲜财孤枪禁恐伙杰迹妹藸遍盖副坦牌江顺秋萨菜划授归浪听凡预奶雄升碃编典袋莱含盛济蒙棋端腿招释介烧误“”。,、‘’【】《》~*…·×÷!?";
var o = "";
for(var i = 0, j = 16; i < chars.length; ++i, ++j) {
if (j == 16) {o += "chars="; j = 0}
o+=chars.charCodeAt(i);
if (j==15) o+='\n'; else o+=',';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment