// p5 viewer for JSON generated by shx_batch_decode.py. const currentFontName = "ROMANT"; /* // Choose one of the following font names (without .json extension) to load: ARCHITXT BVFONT Cdm CIBT____ CIMPLEX COBT____ DIN DINS exthalf2 extslim2 g12f13 gbeitc GENISO HAND HANDLETR HANDLTR hbold HELV ISO ISO8 isocp isoct ISOEQ ISOS ITENCIL KXT LANDLET MICRO monotxt MSIMPLEX romanc romand romans ROMANS8 ROMANT SCRIPTS8 simpfrac simplex STENCIL TICRO TIMESBD txt 2 txt UNIVCL X-HAND1F */ let shxJson; let glyphsByChar = {}; const SAMPLE_TEXT = [ "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", "0123456789 Hello World", ".,:;!?\"'#$%&@+-=*/<>_()[]{}\u2264\u221e\u2205" ].join("\n"); function preload() { shxJson = loadJSON("json/" + currentFontName + ".json"); } function setup() { createCanvas(1600, 480); pixelDensity(3); glyphsByChar = buildGlyphMap(shxJson); } function draw() { background(0); stroke(255); strokeWeight(1.0); strokeJoin(ROUND); strokeCap(ROUND); noFill(); drawString(SAMPLE_TEXT, 90,136, 52, 1.0, 1.6); } function keyPressed() { if (key === "s" || key === "S") { saveCanvas("autocad_shx_font_" + currentFontName, "png"); } } //-------------------------------------------------- function buildGlyphMap(data) { const map = {}; for (const glyph of data.glyphs || []) { if (glyph.unicode) { map[glyph.unicode] = glyph; } } return map; } function drawString(str, x, y, size, spacing = 1.0, lineHeight = 1.35) { const capHeight = shxJson.metrics?.normalized_cap_height || 21; const fontScale = shxJson.scale || shxJson.metrics?.normalized_scale || 1; const sca = size / capHeight * fontScale; let cx = x; let cy = y; for (const ch of Array.from(str)) { if (ch === "\n") { cx = x; cy += size * lineHeight; continue; } const glyph = glyphsByChar[ch]; if (glyph) { drawGlyph(glyph, cx, cy, sca); cx += (glyph.advance_width || 19) * sca * spacing; } else { cx += 19 * sca * spacing; } } } function drawGlyph(glyph, gx, gy, sca) { for (const path of glyph.decoded_stroke_geometry || []) { if (!path.length) continue; beginShape(); for (const cmd of path) { if (cmd.type === "M" || cmd.type === "L") { vertex(gx + cmd.x * sca, gy - cmd.y * sca); } else if (cmd.type === "C") { bezierVertex( gx + cmd.x1 * sca, gy - cmd.y1 * sca, gx + cmd.x2 * sca, gy - cmd.y2 * sca, gx + cmd.x * sca, gy - cmd.y * sca ); } } endShape(); } }