UNPKG

9.87 kBJavaScriptView Raw
1/**
2* Sutton SignWriting TrueType Font Module v1.4.3 (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 }
77 context.clearRect(0, 0, bound, bound);
78 context.font = 30 * zoom + "px 'SuttonSignWritingLine'";
79 context.fillText(String.fromCodePoint(id + 0xF0000), 0, 0);
80 const imgData = context.getImageData(0, 0, bound, bound).data;
81 let w, h, i, s;
82 wloop: for (w = bound - 1; w >= 0; w--) {
83 for (h = 0; h < bound; h += 1) {
84 for (s = 0; s < 4; s += 1) {
85 i = w * 4 + h * 4 * bound + s;
86 if (imgData[i]) {
87 break wloop;
88 }
89 }
90 }
91 }
92 var width = w;
93 hloop: for (h = bound - 1; h >= 0; h--) {
94 for (w = 0; w < width; w += 1) {
95 for (s = 0; s < 4; s += 1) {
96 i = w * 4 + h * 4 * bound + s;
97 if (imgData[i]) {
98 break hloop;
99 }
100 }
101 }
102 }
103 var height = h + 1;
104 width = Math.ceil(width / zoom);
105 height = Math.ceil(height / zoom);
106 // Rounding error in chrome. Manual fixes.
107 if (14394 == id) {
108 width = 19;
109 }
110 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)) {
111 width = 20;
112 }
113 if (31921 == id) {
114 width = 22;
115 }
116 if (38460 == id) {
117 width = 23;
118 }
119 if ([20164, 20212].includes(id)) {
120 width = 25;
121 }
122 if (31894 == id) {
123 width = 28;
124 }
125 if (46698 == id) {
126 width = 29;
127 }
128 if (29606 == id) {
129 width = 30;
130 }
131 if (44855 == id) {
132 width = 40;
133 }
134 if (32667 == id) {
135 width = 50;
136 }
137 if ([11088, 11474, 11490, 11506].includes(id)) {
138 height = 20;
139 }
140 if (6285 == id) {
141 height = 21;
142 }
143 if (40804 == id) {
144 height = 31;
145 }
146 if (41475 == id) {
147 height = 36;
148 }
149 // Error in chrome. Manual fix.
150 // if (width==0 && height==0) {
151 if (width == 0 && height == 0) {
152 const sizefix = {
153 9: [15, 30],
154 10: [21, 30],
155 11: [30, 15],
156 12: [30, 21],
157 13: [15, 30],
158 14: [21, 30]
159 };
160 if (id in sizefix) {
161 width = sizefix[id][0];
162 height = sizefix[id][1];
163 }
164 }
165 if (width == 0 && height == 0) {
166 return undefined;
167 }
168 sizes[id] = [width, height];
169 return [width, height];
170 };
171
172 /**
173 * Function that returns a plane 15 character for a symbol line using an id
174 * @function font.symbolLine
175 * @param {number} id - a 16-bit number of a symbol
176 * @returns {string} character for symbol line
177 * @example
178 * font.symbolLine(1)
179 *
180 * return '󰀁'
181 */
182 const symbolLine = function (id) {
183 return String.fromCodePoint(id + 0xF0000);
184 };
185
186 /**
187 * Function that returns a plane 16 character for a symbol fill using an id
188 * @function font.symbolFill
189 * @param {number} id - a 16-bit number of a symbol
190 * @returns {string} character for symbol fill
191 * @example
192 * font.symbolFill(1)
193 *
194 * return '􀀁'
195 */
196 const symbolFill = function (id) {
197 return String.fromCodePoint(id + 0x100000);
198 };
199
200 /**
201 * Function that creates two text elements for a symbol using an id
202 * @function font.symbolText
203 * @param {number} id - a 16-bit number of a symbol
204 * @returns {string} SVG segment for line and fill
205 * @example
206 * font.symbolText(1)
207 *
208 * return ` <text class="sym-fill" fill="white" style="pointer-events:none;font-family:'SuttonSignWritingFill';font-size:30px;">􀀁</text>
209 * <text class="sym-line" fill="black" style="pointer-events:none;font-family:'SuttonSignWritingLine';font-size:30px;">󰀁</text>`
210 */
211 const symbolText = function (id) {
212 return ` <text class="sym-fill" fill="white" style="pointer-events:none;font-family:'SuttonSignWritingFill';font-size:30px;">${symbolFill(id)}</text>
213 <text class="sym-line" fill="black" style="pointer-events:none;font-family:'SuttonSignWritingLine';font-size:30px;">${symbolLine(id)}</text>`;
214 };
215
216 /**
217 * Function that executes a callback function once the Sutton SignWriiting Line and Fill fonts are ready to use
218 * @function font.cssLoaded
219 * @param {function} callback - a callback function to execute when fonts are ready
220 * @example
221 * const callback = () => {
222 * console.log("Sutton SignWriting Line and Fill fonts are ready to use")
223 * }
224 *
225 * font.cssLoaded( callback )
226 */
227 const cssLoaded = function (callback) {
228 let lineReady = false;
229 let fillReady = false;
230 cssLoadedLine(() => {
231 lineReady = true;
232 });
233 cssLoadedFill(() => {
234 fillReady = true;
235 });
236 const cssCheck = setInterval(function () {
237 if (lineReady && fillReady) {
238 clearInterval(cssCheck);
239 callback();
240 }
241 }, 100);
242 };
243
244 /**
245 * Function that executes a callback function once the Sutton SignWriiting Line font is ready to use
246 * @function font.cssLoadedLine
247 * @param {function} callback - a callback function to execute when line font is ready
248 * @example
249 * const callback = () => {
250 * console.log("Sutton SignWriting Line font is ready to use")
251 * }
252 *
253 * font.cssLoadedLine( callback )
254 */
255 const cssLoadedLine = function (callback) {
256 if (!symbolSize(1)) {
257 const cssCheck = setInterval(function () {
258 if (symbolSize(1)) {
259 clearInterval(cssCheck);
260 callback();
261 }
262 }, 100);
263 } else {
264 callback();
265 }
266 };
267
268 /**
269 * Function that executes a callback function once the Sutton SignWriiting Fill font is ready to use
270 * @function font.cssLoadedFill
271 * @param {function} callback - a callback function to execute when fill font is ready
272 * @example
273 * const callback = () => {
274 * console.log("Sutton SignWriting Fill font is ready to use")
275 * }
276 *
277 * font.cssLoadedFill( callback )
278 */
279 const cssLoadedFill = function (callback) {
280 const fillReady = function () {
281 const canvaser = document.createElement("canvas");
282 canvaser.width = 15;
283 canvaser.height = 30;
284 const context = canvaser.getContext("2d");
285 context.font = "30px 'SuttonSignWritingFill'";
286 context.fillText(symbolFill(1), 0, 0);
287 const imgData = context.getImageData(0, 0, 15, 30).data;
288 return !imgData.every(item => item === 0);
289 };
290 if (!fillReady()) {
291 const cssCheck = setInterval(function () {
292 if (fillReady()) {
293 clearInterval(cssCheck);
294 callback();
295 }
296 }, 100);
297 } else {
298 callback();
299 }
300 };
301
302 exports.cssAppend = cssAppend;
303 exports.cssLoaded = cssLoaded;
304 exports.cssLoadedFill = cssLoadedFill;
305 exports.cssLoadedLine = cssLoadedLine;
306 exports.symbolFill = symbolFill;
307 exports.symbolLine = symbolLine;
308 exports.symbolSize = symbolSize;
309 exports.symbolText = symbolText;
310
311 Object.defineProperty(exports, '__esModule', { value: true });
312
313}));
314
315/* support ongoing development on https://patreon.com/signwriting */