-
Notifications
You must be signed in to change notification settings - Fork 230
/
Copy pathglyph-texture-atlas-maker.html
122 lines (108 loc) · 3.26 KB
/
glyph-texture-atlas-maker.html
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
<!-- Licensed under a BSD license. See license.html for license -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Make Glyph Texture Atlas</title>
<link type="text/css" href="resources/webgl-tutorials.css" rel="stylesheet" />
<style>
* {
box-sizing: border-box;
}
#ui {
width: 200px;
}
</style>
</head>
<body>
</body>
<script src="resources/webgl-utils.js"></script>
<script src="resources/webgl-lessons-helper.js"></script>
<script>
"use strict";
function saveProperties(obj) {
var props = {};
Object.keys(obj).forEach(function(key) {
var desc = Object.getOwnPropertyDescriptor(obj, key);
// only save writable properties
if (desc.writable) {
props[key] = obj[key];
}
});
return props;
}
function restoreProperties(props, obj) {
Object.keys(props).forEach(function(key) {
obj[key] = props[key];
});
}
function makeGlyphCanvas(ctx, maxWidthOfTexture, heightOfLetters, baseLine, padding, letters) {
var rows = 1; // number of rows of glyphs
var x = 0; // x position in texture to draw next glyph
var y = 0; // y position in texture to draw next glyph
var glyphInfos = { // info for each glyph
};
// Go through each letter, measure it, remember its width and position
for (var ii = 0; ii < letters.length; ++ii) {
var letter = letters[ii];
var t = ctx.measureText(letter);
// Will this letter fit on this row?
if (x + t.width + padding > maxWidthOfTexture) {
// so move to the start of the next row
x = 0;
y += heightOfLetters;
++rows;
}
// Remember the data for this letter
glyphInfos[letter] = {
x: x,
y: y,
width: t.width,
};
// advance to space for next letter.
x += t.width + padding;
}
// Now that we know the size we need set the size of the canvas
// We have to save the canvas settings because changing the size
// of a canvas resets all the settings
var settings = saveProperties(ctx);
ctx.canvas.width = (rows == 1) ? x : maxWidthOfTexture;
ctx.canvas.height = rows * heightOfLetters;
restoreProperties(settings, ctx);
// Draw the letters into the canvas
for (var ii = 0; ii < letters.length; ++ii) {
var letter = letters[ii];
var glyphInfo = glyphInfos[letter];
var t = ctx.fillText(letter, glyphInfo.x, glyphInfo.y + baseLine);
}
return glyphInfos;
}
function main() {
var ctx = document.createElement("canvas").getContext("2d");
document.body.insertBefore(ctx.canvas, document.body.firstChild);
ctx.font = "20px sans-serif";
ctx.fillStyle = "white";
var maxTextureWidth = 256;
var letterHeight = 22;
var baseline = 16;
var padding = 1;
var letters = "0123456789.,abcdefghijklmnopqrstuvwxyz";
var glyphInfos = makeGlyphCanvas(
ctx,
maxTextureWidth,
letterHeight,
baseline,
padding,
letters);
// To make it clear lets draw a rect for each glyph
ctx.globalCompositeOperation = "destination-over";
Object.keys(glyphInfos).forEach(function(letter, ndx) {
var glyphInfo = glyphInfos[letter];
ctx.fillStyle = ndx % 2 ? "red" : "green";
ctx.fillRect(glyphInfo.x, glyphInfo.y, glyphInfo.width, letterHeight);
});
}
main();
</script>
</html>