A bitmap font based text utility that can be used to print text to the screen.
I added two bitmap fonts (tiny/normal) based on some images in some own format.
The letter- and line spacing can be set in the constructor.
There's a function to iterate over the pixels of the font to do custom stuff with it, like the third text does.
Kinda follows same API as Hello, world
#text #font #utility
Log in to post a comment.
const turtle = new Turtle();
function walk(i) {
const text = new BitmapText(BitmapTextFonts.NORMAL);
turtle.jump(-40, -30)
text.print(turtle, "~ hello\nworld ~", 2, true,true);
const text2 = new BitmapText(BitmapTextFonts.SMALL, 4);
turtle.jump(-75, -70)
text2.print(turtle, "0123456789!", 2);
const text3 = new BitmapText(BitmapTextFonts.SMALL);
const startPos = [-60, 40];
text3.iter("~ hello world ~".toUpperCase(), pos => {
const scale = 2;
const p = [pos[0] * scale + startPos[0], pos[1] * scale + startPos[1]];
turtle.jump(p[0], p[1]);
turtle.circle(1.2);
turtle.jump(p[0], p[1]);
turtle.circle(1.0);
});
}
////////////////////////////////////////////////////////////////
// BitmapText utility code. Created by Mark Knol 2020
// https://turtletoy.net/turtle/48b904349d
////////////////////////////////////////////////////////////////
class BitmapText {
constructor(font, letterSpacing = 1, lineSpacing = 2) {
this.font = font;
this.letterSpacing = letterSpacing;
this.lineSpacing = lineSpacing;
// decode
const data = this.font.data;
this.bits = [];
let odd = true;
for(let ii=0; ii<data.length; ii++) {
for(let c=0;c<data.charCodeAt(ii) - 40; c++) {
this.bits.push(odd);
}
odd = !odd;
}
}
print(t, str, scale, diagonal1 = false, diagonal2 = false) {
const startPos = t.pos();
this.iter(str, pos => {
const a = [pos[0] * scale, pos[1] * scale];
const b = [(pos[0] + 1) * scale, (pos[1] + 1) * scale];
a[0] += startPos[0];
a[1] += startPos[1];
b[0] += startPos[0];
b[1] += startPos[1];
t.jump(a[0], a[1]);
t.goto(b[0], a[1]);
t.goto(b[0], b[1]);
t.goto(a[0], b[1]);
t.goto(a[0], a[1]);
if (diagonal1) t.goto(b[0], b[1]);
if (diagonal2) {
t.jump(a[0], b[1]);
t.goto(b[0], a[1]);
}
});
}
iter(str, cb) {
this.get(str).forEach(cb);
}
get(str) {
const positions = [];
let line = 0;
let offset = 0;
const cpl = this.font.charsPerLine;
for (let i=0; i<str.length; i++) {
if (str.charAt(i) == "\n") { line ++; offset = 0; continue; }
let char = str.charCodeAt(i) - 32; // start from space
if (char < 0 || char > 3 * 32) continue;
let drawPos = [offset++ * (this.font.size[0] + this.letterSpacing), line * (this.font.size[1] + this.lineSpacing)];
let charPos = [char % cpl * (this.font.size[0] + this.font.spacing[0]), Math.floor(char / cpl) * (this.font.size[1] + this.font.spacing[1])];
for (let y=0; y<this.font.size[1]; y++){
for (let x=0; x<this.font.size[0]; x++) {
let dotPos = [x, y];
if (this.bits[charPos[0] + dotPos[0] + (charPos[1] + dotPos[1]) * ((this.font.size[0] + this.font.spacing[0]) * cpl)]) {
positions.push([drawPos[0] + dotPos[0], drawPos[1] + dotPos[1]]);
}
}
}
}
return positions;
}
}
const BitmapTextFonts = {
// based on <https://robey.lag.net/2010/01/23/tiny-monospace-font.html>
SMALL: {
data: "(-)*)))))))**)),)+),)))+)))=+*)*+)+)))))+)+)+)+)+3)-)++.)*))))+)*,)))))*)+)+)+)+)8)))))*),)+)))))))+)-)))))))))*)+)+)*+*),).).)))***)+)/)+)*+)+-+.)*)))*)*+**)+)+)++))+)+1)1)*)6+)**)+))).)+)+)+)+)/)*)+)))*)*)-)+)+)))))+)))))+)*)+)+)*+*)3).)))*),)**/)))+)))-)0).+*)*+)++))+)++))+)+-)-)-),)«)+)**+*)**+)+**)))))++)))))))+)))))))*)**+)**+*)+)))))))))))))))))))))+)+-+*).)))))))))))))+)))))+)+)+)))*),)))))))++)+)))))))))))))))))),)*)))))))))))))))))))+)))+)-)))))-+)+)**)+))))+)+)+)+*),))**)++)+)))))**))))+*)+)*))))))))+*)+)+)*),),)1)+)))))))))+)))))+)+)))))))*)*)))))))))+))))+))))))++)*,)*)*)))*)*+))))*)*)+)-)+)2*)))))*+*)**+)),*)))))+*)*))))+))))))))*)*),*)))))*+)+**)*)))))))*)*+)+-+-+©)/)1)/)-),),)-*G)C**)**+*)+*).)1)***)+*))3),)7)+)*),*)+9))))+*)+)+)***+.*)*+***)))))+)+)*+),)))))*)*+)*+)*))))))))+)*+)*)))))))))))))))****))1)-+-)))))))))+))))*+),)))))*),))*+)*+)))))))))*+*)),**)*))))+)+*),))*+)+)+).+-+)*+******)***)))*)***))))+))))))))*)*)-)))+*+)+**)*+)))))**+***)**.+©",
size: [3,5],
spacing: [1,1],
charsPerLine: 32,
},
// based on <https://opengameart.org/content/ascii-bitmap-font-oldschool>
NORMAL: {
data: "(1)-))),)))-),*.+-)/),)X+-)5)-))),))),,***)*)*)-).).),))))),)E)*)+)+*5)3-*)))/)+)))4)0),+-)D)+)***)))5)4))),+-)-)5)0)+-*-1-3),))))),)5)3-,)))+)-)))))2)0),+-).);)-**),)B)))+,+)***)*)4).),))))),).):).)+),)5)4)))-)/*+*))4),)<)6)4++-ħ+,+-*+-+++-++,+O+,+,++,,++)+)*)+)+)))+).)2)*)+)*)+),).)/)3)-)+)*)+)*)+)*)+)*)+).).)*)*)+).)1)+)+)*)+):),-,),)+)*))+*)+)*)+)*)1)-*+-*,+,-)-+,,9)7).)+)))))*-*,+)0)0)-)/)*)+)+)-)+).)3).),-,).),))+*)+)*)+)*)/)-)+)-)/)*)+)+)-)+).),).)/)3)4).)+)*)+)*)+)*-++.)+,,+,).+,+3)D)-++)+)*,,+ħ,+-*-+++)+)*-*-*)+)*).)+)*)+)+++,,++,,,*-*)+)*)+)*).).)+)*)+),)0)*)+)*).*)**)+)*)+)*)+)*)+)*)+)*)0),)+)*)+)*).).).)+),)0)*)*)+).)))))***)*)+)*)+)*)+)*)+)*)0),)+)*)+)*,+,+).-,)0)*+,).)+)*)))))*)+)*,+)+)*,,+-),)+)*)+)*).).)***)+),)0)*)*)+).)+)*)***)+)*).)))))*)+).),),)+)*)+)*).).)+)*)+),),)+)*)+)*).)+)*)+)*)+)*).)*)+)+).),),)+)*,+-*)/++)+)*-+++)+)*-*)+)*)+)+++)/*))*)+)*,-)-+ħ)+)*)+)*)+)*)+)*-,*3*.)4)4)9)3*2)+)*)+)*)+)*)+).),),)0)-)))4)3)9)2)4)+)*)+)+))),))).)-)-)/)B++,,+,,+++-+,*)+)*)+),).).).).).)E)*)+)*)+)*)+)*)+)+)-)+)*)+)*)))))+)))-)-)/)/)-)B,*)+)*).)+)*-+).,+)))+*)**)+),),)0)0),)A)+)*)+)*)+)*)+)*)/)1),),)+)*)+),),-,*3*3-2,*,,+,,+,+).+ħ)0)0)*).)`)P)<).)`)P,++.+*)*)+).*))+,,++,,,*))*,,*,+)+)*)+)*)+)*)+)*)+)*)+),)0)*+,).)))))*)+)*)+)*)+)*)+)***)*)/)-)+)*)+)*)+)+)))+)+)*)+),)0)*)*)+).)))))*)+)*)+)*,,,*)/+,)-)+)*)+)*)+),)-,*)+),),)+)*)+)*).)+)*)+)*)+)*)2)*)2)+)*)*)+)+)))+)))))+)))/)*)+)*-+++)+)+++)+)*)+)+++)2)*).,-*,,,)-)))+)+)++ı)-)-)).).)-,).).)-)*)),)/)/)+))*).).).))/).).)--)-)-)Ƌ",
size: [5,7],
spacing: [2,2],
charsPerLine: 18,
}
}