asciiblaster

- draw irc art in your web browser
git clone git://git.acid.vegas/asciiblaster.git
Log | Files | Refs | Archive | README

colorcode.js (15325B)

      1 !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var o;"undefined"!=typeof window?o=window:"undefined"!=typeof global?o=global:"undefined"!=typeof self&&(o=self),o.colorcode=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
      2 var colorcode = {};
      3 module.exports = colorcode;
      4 colorcode.to_json = require('./src/to_json');
      5 colorcode.from_json = require('./src/from_json');
      6 colorcode.style = require('./src/style');
      7 colorcode.to_canvas = require('./src/canvas');
      8 colorcode.color = require('./src/color');
      9 colorcode.font = require('./src/font');
     10 
     11 },{"./src/canvas":2,"./src/color":3,"./src/font":4,"./src/from_json":8,"./src/style":9,"./src/to_json":10}],2:[function(require,module,exports){
     12 var to_json = require('./to_json');
     13 var fontload = require('./font').load;
     14 var style = require('./style');
     15 var color = require('./color');
     16 
     17 // node-canvas
     18 var Canvas = require('canvas');
     19 if (typeof Image === "undefined") Image = Canvas.Image;
     20 
     21 var make_canvas = function(){
     22   if (typeof document === "undefined" && typeof Canvas !== "undefined")
     23     return new Canvas();
     24   else
     25     return document.createElement("canvas");
     26 }
     27 
     28 var canvas_tmp;
     29 
     30 var render_colorcode = function(json, canvas, font, opts){
     31 
     32   var cw = font.char_w
     33     , ch = font.char_h
     34     , ctx = canvas.getContext('2d')
     35     , canvas_tmp = canvas_tmp || make_canvas()
     36     , ctx_tmp = canvas_tmp.getContext("2d")
     37 
     38   var palette = color.palettes[opts.palette || style.palette];
     39   var bg = opts.bg || style.bg;
     40 
     41   canvas_tmp.width = cw;
     42   canvas_tmp.height = ch;
     43   
     44   canvas.width = json.w * cw;
     45   canvas.height = json.h * ch;
     46 
     47   // pre fill entire canvas with bg color
     48   // is this a good optimization?
     49   if (bg === color.transparent_index){
     50     // already cleared when resized above
     51     // canvas.clearRect(0,0, canvas.width,canvas.height);
     52   } else {
     53     ctx.fillStyle = palette[bg];
     54     ctx.fillRect(0,0, canvas.width,canvas.height);
     55   }
     56 
     57   for (var l=0; l<json.lines.length; l++){
     58     var line = json.lines[l];
     59     for (var c=0; c<line.length; c++){
     60       var char = line[c];
     61       var x = c * cw
     62       var y = l * ch
     63       
     64       // draw bg for this char if not already filled
     65       if (char.bg !== bg) {
     66         if (char.bg === color.transparent_index) {
     67             ctx.clearRect(x, y, cw, ch)
     68         } else { 
     69           ctx.fillStyle = palette[char.bg]
     70           ctx.fillRect(x, y, cw, ch);
     71         }
     72       }
     73 
     74       if (font.is_char_blank(char.value)) continue;
     75 
     76       // draw char in fg
     77       var fg = palette[char.fg]
     78       if (fg !== color.transparent){
     79         ctx_tmp.globalCompositeOperation = 'source-over'
     80         ctx_tmp.fillStyle = fg
     81         ctx_tmp.fillRect(0,0,cw,ch)
     82         ctx_tmp.globalCompositeOperation = 'destination-in'
     83         font.render_char(font, char.value, ctx_tmp, 0, 0, char)
     84         ctx.drawImage(canvas_tmp, x, y)
     85       } else { // transparent foreground punches out bg
     86         ctx.globalCompositeOperation = 'destination-out'
     87         font.render_char(font, char.value, ctx, x, y, char)
     88         ctx.globalCompositeOperation = 'source-over'
     89       }
     90 
     91     }
     92   }
     93 
     94   if (opts.done) opts.done(canvas)
     95 
     96 
     97 }
     98 
     99 var to_canvas = function(string_or_json, opts){
    100   opts = opts || {};
    101   
    102   if (typeof string_or_json === 'string')
    103     string_or_json = to_json(string_or_json, opts);
    104   
    105   var canvas = opts.canvas || make_canvas();
    106   var font_name = opts.font || style.font;
    107 
    108   fontload(font_name, function(font){ 
    109     render_colorcode(string_or_json, canvas, font, opts)
    110   });
    111 
    112   return canvas;
    113 }
    114 
    115 module.exports = to_canvas;
    116 
    117 },{"./color":3,"./font":4,"./style":9,"./to_json":10,"canvas":11}],3:[function(require,module,exports){
    118 var style = require('./style');
    119 
    120 var color = {};
    121 module.exports = color;
    122 
    123 style.palette = 'mirc';
    124 
    125 color.transparent_index = 99;
    126 color.transparent = 'rgba(0,0,0,0)';
    127 var ps = color.palettes = {};
    128 
    129 ps.mirc = [
    130  'rgb(255,255,255)'
    131 ,'rgb(0,0,0)'
    132 ,'rgb(0,0,127)'
    133 ,'rgb(0,147,0)'
    134 ,'rgb(255,0,0)'
    135 ,'rgb(127,0,0)'
    136 ,'rgb(156,0,156)'
    137 ,'rgb(252,127,0)'
    138 ,'rgb(255,255,0)'
    139 ,'rgb(0,252,0)'
    140 ,'rgb(0,147,147)'
    141 ,'rgb(0,255,255)'
    142 ,'rgb(0,0,252)'
    143 ,'rgb(255,0,255)'
    144 ,'rgb(127,127,127)'
    145 ,'rgb(210,210,210)'
    146 ];
    147 
    148 ps.winxp = [
    149  'rgb(255,255,255)'
    150 ,'rgb(0,0,0)'
    151 ,'rgb(0,0,128)'
    152 ,'rgb(0,128,0)'
    153 ,'rgb(255,0,0)'
    154 ,'rgb(128,0,0)'
    155 ,'rgb(128,0,128)'
    156 ,'rgb(255,128,0)'
    157 ,'rgb(255,255,0)'
    158 ,'rgb(0,255,0)'
    159 ,'rgb(0,128,128)'
    160 ,'rgb(0,255,255)'
    161 ,'rgb(0,0,255)'
    162 ,'rgb(255,0,255)'
    163 ,'rgb(128,128,128)'
    164 ,'rgb(192,192,192)'
    165 ];
    166 
    167 ps.vga = [
    168  'rgb(255,255,255)'
    169 ,'rgb(0,0,0)'
    170 ,'rgb(0,0,170)'
    171 ,'rgb(0,170,0)'
    172 ,'rgb(255,85,85)'
    173 ,'rgb(170,0,0)'
    174 ,'rgb(170,0,170)'
    175 ,'rgb(170,85,0)'
    176 ,'rgb(255,255,85)'
    177 ,'rgb(85,255,85)'
    178 ,'rgb(0,170,170)'
    179 ,'rgb(85,255,255)'
    180 ,'rgb(85,85,255)'
    181 ,'rgb(255,85,255)'
    182 ,'rgb(85,85,85)'
    183 ,'rgb(170,170,170)'
    184 ];
    185 
    186 ps.c64 = [
    187  'rgb(255,255,255)'
    188 ,'rgb(0,0,0)'
    189 ,'rgb(69,32,170)'
    190 ,'rgb(101,170,69)'
    191 ,'rgb(138,101,32)'
    192 ,'rgb(138,69,32)'
    193 ,'rgb(138,69,170)'
    194 ,'rgb(101,69,0)'
    195 ,'rgb(207,207,101)'
    196 ,'rgb(170,239,138)'
    197 ,'rgb(138,138,138)'
    198 ,'rgb(101,170,207)'
    199 ,'rgb(138,101,223)'	
    200 ,'rgb(207,138,101)'
    201 ,'rgb(69,69,69)'
    202 ,'rgb(170,170,170)'
    203 ];
    204 
    205 ps.appleii = [
    206  'rgb(255,255,255)' 
    207 ,'rgb(0,0,0)'
    208 ,'rgb(64,53,121)'
    209 ,'rgb(64,75,7)'
    210 ,'rgb(191,180,248)'
    211 ,'rgb(109,41,64)'
    212 ,'rgb(218,60,241)'
    213 ,'rgb(218,104,15)'
    214 ,'rgb(191,202,134)'
    215 ,'rgb(38,195,16)'
    216 ,'rgb(19,87,64)'
    217 ,'rgb(146,214,191)'
    218 ,'rgb(37,151,240)'
    219 ,'rgb(236,168,191)'
    220 ,'rgb(128,128,128)'
    221 ,'rgb(128,128,128)'
    222 ];
    223 
    224 
    225 },{"./style":9}],4:[function(require,module,exports){
    226 var __dirname="/src";var style = require('./style');
    227 // node-canvas
    228 var Canvas = require('canvas');
    229 if (typeof Image === "undefined") Image = Canvas.Image;
    230 
    231 var font = {};
    232 module.exports = font;
    233 
    234 // hack for loading fonts in node... todo, fix this
    235 font.img_path = "";
    236 if (typeof document === "undefined") font.img_path = __dirname + "/../examples/web/"
    237 
    238 
    239 font.list = {};
    240 
    241 var fsexps = require('./font/fixedsys');
    242 var cp437s = require('./font/cp437');
    243 for (f in fsexps) font.list[fsexps[f].name] = fsexps[f];
    244 for (f in cp437s) font.list[cp437s[f].name] = cp437s[f];
    245 
    246 style.font = 'fixedsys_8x16';
    247 
    248 var err_font_load = function(){
    249   console.log("couldn't load font")
    250 }
    251 
    252 
    253 font.load = function(font_name, callback_fn){
    254   if (!(font_name in font.list)) { return;} // todo error
    255   
    256   var f = font.list[font_name]
    257   
    258   if (f.loaded) {
    259     callback_fn(f);
    260   } else {
    261     f.sheet = new Image();
    262     f.sheet.crossOrigin = 'anonymous'
    263     // node-canvas doesn't have addEventListener :(
    264     f.sheet.onload = function(){
    265       f.loaded = true
    266       callback_fn(f);
    267     }
    268     f.sheet.src = font.img_path + f.sheet_url
    269 
    270   }
    271 }
    272 
    273 
    274 },{"./font/cp437":5,"./font/fixedsys":6,"./style":9,"canvas":11}],5:[function(require,module,exports){
    275 var cp437s = [[8,8],[8,12],[8,14],[8,16],[10,10],[10,16],[12,12],[16,16]]
    276 var fonts = {};
    277 module.exports = fonts;
    278 
    279 // utf8 -> cp437 function by sheetjs
    280 // edited from https://github.com/SheetJS/js-codepage/blob/master/bits/437.js
    281 var cp437 = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
    282 
    283 var render_char = function(font, char_value, ctx, ctx_x, ctx_y){
    284   char_value = cp437.enc[String.fromCharCode(char_value)] | 0;
    285   var sheet_x = (char_value % font.sheet_w_in_chars) * font.char_w
    286   var sheet_y = ((char_value / font.sheet_w_in_chars) |0) * font.char_h
    287   ctx.drawImage(font.sheet, 
    288                sheet_x|0, sheet_y|0, font.char_w, font.char_h,
    289                ctx_x|0, ctx_y|0, font.char_w, font.char_h)
    290 
    291 }
    292 
    293 for (var i=0, wh; wh=cp437s[i]; i++){
    294   var font = {};
    295   font.is_char_blank = require('../fontutil').is_char_blank;
    296   font.render_char = render_char;
    297   font.name = 'cp437_' + wh[0] + 'x' + wh[1];
    298   font.sheet_url = './img/' + font.name + '.png'
    299   font.sheet_w_in_chars = 16;
    300   font.char_w = wh[0]
    301   font.char_h = wh[1]
    302   fonts[font.name] = font;
    303 }
    304 
    305 
    306 
    307 // window.cp437 = cp437;
    308 
    309 },{"../fontutil":7}],6:[function(require,module,exports){
    310 var fsexps = [[8,16,0],[8,15,1],[8,8,5]]
    311 var fonts = {};
    312 module.exports = fonts;
    313 
    314 var render_char = function(font, char_value, ctx, ctx_x, ctx_y, char){
    315   var sheet_x = 0, sheet_y = 3;
    316   if (char_value >= 0x20 && char_value <= 0x7e){ // ascii
    317     sheet_x = (char_value - 0x20) * font.char_w_sheet
    318     if (char.i){ // italic
    319       sheet_y = 1 * font.char_h_sheet + 3
    320     }
    321  } else if (char_value >= 0x80 && char_value <= 0xff){ // latin-1
    322     sheet_x = (char_value - 0x80) * font.char_w_sheet; 
    323     sheet_y = 2 * font.char_h_sheet + 3
    324  } else if (char_value >= 0x0100 && char_value <= 0x017f){ // latin a
    325     sheet_x = (char_value - 0x0100) * font.char_w_sheet; 
    326     sheet_y = 3 * font.char_h_sheet + 3
    327  } else if (char_value >= 0x0180 && char_value <= 0x024f){ // latin b
    328     sheet_x = (char_value - 0x0180) * font.char_w_sheet; 
    329     sheet_y = 4 * font.char_h_sheet + 3
    330  } else if (char_value >= 0x2500 && char_value <= 0x25ff){ // geom
    331     sheet_x = (char_value - 0x2500) * font.char_w_sheet; 
    332     sheet_y = 5 * font.char_h_sheet + 3
    333   } else if (char_value >= 0x2600 && char_value <= 0x26ff){ // emoji
    334     sheet_x = (char_value - 0x2600) * font.char_w_sheet; 
    335     sheet_y = 6 * font.char_h_sheet + 3
    336   }
    337 
    338   // var sheet_x = (char_value % font.sheet_w_in_chars) * font.char_w
    339   // var sheet_y = ((char_value / font.sheet_w_in_chars) |0) * font.char_h + 3
    340   ctx.drawImage(font.sheet, 
    341                sheet_x|0, (sheet_y|0) + font.y_adj, font.char_w, font.char_h,
    342                ctx_x|0, ctx_y|0, font.char_w, font.char_h)
    343 
    344 }
    345 
    346 for (var i=0, wh; wh=fsexps[i]; i++){
    347   var font = {
    348     name: 'fixedsys_' + wh[0] + 'x' + wh[1],
    349     sheet_url: './img/fsex-simple.png',
    350     sheet_w_in_chars: 128,
    351     char_w_sheet: 8,
    352     char_h_sheet: 16,
    353     char_w: wh[0],
    354     char_h: wh[1],
    355     y_adj: wh[2],
    356     is_char_blank: require('../fontutil').is_char_blank,
    357     render_char: render_char
    358   }
    359   fonts[font.name] = font
    360 }
    361 },{"../fontutil":7}],7:[function(require,module,exports){
    362 var util = {};
    363 module.exports = util;
    364 
    365 util.is_char_blank = function(char_value){
    366   if (char_value === 32) return true;
    367 }
    368 
    369 util.render_char = function(font, char_value, ctx, ctx_x, ctx_y){
    370   var sheet_x = (char_value % font.sheet_w_in_chars) * font.char_w
    371   var sheet_y = ((char_value / font.sheet_w_in_chars) |0) * font.char_h
    372   ctx.drawImage(font.sheet, 
    373                sheet_x|0, sheet_y|0, font.char_w, font.char_h,
    374                ctx_x|0, ctx_y|0, font.char_w, font.char_h)
    375 
    376 }
    377 
    378 
    379 },{}],8:[function(require,module,exports){
    380 var char_color = '\x03';
    381 
    382 var make_colorcode_fgbg = function(fg, bg){
    383   // pad numbers: this prevents irc parsing confusion
    384   // when the character after the colorcode is a number
    385   if (fg < 10) fg = "0" + fg;
    386   if (bg < 10) bg = "0" + bg;
    387   return char_color + fg + "," + bg
    388 }
    389 
    390 var colorcode_from_json = function(json, opts){
    391   var out = "";
    392   for (var li=0, line; line=json.lines[li]; li++){
    393     for (var ci=0, char; char=line[ci]; ci++){
    394       out += make_colorcode_fgbg(char.fg, char.bg)
    395       out += String.fromCharCode(char.value)
    396     }   
    397     out += "\n";
    398   }
    399   return out;
    400 }
    401 
    402 
    403 module.exports = colorcode_from_json;
    404 
    405 },{}],9:[function(require,module,exports){
    406 // default settings for fonts, colors, etc
    407 var style = {};
    408 module.exports = style;
    409 
    410 },{}],10:[function(require,module,exports){
    411 var char_color = '\x03';
    412 var regexp_color = /(^[\d]{1,2})?(?:,([\d]{1,2}))?/;
    413 
    414 var style_chars = {
    415   '\x02': 'bold',
    416   '\x1d': 'italic',
    417   '\x1f': 'underline',
    418   '\x0f': 'reset',
    419   '\x16': 'inverse'
    420 };
    421 
    422 var Style = function(style){
    423   this.b = style.b;
    424   this.i = style.i;
    425   this.u = style.u;
    426   this.fg = style.fg;
    427   this.bg = style.bg;
    428 };
    429 
    430 var style_fns = {};
    431 
    432 style_fns.bold = function(style){ style.b = !style.b };
    433 
    434 style_fns.italic = function(style){ style.i = !style.i };
    435 
    436 style_fns.underline = function(style){ style.u = !style.u };
    437 
    438 style_fns.inverse = function(style){
    439   var tmp = style.fg;
    440   style.fg = style.bg;
    441   style.bg = tmp;
    442 };
    443 
    444 style_fns.reset = function(style, base_style){
    445   style.b =  base_style.b;
    446   style.i =  base_style.i;
    447   style.u =  base_style.u;
    448   style.fg = base_style.fg;
    449   style.bg = base_style.bg;
    450 };
    451 
    452 var colorcode_to_json = function(string, opts){
    453   // looks like its already converted
    454   if (typeof string === 'object' &&
    455       'lines' in string &&
    456       'w' in string &&
    457       'h' in string)
    458     return string;
    459  
    460 
    461   opts = opts || {};
    462   var d = colorcode_to_json.defaults;
    463 
    464   var base_style = {
    465     b:  "b" in opts ? opts.b : d.b,
    466     i:  "i" in opts ? opts.i : d.i,
    467     u:  "u" in opts ? opts.u : d.u,
    468     fg: "fg" in opts ? opts.fg : d.fg,
    469     bg: "bg" in opts ? opts.bg : d.bg
    470   };
    471 
    472   var lines_in = string.split(/\r?\n/);
    473   var lines_out = [];
    474   var w = 0, h = 0;
    475 
    476   for (var i=0; i<lines_in.length; i++){
    477     var line = lines_in[i];
    478     if (line.length === 0) continue; // skip blank lines
    479     var json_line = line_to_json(line, base_style);
    480     if (w < json_line.length) w = json_line.length;
    481     lines_out.push(json_line);
    482     h++;
    483   }
    484 
    485   return {w:w, h:h, lines:lines_out};
    486 };
    487 
    488 colorcode_to_json.defaults = {
    489   b: false
    490 , i: false
    491 , u: false
    492 , fg: 1
    493 , bg: 99
    494 };
    495 
    496 var line_to_json = function(line, base_style){
    497   var out = [];
    498   var pos = -1;
    499   var len = line.length -1;
    500   var char;
    501   var style = new Style(base_style); 
    502   
    503   while (pos < len){ pos++;
    504 
    505     char = line[pos];
    506     
    507     // next char is a styling char
    508     if (char in style_chars){
    509       style_fns[style_chars[char]](style, base_style);
    510       continue;
    511     }
    512 
    513     // next char is a color styling char, with possible color nums after
    514     if (char === char_color){
    515       var matches = line.substr(pos+1,5).match(regexp_color);
    516       
    517       // \x03 without color code is a soft style reset 
    518       if (matches[1] === undefined && matches[2] === undefined) {
    519         style.fg = base_style.fg;
    520         style.bg = base_style.bg;
    521         continue;
    522       }
    523 
    524       if (matches[1] !== undefined)
    525         style.fg = Number(matches[1]);
    526 
    527       if (matches[2] !== undefined)
    528         style.bg = Number(matches[2]);
    529 
    530       pos += matches[0].length;
    531       continue;
    532        
    533     }
    534 
    535     // otherwise, next char is treated as normal content
    536     var data = new Style(style);
    537     //data.value = char;
    538     data.value = char.charCodeAt(0);
    539 
    540     out.push(data);
    541   }
    542   return out;
    543 };
    544 
    545 module.exports = colorcode_to_json;
    546 
    547 },{}],11:[function(require,module,exports){
    548 
    549 },{}]},{},[1])
    550 (1)
    551 });