1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
define(function(require, exports, module){
module.exports = function generateSDFCache(font){
vec4[] buf = vec4[]()
buf.quad.length = font.count
buf.length = 0
var font_size = .2
var width = 2048
var height = 2048
var margin = 8. / width
var glyphs = font.glyphs
var left = -1 + 0.03
var top = -1 + font_size
var px = left
var py = 1
var o = 0
var maxh = 0
var ct = 0
for(var k in glyphs){
var info = glyphs[k]
// 0___14
var gx = ((info.atlas_x<<6) | info.nominal_w)<<1
var gy = ((info.atlas_y<<6) | info.nominal_h)<<1
var o = buf.quad.length++
buf.quad_tl[o] = vec4(info.tmin_x = px, info.tmin_y = py, gx, gy)
buf.quad_tr[o] = vec4(info.tmax_x = px + font_size * info.width, py, gx|1, gy)
buf.quad_bl[o] = vec4(px, info.tmax_y = py - font_size * info.height, gx, gy|1)
buf.quad_br[o] = vec4(px + font_size * info.width, py - font_size * info.height, gx|1, gy|1)
px += (info.tmax_x - info.tmin_x) + margin
var my_h = (info.tmin_y - info.tmax_y) + margin
if(my_h > maxh) maxh = my_h
info.tmin_x = info.tmin_x *.5 + .5
info.tmin_y = info.tmin_y *.5 + .5
info.tmax_x = info.tmax_x *.5 + .5
info.tmax_y = info.tmax_y *.5 + .5
if(px + font_size > 1) px = left, py -= maxh, maxh = 0
}
genWhitespace(font)
sdf_texture = Texture.rgba(width, height)
sdf_mesh = buf
font.sdf_texture = sdf_texture
if(dump_sdf){
mymesh = vec2Rect(0,0,1,1)
vertex: mymesh[]*vec2(8.,8.) * (m_mesh * m_world * device.m_camera)
pixel: sdf_texture.sample(pixel mymesh[])
}
glyphy_coords: sdf_mesh[].zw
if(sdf_bake){
var header = 12 + font.count * 10 * 4
var body = sdf_texture.w_ * sdf_texture.h_ * 4
var data = new Uint8Array(header + body)
var vuint32 = new Uint32Array(data.buffer)
var vfloat32 = new Float32Array(data.buffer)
var vuint16 = new Uint16Array(data.buffer)
var off = 0
vuint32[off++] = 0x02F01175
vuint16[2] = sdf_texture.w_
vuint16[3] = sdf_texture.h_
off++
vuint32[off++] = font.count
var glyphs = font.glyphs
var check = 0
for(var unicode in glyphs){
var info = glyphs[unicode]
check++
vuint32[off++] = unicode
vfloat32[off++] = info.min_x
vfloat32[off++] = info.min_y
vfloat32[off++] = info.max_x
vfloat32[off++] = info.max_y
vfloat32[off++] = info.advance
vfloat32[off++] = info.tmin_x
vfloat32[off++] = info.tmin_y
vfloat32[off++] = info.tmax_x
vfloat32[off++] = info.tmax_y
}
data._t_ = 1
sdf_header = data
sdf_header_offset = header
once:(){
sdf_texture{
clearAll(#black)
this{
vertex:sdf_mesh[].xy
pixel: glyphy_sdf_generate(pixel sdf_mesh[])
}
var data = sdf_header.subarray(sdf_header_offset)
this.gl.readPixels(0,0,sdf_texture.w, sdf_texture.h, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data)
console.log(sdf_texture.w, sdf_texture.h)
var xhr = new XMLHttpRequest()
xhr.open("POST", "/bake", false)
xhr.send(sdf_header)
}
}
}
else{
once:(){
sdf_texture{
clearAll(#black)
this{
vertex:sdf_mesh[].xy
pixel: glyphy_sdf_generate(pixel sdf_mesh[])
}
}
}
}
}
}) |