# Prepare data for JS renderer

It's asked to write a script to generate a source data to feed a JavaScript renderer.

## JS Renderer documentation

The JS renderer is this script:

function o(x){
r=x.split(' ');
(d=document).write('<style>i{position:absolute;width:10;height:10;background:#000}</style>');
for(i=0;i<r.length;++i){c=r[i].split(',');d.write('<i style=top:'+(e=eval)(c[0])+';left:'+e(c[1])+'></i>')
}
}


It takes as input a list of X/Y coordinates separated by spaces and commas and prints on DOM the points as 10×10 pixel squares.

For example, if you call the script with:

o('0,0 10,0 20,0 30,0 40,0 20,10 20,20 0,30 10,30 20,30 30,30 40,30 0,50 10,50 20,50 30,50 40,50');


It will print:

Notice that the values can be expressed as calculations, so it will accept:

o('10*2,50/5');


Write a script that, given as input a string of characters ([A-Z0-9 ]; uppercase letters, numbers, spaces) prints on stdout the coordinates to feed the JS renderer.

### Rules

• The "line-height" of the characters should be of at least 50px
• Your script doesn't need to run the JS parser
• The expected output format is: x,y x,y x,y x,y
• The shortest code wins

Bonus: if you could reduce the length of the JS renderer without changing the behavior would be great :)

• Do the letters have to be all uppercase? or just readable? – Tobia Feb 11 '14 at 22:04
• all uppercase, I've made it clearer in the description. – Fez Vrasta Feb 11 '14 at 22:05
• Your rules say expected output is x,y but your code produces 'top:'+eval(cp[0])+';left:'+eval(cp[1]) which is the opposite. Which one is right? – Tobia Feb 11 '14 at 23:33
• Unhandled Error: Security error: attempted to read protected variable: i --> result of running your code on opera 12.16 on windows 8 pro 64bits. – Ismael Miguel Feb 12 '14 at 0:28
• It's a golfed code, it's normal that it throws warnings :) Tobia: x and y are just conventions, just follow the examples – Fez Vrasta Feb 12 '14 at 6:27

## Mathematica - 164 bytes

