-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
150 lines (122 loc) · 3.87 KB
/
index.js
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
147
148
149
150
var Base = require('fontpath-simple-renderer')
var inherits = require('inherits')
var bmfont2fontpath = require('fontpath-bmfont')
var texcoord = require('texcoord')
var xtend = require('xtend')
var createTexture = require('gl-texture2d')
var Batch = require('gl-sprite-batch')
var tmpPos = [0, 0],
tmpShape = [0, 0],
tmp1 = [0, 0],
tmp2 = [0, 0]
var DEFAULT_TEXCOORD = [0, 0, 1, 1]
var maxInitialCapacity = 500
function texcoordGlyph(glyph, atlas, out) {
tmp1[0] = glyph.x
tmp1[1] = glyph.y
tmp2[0] = glyph.width
tmp2[1] = glyph.height
return texcoord(tmp1, tmp2, atlas, out)
}
function TextRenderer(gl, opt) {
if (!(this instanceof TextRenderer))
return new TextRenderer(gl, opt)
opt = opt||{}
if (!opt.font)
throw new Error('must specify bmfont at creation time')
//if the font has Image/ndarray array
if (!opt.textures && Array.isArray(opt.font.images)) {
opt.textures = opt.font.images.map(function(img) {
return createTexture(gl, img)
})
}
opt.font = bmfont2fontpath(opt.font)
Base.call(this, opt)
this.textures = opt.textures || []
this.gl = gl
if (!gl)
throw new Error("must specify gl context")
//assume text will be used dynamically
if (typeof opt.dynamic !== 'boolean')
opt.dynamic = true
var batch = opt.batch
if (!batch)
this.defaultBatch = Batch(gl, opt)
this.batch = batch || this.defaultBatch
if (typeof opt.wrapWidth !== 'number')
this.layout()
}
inherits(TextRenderer, Base)
TextRenderer.prototype.dispose = function(textures) {
if (this.defaultBatch)
this.defaultBatch.dispose()
if (textures) {
this.textures.forEach(function(t) {
if (typeof t.dispose === 'function')
t.dispose()
})
}
return this
}
TextRenderer.prototype.uncache = function() {
this._cache = false
this.batch.clear()
return this
}
TextRenderer.prototype.cache = function(x, y, start, end) {
// if (this.underline || this.font.pages.length > 1)
// throw new Error('currently cached text does not support underlines or multiple texture pages')
this._cache = true
this.batch.ensureCapacity(this.text.length)
this.batch.clear()
this._build(x, y, start, end)
return this
}
TextRenderer.prototype.draw = function(shader, x, y, start, end) {
var batch = this.batch
batch.bind(shader)
//if we're drawing dynamically
if (!this._cache) {
batch.clear()
this._build(x, y, start, end)
}
batch.draw()
batch.unbind()
return this
}
TextRenderer.prototype._build = function(x, y, start, end) {
var result = this.render(x, y, start, end)
var batch = this.batch
var i = 0
//underlines currently not supported with cache()
if (!this._cache) {
batch.texcoord = DEFAULT_TEXCOORD
batch.texture = null
for (i = 0; i < result.underlines.length; i++) {
var underline = result.underlines[i]
batch.position = underline.position
batch.shape = underline.size
batch.push()
}
}
//now draw our glyphs into the batch...
for (i = 0; i < result.glyphs.length; i++) {
var g = result.glyphs[i]
this._drawGlyph(batch, g)
}
}
TextRenderer.prototype._drawGlyph = function(batch, data) {
//... we could sort these by texture page to reduce draws
var glyph = data.glyph
var img = this.textures[glyph.page]
tmpPos[0] = data.position[0]+glyph.hbx
tmpPos[1] = data.position[1]+glyph.hby - this.font.descender
tmpShape[0] = glyph.width * data.scale[0]
tmpShape[1] = glyph.height * data.scale[1]
batch.texture = img
texcoordGlyph(glyph, img && img.shape, batch.texcoord)
batch.position = tmpPos
batch.shape = tmpShape
batch.push()
}
module.exports = TextRenderer