Niro* by cho45

#16 The JavaScript Philosophy

  1. Small is beautiful.
  2. Make each snippet do one thing well.
  3. Build a prototype as soon as possible.
  4. Choose portability over efficiency.
  5. Store data in plain object.
  6. Use software leverage to your advantage.
  7. Use callback to increase leverage and portability.
  8. Avoid captive user interfaces.
  9. Make every snippet independent.

Mike Gancarz: The UNIX Philosophy

[[javascript]]

#15 DSi browser hacks

You may often write javascript for DSi browser so I do. I have some knowledge for it.

How to change the cursor.

You may try 'cursor: default' CSS but DSi browser ignores it.

But you can change to default cursor by 'position: absolute'.

How to show caret on input area.

You can show caret on input area by using JavaScirpt focus() function, and press 'A' button to input \n.

When focus event is fired.

It is fired *after* inputting text.

Keyboard events that you are able to handle.

  • 'A' key events are always fired.
  • Pressing 'L' key or 'R' key, ↑↓←→ key events are fired.
    • But page is fixed (that is cannot be scrolled), ↑↓ key events are fired without 'L' or 'R'.

That's all.

And some information:

  • keyup event is not fired, only keypress and keydown event are fired.
  • Pressing continuously, keydown events are fired many times.

HTML canvas on DSi browser

You cannot use drawImage() function. It is callable but unusable.

Color's low 4bits are cutoffed. For Example, if you specified #FFFFFF as fillStyle and call fillRect, drawing color is #F0F0F0 actually. And that this rule is also applied to alpha channel, more properly, #FFFFFF is treat as rgba(240, 240, 240, 0.94). So you can exactly not draw true white color.

#14 Irssi web interface Irssw

I wrote new web interface of irssi which is an IRC client. I wanted a good IRC web interface on smartphones (Android or iPhone) but it isn't.

Install and Run

  1. Copy rpc.pl to ~/.irssi/scripts/auto
    • And once run "/script load auto/rpc" in irssi
  2. Copy app.conf.sample to app.conf and edit it
    • You must change the password
  3. Run HTTPD: perl script/server.pl -p 9876
  4. Access http://server:9876/

Design

This is mainly designed for Android (especialy "poor" Android, HT-03A). So Irssw has following features:

  • Save memory
  • Full Ajax (for UI performance)
  • Unread management integrated to irssi
  • Post current location (This is just the icing on the cake)

Enjoy.

#13 clearLine function on HTML Canvas

HTML5 canvas API does not have clearLine which clear (transparent) by line.

#12 BDF font rederrer in JavaScript

Wrote a BDF (Bitmap Description Format) rederer in JavaScript. BDF is easy to handle by JS because it is just text file.

This only depends on following:

  • Canvas element and 2D context
  • fillRect() function

Code:

function BDFFont () { this.init.apply(this, arguments) };
BDFFont.prototype = {
	init : function (bdf) {
		var self = this;
		self.glyphs = {};
		self.properties = {};
		self.parse(bdf);
	},

	parse : function (bdf) {
		var self = this;
		var lines = bdf.split(/\n/);

		var glyph = null, properties = null;
		for (var i = 0, len = lines.length; i < len; i++) {
			var line = lines[i];

			if (glyph) {
				if (line != 'ENDCHAR') {
					if (!glyph['BITMAP']) {
						var d = line.split(' ');
						switch (d[0]) {
							case 'ENCODING':
								glyph['ENCODING'] = +d[1];
								break;
							case 'SWIDTH':
								glyph['SWIDTH'] = {
									x: +d[1],
									y: +d[2]
								};
								break;
							case 'DWIDTH':
								glyph['DWIDTH'] = {
									x: +d[1],
									y: +d[2]
								};
								break;
							case 'BBX':
								glyph['BBw']  = +d[1];
								glyph['BBh']  = +d[2];
								glyph['BBox'] = +d[3];
								glyph['BBoy'] = +d[4];
								break;
							case 'ATTRIBUTES':
								break;
							case 'BITMAP':
								glyph['BITMAP'] = [];
								break;
						}
					} else {
						glyph['BITMAP'].bits = line.length * 4;
						glyph['BITMAP'].push(parseInt(line, 16));
					}
				} else {
					self.glyphs[glyph['ENCODING']] = glyph;
					glyph = null;
				}
			} else if (properties) {
				if (line != 'ENDPROPERTIES') {
					var d = line.split(' ', 2);
					properties[ d[0] ] = (d[1][0] == '"') ? d[1].substring(1, d[1].length - 2): +d[1];
				} else {
					self.properties = properties;
					properties = null;
				}
			} else {
				var d = line.split(' ');
				switch (d[0]) {
					case 'COMMENT': break;
					case 'FONT':
						self['FONT'] = d[1];
						break;
					case 'SIZE':
						self['SIZE'] = {
							size : +d[1],
							xres : +d[2],
							yres : +d[3]
						};
						break;
					case 'FONTBOUNDINGBOX':
						self['FONTBOUNDINGBOX'] = {
							w : +d[1],
							h : +d[2],
							x : +d[3],
							y : +d[4]
						};
						break;
					case 'STARTPROPERTIES':
						properties = {};
						break;
					case 'CHARS':
						self['CHARS'] = +d[1];
						break;
					case 'STARTCHAR':
						glyph = {};
					case 'ENDCHAR':
						break;
				}
			}
		}
	},

	drawChar : function (ctx, c, bx, by, t) {
		var self = this;
		var g = self.glyphs[ c ] || self.glyphs[ self.properties['DEFAULT_CHAR'] ];
		if (t) {
			var f = function () {};
			f.prototype = g;
			g = new f();
			g = t(g);
		};
		var n = g['BBw'];
		var b = g['BITMAP'];
		var ox = bx + g['BBox'] - 1;
		var oy = by - g['BBoy'] - g['BBh'] + 1;
		for (var y = 0, len = b.length; y < len; y++) {
			var l = b[y];
			for (var i = b.bits, x = 0; i >= 0; i--, x++) {
				if (l >> i & 0x01 == 1) {
					ctx.fillRect(ox + x, oy + y, 1, 1);
				}
			}
		}
		return { x: bx + g['DWIDTH'].x, y : by + g['DWIDTH'].y };
	},

	drawText : function (ctx, text, x, y, t) {
		var self = this;
		for (var i = 0, len = text.length; i < len; i++) {
			var c = text[i].charCodeAt(0);
			var r = self.drawChar(ctx, c, x, y, t);
			x = r.x; y = r.y;
		}
		return { x: x, y: y };
	},

	drawEdgeText : function (ctx, text, x, y, t) {
		var self = this;
		self.drawText(ctx, text, x, y, function (g) {
			var bitmap =  new Array(g['BITMAP'].length + 2);
			bitmap.bits = g['BITMAP'].bits + 2;
			for (var i = -1, len = bitmap.length; i < len; i++) {
				bitmap[i+1] = g['BITMAP'][i]   | g['BITMAP'][i]   >> 1 | g['BITMAP'][i]   >> 2 |
				              g['BITMAP'][i+1] | g['BITMAP'][i+1] >> 1 | g['BITMAP'][i+1] >> 2 |
				              g['BITMAP'][i-1] | g['BITMAP'][i-1] >> 1 | g['BITMAP'][i-1] >> 2 ;
			}
			g['BITMAP'] = bitmap;
			g['BBox']  += -3;
			g['BBoy']  +=  1;
			return g;
		});
	}
};
login