I'm happy to agree if you call this cheating, but it wasn't ruled out in the question. I let Mathematica rasterise the string and then throw away all white pixels and generate instructions from the rest:

 g=""<>MapIndexed[If[#<1,"",{h,w}=ToString/@(10#2);h<>","<>w<>""]&,ImageData@Rasterize[#,RasterSize->(n=5StringLength@#),ImageSize->n]/.{(1.)..}->0/.{_,_,_}->1,{2}]&


It could probably be golfed down even further. Especially the /.{(1.)..}->0/.{_,_,_}->1 looks suspiciously like it could be simplified.

Slightly ungolfed:

g[str_] := (
n = 5*StringLength[str];
pixels = ImageData[Rasterize[str, RasterSize->n, ImageSize->n]]
/. {1., 1., 1.} -> 0
/. {_, _, _} -> 1;
StringJoin[
MapIndexed[
If[#1 < 1,
"",
{h, w} = Map[ToString, 10*#2];
h <> "," <> w <> ""
] &,
pixels,
{2}
]
]
);


This will handle really any characters in the string, and you can tweak the size by adjusting the 5 (which means letters are 5 pixels wide, which meets your requirement of them being 50 actual pixels tall).

Here is some example output using a resolution of 7:

And here using a resolutiong of 9:

And 12:

(The screenshots are somewhat minified to fit SE's column width, of course.)

# APL, 196 chars

f←37 5 3⍴(555/2)⊤95x⊥32-⍨⎕UCS'ne,[9fkO!|UUmYb~qu"*5n2wJgBe1P~P+E)\$?ZGHb4{W(:edC2JdpirhX4I@m/K/q,ww <=:N%(euf9AJ"'
⎕←1↓∊{⍕¨' '⍺','⍵}/¨↑,/{10×(2↑4×⍵-1)∘+¨1-⍨a/⍥,⍳⍴a←⍉f[(' ',⎕A,∊⍕¨0,⍳9)⍳⍵⌷s;;]}¨⍳⍴s←⍞


Dialect is Nars2000.

The first line produces the font, which I took from this page. I've encoded it in base 95 as printable ASCII characters, so the first line decodes it and turns it into a 37×5×3 bitmap.

The second line reads a line of input. For each character it extracts the right bitmap from the font, produces a list of coordinates of the 'on' bits, adds an offset to the first coordinate (x) depending on the position in the string, multiplies by 10, formats the result as required, and outputs it.

Here is the output for HELLO WORLD 9

0,0 0,10 0,20 0,30 0,40 10,20 20,0 20,10 20,20 20,30 20,40 40,0 40,10 40,20 40,30 40,40 50,0 50,20 50,40 60,0 60,20 60,40 80,0 80,10 80,20 80,30 80,40 90,40 100,40 120,0 120,10 120,20 120,30 120,40 130,40 140,40 160,10 160,20 160,30 170,0 170,40 180,10 180,20 180,30 240,0 240,10 240,20 240,30 240,40 250,30 260,0 260,10 260,20 260,30 260,40 280,10 280,20 280,30 290,0 290,40 300,10 300,20 300,30 320,0 320,10 320,20 320,30 320,40 330,0 330,20 330,30 340,10 340,20 340,40 360,0 360,10 360,20 360,30 360,40 370,40 380,40 400,0 400,10 400,20 400,30 400,40 410,0 410,40 420,10 420,20 420,30 480,0 480,10 480,20 480,40 490,0 490,20 490,40 500,0 500,10 500,20 500,30 500,40


And here it is turned into an image:

It could probably be golfed a bit more here and there, but the main gain would come from a smarter font encoding.

I can explain the code in more detail if anyone asks.

• I'm sorry to give bad news but it shows 90º rotated clock-wise and horizontally inverted. Other than that, it looks awesome – Ismael Miguel Feb 12 '14 at 0:45
• @IsmaelMiguel Yeah, I posted a comment earlier on the question above. His rules tell to output x,y, but his demo code reads the numbers as y,x. I chose to go with the rules and flipped cp[0] and cp[1] to take the screenshot. But in case it turns out to be y,x, I'll just have to flip one symbol in my code. – Tobia Feb 12 '14 at 1:37
• I made an "improved" version of the code and it prints perfectly using the example he gave. MAYBE you should do like in the example. And add a comment to the code, regarding this issue. This is my opinion, you are free to go ahead and do what you want. The only thing is that he is using it in Javascript and the result looks perfect except for that tiny difference I told in the last comment. But other than that, you did a nice work. – Ismael Miguel Feb 12 '14 at 1:51

# Javascript (E6) 274

(261 function + 13 console output)

Not so short, but any font, any size, any character

F=(m,f="50",F="Georgia")=>{d=1024;e=document.createElement("canvas");c=e.getContext("2d");e.height=e.width=d;c.font=f+"px "+F;c.fillText(m,0,f);
i=c.getImageData(0,0,d,d).data;q='';for(p=d*d*4;p;p-=4)i[p-1]&&(q+=(p>>12)+'0,'+((p>>2)&(d-1))+'0 ');return q.trim()}


Ungolfed

function F(m, f="50", F="Georgia") {
d = 1024
e = document.createElement("canvas")
c = e.getContext("2d")
e.height = e.width=d
c.font = f + "px " + F
c.fillText(m,0,f);
i = c.getImageData(0,0,d,d).data;
q=''
for (p = d*d*4; p; p-=4)
i[p-1] && (q += (p >> 12)+'0,'+((p>>2) & (d-1))+'0 ');
return q.trim()
}


Usage

console.log(F('HELLO WORLD'))

console.log(F('Bonjour, monde',30,'Garamond'))

# JavScript 278

Slightly smaller renderer.

function o(x){
(d=document).write('<style>i{position:absolute;width:10;height:10;background:#000}</style>');
var r=/([^ ]+),([^ ]+)/g,e=eval
while((m=r.exec(x)))d.write('<i style=top:'+e(m[1])+'px;left:'+e(m[2])+'px></i>')
}


JavaScript that writes coords to console.

function a(s) {
r=''
c=document.createElement('canvas')
c.width=c.height=w=40
t=c.getContext("2d")
t.fillText(s,0,8)
d=t.getImageData(0,0,w,w).data
x=y=0
for(p=3;p<6400;p+=4)x%=w,y+=x++?0:1,r+=d[p]>9?y+'*10,'+x+'*10 ':''
return r
}
var coords = a('TEST 9');
console.log(coords);

• this is not what it's asked – Fez Vrasta Feb 14 '14 at 19:44