UNPKG

9.91 kBJavaScriptView Raw
1/**
2* Sutton SignWriting TrueType Font Module v1.5.2 (https://github.com/sutton-signwriting/font-ttf)
3* Author: Steve Slevinski (https://SteveSlevinski.me)
4* font.js is released under the MIT License.
5*/
6
7(function (global, factory) {
8 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
9 typeof define === 'function' && define.amd ? define(['exports'], factory) :
10 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.ssw = global.ssw || {}, global.ssw.ttf = global.ssw.ttf || {}, global.ssw.ttf.font = {})));
11})(this, (function (exports) { 'use strict';
12
13 /**
14 * Function that appends font-face CSS for the Sutton SignWriting fonts for system installed fonts, relative directory fonts, or content delivery network
15 * @function font.cssAppend
16 * @param {string} dir - an optional relative directory for font location
17 * @example
18 * font.cssAppend('./font/')
19 */
20 const cssAppend = function (dir = '') {
21 const id = "SgnwFontCss";
22 if (!document.getElementById(id)) {
23 const style = document.createElement('style');
24 style.setAttribute("id", "SgnwFontCss");
25 style.appendChild(document.createTextNode(`
26 @font-face {
27 font-family: "SuttonSignWritingLine";
28 src:
29 local('SuttonSignWritingLine'),
30 ${dir ? `url('${dir}SuttonSignWritingLine.ttf') format('truetype'),` : ""}
31 url('https://cdn.jsdelivr.net/npm/@sutton-signwriting/font-ttf@1.0.0/font/SuttonSignWritingLine.ttf') format('truetype');
32 }
33 @font-face {
34 font-family: "SuttonSignWritingFill";
35 src:
36 local('SuttonSignWritingFill'),
37 ${dir ? `url('${dir}SuttonSignWritingFill.ttf') format('truetype'),` : ""}
38 url('https://cdn.jsdelivr.net/npm/@sutton-signwriting/font-ttf@1.0.0/font/SuttonSignWritingFill.ttf') format('truetype');
39 }
40 @font-face {
41 font-family: "SuttonSignWritingOneD";
42 src:
43 local('SuttonSignWritingOneD'),
44 ${dir ? `url('${dir}SuttonSignWritingOneD.ttf') format('truetype'),` : ""}
45 url('https://cdn.jsdelivr.net/npm/@sutton-signwriting/font-ttf@1.0.0/font/SuttonSignWritingOneD.ttf') format('truetype');
46 }
47 `));
48 document.head.appendChild(style);
49 }
50 };
51
52 let sizes = {};
53 const zoom = 2;
54 const bound = 76 * zoom;
55 let context;
56
57 /**
58 * Function that returns the size of a symbol using an id
59 * @function font.symbolSize
60 * @param {number} id - a 16-bit number of a symbol
61 * @returns {number[]} width and height of symbol
62 * @example
63 * font.symbolSize(1)
64 *
65 * return [15,30]
66 */
67 const symbolSize = function (id) {
68 if (id in sizes) {
69 return [...sizes[id]];
70 }
71 if (!context) {
72 const canvaser = document.createElement("canvas");
73 canvaser.width = bound;
74 canvaser.height = bound;
75 context = canvaser.getContext("2d", {
76 willReadFrequently: true
77 });
78 }
79 context.clearRect(0, 0, bound, bound);
80 context.font = 30 * zoom + "px 'SuttonSignWritingLine'";
81 context.fillText(String.fromCodePoint(id + 0xF0000), 0, 0);
82 const imgData = context.getImageData(0, 0, bound, bound).data;
83 let w, h, i, s;
84 wloop: for (w = bound - 1; w >= 0; w--) {
85 for (h = 0; h < bound; h += 1) {
86 for (s = 0; s < 4; s += 1) {
87 i = w * 4 + h * 4 * bound + s;
88 if (imgData[i]) {
89 break wloop;
90 }
91 }
92 }
93 }
94 var width = w;
95 hloop: for (h = bound - 1; h >= 0; h--) {
96 for (w = 0; w < width; w += 1) {
97 for (s = 0; s < 4; s += 1) {
98 i = w * 4 + h * 4 * bound + s;
99 if (imgData[i]) {
100 break hloop;
101 }
102 }
103 }
104 }
105 var height = h + 1;
106 width = Math.ceil(width / zoom);
107 height = Math.ceil(height / zoom);
108 // Rounding error in chrome. Manual fixes.
109 if (14394 == id) {
110 width = 19;
111 }
112 if ([10468, 10480, 10496, 10512, 10500, 10532, 10548, 10862, 10878, 10894, 11058, 11074, 11476, 11488, 11492, 11504, 11508, 11520, 10516, 10910, 10926, 11042, 11082, 10942].includes(id)) {
113 width = 20;
114 }
115 if (31921 == id) {
116 width = 22;
117 }
118 if (38460 == id) {
119 width = 23;
120 }
121 if ([20164, 20212].includes(id)) {
122 width = 25;
123 }
124 if (31894 == id) {
125 width = 28;
126 }
127 if (46698 == id) {
128 width = 29;
129 }
130 if (29606 == id) {
131 width = 30;
132 }
133 if (44855 == id) {
134 width = 40;
135 }
136 if (32667 == id) {
137 width = 50;
138 }
139 if ([11088, 11474, 11490, 11506].includes(id)) {
140 height = 20;
141 }
142 if (6285 == id) {
143 height = 21;
144 }
145 if (40804 == id) {
146 height = 31;
147 }
148 if (41475 == id) {
149 height = 36;
150 }
151 // Error in chrome. Manual fix.
152 // if (width==0 && height==0) {
153 if (width == 0 && height == 0) {
154 const sizefix = {
155 9: [15, 30],
156 10: [21, 30],
157 11: [30, 15],
158 12: [30, 21],
159 13: [15, 30],
160 14: [21, 30]
161 };
162 if (id in sizefix) {
163 width = sizefix[id][0];
164 height = sizefix[id][1];
165 }
166 }
167 if (width == 0 && height == 0) {
168 return undefined;
169 }
170 sizes[id] = [width, height];
171 return [width, height];
172 };
173
174 /**
175 * Function that returns a plane 15 character for a symbol line using an id
176 * @function font.symbolLine
177 * @param {number} id - a 16-bit number of a symbol
178 * @returns {string} character for symbol line
179 * @example
180 * font.symbolLine(1)
181 *
182 * return '󰀁'
183 */
184 const symbolLine = function (id) {
185 return String.fromCodePoint(id + 0xF0000);
186 };
187
188 /**
189 * Function that returns a plane 16 character for a symbol fill using an id
190 * @function font.symbolFill
191 * @param {number} id - a 16-bit number of a symbol
192 * @returns {string} character for symbol fill
193 * @example
194 * font.symbolFill(1)
195 *
196 * return '􀀁'
197 */
198 const symbolFill = function (id) {
199 return String.fromCodePoint(id + 0x100000);
200 };
201
202 /**
203 * Function that creates two text elements for a symbol using an id
204 * @function font.symbolText
205 * @param {number} id - a 16-bit number of a symbol
206 * @returns {string} SVG segment for line and fill
207 * @example
208 * font.symbolText(1)
209 *
210 * return ` <text class="sym-fill" fill="white" style="pointer-events:none;font-family:'SuttonSignWritingFill';font-size:30px;">􀀁</text>
211 * <text class="sym-line" fill="black" style="pointer-events:none;font-family:'SuttonSignWritingLine';font-size:30px;">󰀁</text>`
212 */
213 const symbolText = function (id) {
214 return ` <text class="sym-fill" fill="white" style="pointer-events:none;font-family:'SuttonSignWritingFill';font-size:30px;">${symbolFill(id)}</text>
215 <text class="sym-line" fill="black" style="pointer-events:none;font-family:'SuttonSignWritingLine';font-size:30px;">${symbolLine(id)}</text>`;
216 };
217
218 /**
219 * Function that executes a callback function once the Sutton SignWriiting Line and Fill fonts are ready to use
220 * @function font.cssLoaded
221 * @param {function} callback - a callback function to execute when fonts are ready
222 * @example
223 * const callback = () => {
224 * console.log("Sutton SignWriting Line and Fill fonts are ready to use")
225 * }
226 *
227 * font.cssLoaded( callback )
228 */
229 const cssLoaded = function (callback) {
230 let lineReady = false;
231 let fillReady = false;
232 cssLoadedLine(() => {
233 lineReady = true;
234 });
235 cssLoadedFill(() => {
236 fillReady = true;
237 });
238 const cssCheck = setInterval(function () {
239 if (lineReady && fillReady) {
240 clearInterval(cssCheck);
241 callback();
242 }
243 }, 100);
244 };
245
246 /**
247 * Function that executes a callback function once the Sutton SignWriiting Line font is ready to use
248 * @function font.cssLoadedLine
249 * @param {function} callback - a callback function to execute when line font is ready
250 * @example
251 * const callback = () => {
252 * console.log("Sutton SignWriting Line font is ready to use")
253 * }
254 *
255 * font.cssLoadedLine( callback )
256 */
257 const cssLoadedLine = function (callback) {
258 if (!symbolSize(1)) {
259 const cssCheck = setInterval(function () {
260 if (symbolSize(1)) {
261 clearInterval(cssCheck);
262 callback();
263 }
264 }, 100);
265 } else {
266 callback();
267 }
268 };
269
270 /**
271 * Function that executes a callback function once the Sutton SignWriiting Fill font is ready to use
272 * @function font.cssLoadedFill
273 * @param {function} callback - a callback function to execute when fill font is ready
274 * @example
275 * const callback = () => {
276 * console.log("Sutton SignWriting Fill font is ready to use")
277 * }
278 *
279 * font.cssLoadedFill( callback )
280 */
281 const cssLoadedFill = function (callback) {
282 const fillReady = function () {
283 const canvaser = document.createElement("canvas");
284 canvaser.width = 15;
285 canvaser.height = 30;
286 const context = canvaser.getContext("2d");
287 context.font = "30px 'SuttonSignWritingFill'";
288 context.fillText(symbolFill(1), 0, 0);
289 const imgData = context.getImageData(0, 0, 15, 30).data;
290 return !imgData.every(item => item === 0);
291 };
292 if (!fillReady()) {
293 const cssCheck = setInterval(function () {
294 if (fillReady()) {
295 clearInterval(cssCheck);
296 callback();
297 }
298 }, 100);
299 } else {
300 callback();
301 }
302 };
303
304 exports.cssAppend = cssAppend;
305 exports.cssLoaded = cssLoaded;
306 exports.cssLoadedFill = cssLoadedFill;
307 exports.cssLoadedLine = cssLoadedLine;
308 exports.symbolFill = symbolFill;
309 exports.symbolLine = symbolLine;
310 exports.symbolSize = symbolSize;
311 exports.symbolText = symbolText;
312
313 Object.defineProperty(exports, '__esModule', { value: true });
314
315}));
316
317/* support ongoing development on https://patreon.com/signwriting */