|
101 | 101 | <td>Font array name:</td><td><input placeholder="Font array name" type="text" id="name" value="My_Font"/></td>
|
102 | 102 | <td width="75%" rowspan="5">
|
103 | 103 | <textarea id="inputText" placeholder="Or paste a char array font definition here">
|
104 |
| -const char My_Font[] PROGMEM = { |
| 104 | +const uint8_t My_Font[] PROGMEM = { |
105 | 105 | 0x0A, // Width: 10
|
106 | 106 | 0x0D, // Height: 13
|
107 | 107 | 0x01, // First char: 1
|
|
128 | 128 | <td colspan="3"> </td> <!--slightly improves layout-->
|
129 | 129 | </tr>
|
130 | 130 | <tr>
|
131 |
| - <td colspan="2"><button id="create">Create</button> <button id="generate">Generate</button> <button id="savetoFile">Save To File</button> </td> |
| 131 | + <td colspan="2"> |
| 132 | + <button id="create">Create</button> |
| 133 | + <button id="shiftUp">Shift all up</button> |
| 134 | + <button id="generate">Generate</button> |
| 135 | + <button id="savetoFile">Save To File</button> |
| 136 | + </td> |
132 | 137 | <td><input type="file" id="fileinput" /> <button id="parse">Parse</button></td>
|
133 | 138 | </tr>
|
134 | 139 | </table>
|
|
288 | 293 | // Read from the <td> css class the pixels that need to be on
|
289 | 294 | // generates the jump table and font data
|
290 | 295 | generate() {
|
| 296 | + // this.width -= 3; // hack to narrow an existing font |
291 | 297 | Font.emptyOutput();
|
292 | 298 | let chars = this.fontContainer.getElementsByTagName('table');
|
293 | 299 | let firstCharCode = parseInt(document.getElementById('code').value);
|
|
306 | 312 | let charBytes = [];
|
307 | 313 | let charCode = ch + firstCharCode;
|
308 | 314 | let rows = chars[ch].getElementsByTagName('tr');
|
309 |
| - let notZero = false; |
| 315 | + let charNotZero = false; |
310 | 316 | // Browse each column
|
311 | 317 | for(let col = 0; col < this.width ; col++) {
|
312 | 318 | let bits = ""; // using string because js uses 32b ints when performing bit operations
|
|
328 | 334 | //Font.output('data', ` // ${bits.substr(b-7, 8)}`); // Debugging help: rotated bitmap
|
329 | 335 | let byte = parseInt(bits.substr(b-7, 8), 2);
|
330 | 336 | if (byte !== 0) {
|
331 |
| - notZero = true; |
| 337 | + charNotZero = true; |
332 | 338 | }
|
333 | 339 | charBytes.push(Font.toHexString(byte));
|
334 | 340 | }
|
335 | 341 | }
|
336 |
| - // Remove bytes with value 0 at the end of the array. |
337 |
| - while(parseInt(charBytes[charBytes.length-1]) === 0 && charBytes.length !== 1) { |
| 342 | + // Compute the used width of the character: |
| 343 | + // rightmost column with pixels plus one |
| 344 | + // one column is spread over several bytes... |
| 345 | + let charWidth = 0; |
| 346 | + for(let i=charBytes.length - 1; i >= 0; i-=this.bytesForHeight) { |
| 347 | + let sum = 0; |
| 348 | + for(let j=0; j < this.bytesForHeight; j++) { |
| 349 | + sum += parseInt(charBytes[i - j], 16); |
| 350 | + } |
| 351 | + if(sum !== 0) { |
| 352 | + charWidth = (i + 1)/this.bytesForHeight + 1; |
| 353 | + break; |
| 354 | + } |
| 355 | + } |
| 356 | + |
| 357 | + // Memory optim: Remove bytes with value 0 at the end of the array. |
| 358 | + while(parseInt(charBytes[charBytes.length-1], 16) === 0 && charBytes.length > 1) { |
338 | 359 | charBytes.pop();
|
339 | 360 | }
|
340 |
| - |
341 |
| - if (notZero) { |
| 361 | + if (charNotZero) { |
342 | 362 | Font.output('data', ` ${charBytes.join(', ')}, // ${charCode}`);
|
343 |
| - // TODO: last param width is not the best value. Need to compute the actual occupied width |
344 |
| - Font.output('jump', ` ${Font.getMsB(charAddr)}, ${Font.getLsB(charAddr)}, ${Font.toHexString(charBytes.length)}, ${Font.toHexString(this.width)}, // ${charCode} `); |
| 363 | + Font.output('jump', ` ${Font.getMsB(charAddr)}, ${Font.getLsB(charAddr)}, ${Font.toHexString(charBytes.length)}, ${Font.toHexString(charWidth)}, // ${charCode} `); |
345 | 364 | charAddr += charBytes.length;
|
346 | 365 | } else {
|
347 | 366 | Font.output('jump', ` 0xFF, 0xFF, 0x00, ${Font.toHexString(this.width)}, // ${charCode} `);
|
|
350 | 369 | Font.output('data', '};');
|
351 | 370 |
|
352 | 371 | Font.output('header', "// Font generated or edited with the glyphEditor");
|
353 |
| - Font.output('header', `const char ${name}[] PROGMEM = {`); |
| 372 | + Font.output('header', `const uint8_t ${name}[] PROGMEM = {`); |
354 | 373 | // Comments are used when parsing back a generated font
|
355 | 374 | Font.output('header', ` ${Font.toHexString(this.width)}, // Width: ${this.width}`);
|
356 | 375 | Font.output('header', ` ${Font.toHexString(this.height)}, // Height: ${this.height}`);
|
|
383 | 402 | font.saveFile();
|
384 | 403 | });
|
385 | 404 |
|
| 405 | + document.getElementById('shiftUp').addEventListener('click', function() { |
| 406 | + var chars = document.getElementById("chars"); |
| 407 | + var tables = chars.getElementsByTagName("table"); |
| 408 | + for(var i=0; i< tables.length; i++) { |
| 409 | + shiftUp(tables[i]); |
| 410 | + } |
| 411 | + }); |
| 412 | + |
386 | 413 | document.getElementById('generate').addEventListener('click', function() {
|
387 | 414 | font.generate();
|
388 | 415 | });
|
|
462 | 489 |
|
463 | 490 | // Shift pixels up
|
464 | 491 | case 'up':
|
465 |
| - pixels = currentContainer.getElementsByTagName('td'); |
466 |
| - for(p = 0; p < pixels.length; p++) { |
467 |
| - if(p < font.width*(font.height -1)) { |
468 |
| - pixels[p].className = pixels[p + font.width].className; |
469 |
| - } else { |
470 |
| - pixels[p].className = ''; |
471 |
| - } |
472 |
| - } |
| 492 | + shiftUp(currentContainer); |
473 | 493 | break;
|
474 | 494 |
|
475 | 495 | case 'toggle':
|
|
502 | 522 | }
|
503 | 523 |
|
504 | 524 | });
|
| 525 | + function shiftUp(container) { |
| 526 | + var pixels = container.getElementsByTagName('td'); |
| 527 | + for(p = 0; p < pixels.length; p++) { |
| 528 | + if(p < font.width*(font.height -1)) { |
| 529 | + pixels[p].className = pixels[p + font.width].className; |
| 530 | + } else { |
| 531 | + pixels[p].className = ''; |
| 532 | + } |
| 533 | + } |
| 534 | + } |
| 535 | + |
505 | 536 | document.getElementById('chars').addEventListener('mouseover', function(e) {
|
506 | 537 | let target = e.target;
|
507 | 538 | let action = target.getAttribute('action');
|
|
0 commit comments