| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 | var CHAR_TILDE = 126;var CODE_FNC1 = 102;var SET_STARTA = 103;var SET_STARTB = 104;var SET_STARTC = 105;var SET_SHIFT = 98;var SET_CODEA = 101;var SET_CODEB = 100;var SET_STOP = 106;var REPLACE_CODES = {	CHAR_TILDE: CODE_FNC1 //~ corresponds to FNC1 in GS1-128 standard}var CODESET = {	ANY: 1,	AB: 2,	A: 3,	B: 4,	C: 5};function getBytes(str) {	var bytes = [];	for (var i = 0; i < str.length; i++) {		bytes.push(str.charCodeAt(i));	}	return bytes;}exports.code128 = function(ctx, text, width, height) {	width = parseInt(width);	height = parseInt(height);	var codes = stringToCode128(text);	var g = new Graphics(ctx, width, height);	var barWeight = g.area.width / ((codes.length - 3) * 11 + 35);	var x = g.area.left;	var y = g.area.top;	for (var i = 0; i < codes.length; i++) {		var c = codes[i];		//two bars at a time: 1 black and 1 white		for (var bar = 0; bar < 8; bar += 2) {			var barW = PATTERNS[c][bar] * barWeight;			// var barH = height - y - this.border;			var barH = height - y;			var spcW = PATTERNS[c][bar + 1] * barWeight;			//no need to draw if 0 width			if (barW > 0) {				g.fillFgRect(x, y, barW, barH);			}			x += barW + spcW;		}	}	ctx.draw();}function stringToCode128(text) {	var barc = {		currcs: CODESET.C	};	var bytes = getBytes(text);	//decide starting codeset	var index = bytes[0] == CHAR_TILDE ? 1 : 0;	var csa1 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;	var csa2 = bytes.length > 0 ? codeSetAllowedFor(bytes[index++]) : CODESET.AB;	barc.currcs = getBestStartSet(csa1, csa2);	barc.currcs = perhapsCodeC(bytes, barc.currcs);	//if no codeset changes this will end up with bytes.length+3	//start, checksum and stop	var codes = new Array();	switch (barc.currcs) {		case CODESET.A:			codes.push(SET_STARTA);			break;		case CODESET.B:			codes.push(SET_STARTB);			break;		default:			codes.push(SET_STARTC);			break;	}	for (var i = 0; i < bytes.length; i++) {		var b1 = bytes[i]; //get the first of a pair		//should we translate/replace		if (b1 in REPLACE_CODES) {			codes.push(REPLACE_CODES[b1]);			i++ //jump to next			b1 = bytes[i];		}		//get the next in the pair if possible		var b2 = bytes.length > (i + 1) ? bytes[i + 1] : -1;		codes = codes.concat(codesForChar(b1, b2, barc.currcs));		//code C takes 2 chars each time		if (barc.currcs == CODESET.C) i++;	}	//calculate checksum according to Code 128 standards	var checksum = codes[0];	for (var weight = 1; weight < codes.length; weight++) {		checksum += (weight * codes[weight]);	}	codes.push(checksum % 103);	codes.push(SET_STOP);	//encoding should now be complete	return codes;	function getBestStartSet(csa1, csa2) {		//tries to figure out the best codeset		//to start with to get the most compact code		var vote = 0;		vote += csa1 == CODESET.A ? 1 : 0;		vote += csa1 == CODESET.B ? -1 : 0;		vote += csa2 == CODESET.A ? 1 : 0;		vote += csa2 == CODESET.B ? -1 : 0;		//tie goes to B due to my own predudices		return vote > 0 ? CODESET.A : CODESET.B;	}	function perhapsCodeC(bytes, codeset) {		for (var i = 0; i < bytes.length; i++) {			var b = bytes[i]			if ((b < 48 || b > 57) && b != CHAR_TILDE)				return codeset;		}		return CODESET.C;	}	//chr1 is current byte	//chr2 is the next byte to process. looks ahead.	function codesForChar(chr1, chr2, currcs) {		var result = [];		var shifter = -1;		if (charCompatible(chr1, currcs)) {			if (currcs == CODESET.C) {				if (chr2 == -1) {					shifter = SET_CODEB;					currcs = CODESET.B;				} else if ((chr2 != -1) && !charCompatible(chr2, currcs)) {					//need to check ahead as well					if (charCompatible(chr2, CODESET.A)) {						shifter = SET_CODEA;						currcs = CODESET.A;					} else {						shifter = SET_CODEB;						currcs = CODESET.B;					}				}			}		} else {			//if there is a next char AND that next char is also not compatible			if ((chr2 != -1) && !charCompatible(chr2, currcs)) {				//need to switch code sets				switch (currcs) {					case CODESET.A:						shifter = SET_CODEB;						currcs = CODESET.B;						break;					case CODESET.B:						shifter = SET_CODEA;						currcs = CODESET.A;						break;				}			} else {				//no need to shift code sets, a temporary SHIFT will suffice				shifter = SET_SHIFT;			}		}		//ok some type of shift is nessecary		if (shifter != -1) {			result.push(shifter);			result.push(codeValue(chr2));		} else {			if (currcs == CODESET.C) {				//include next as well				result.push(codeValue(chr1, chr2));			} else {				result.push(codeValue(chr1));			}		}		barc.currcs = currcs;		return result;	}}//reduce the ascii code to fit into the Code128 char tablefunction codeValue(chr1, chr2) {	if (typeof chr2 == "undefined") {		return chr1 >= 32 ? chr1 - 32 : chr1 + 64;	} else {		return parseInt(String.fromCharCode(chr1) + String.fromCharCode(chr2));	}}function charCompatible(chr, codeset) {	var csa = codeSetAllowedFor(chr);	if (csa == CODESET.ANY) return true;	//if we need to change from current	if (csa == CODESET.AB) return true;	if (csa == CODESET.A && codeset == CODESET.A) return true;	if (csa == CODESET.B && codeset == CODESET.B) return true;	return false;}function codeSetAllowedFor(chr) {	if (chr >= 48 && chr <= 57) {		//0-9		return CODESET.ANY;	} else if (chr >= 32 && chr <= 95) {		//0-9 A-Z		return CODESET.AB;	} else {		//if non printable		return chr < 32 ? CODESET.A : CODESET.B;	}}var Graphics = function(ctx, width, height) {	this.width = width;	this.height = height;	this.quiet = Math.round(this.width / 40);	this.border_size = 0;	this.padding_width = 0;	this.area = {		width: width - this.padding_width * 2 - this.quiet * 2,		height: height - this.border_size * 2,		top: this.border_size - 4,		left: this.padding_width + this.quiet	};	this.ctx = ctx;	this.fg = "#000000";	this.bg = "#ffffff";	// fill background	this.fillBgRect(0, 0, width, height);	// fill center to create border	this.fillBgRect(0, this.border_size, width, height - this.border_size * 2);}//use native colorGraphics.prototype._fillRect = function(x, y, width, height, color) {	this.ctx.setFillStyle(color)	this.ctx.fillRect(x, y, width, height)}Graphics.prototype.fillFgRect = function(x, y, width, height) {	this._fillRect(x, y, width, height, this.fg);}Graphics.prototype.fillBgRect = function(x, y, width, height) {	this._fillRect(x, y, width, height, this.bg);}var PATTERNS = [	[2, 1, 2, 2, 2, 2, 0, 0], // 0	[2, 2, 2, 1, 2, 2, 0, 0], // 1	[2, 2, 2, 2, 2, 1, 0, 0], // 2	[1, 2, 1, 2, 2, 3, 0, 0], // 3	[1, 2, 1, 3, 2, 2, 0, 0], // 4	[1, 3, 1, 2, 2, 2, 0, 0], // 5	[1, 2, 2, 2, 1, 3, 0, 0], // 6	[1, 2, 2, 3, 1, 2, 0, 0], // 7	[1, 3, 2, 2, 1, 2, 0, 0], // 8	[2, 2, 1, 2, 1, 3, 0, 0], // 9	[2, 2, 1, 3, 1, 2, 0, 0], // 10	[2, 3, 1, 2, 1, 2, 0, 0], // 11	[1, 1, 2, 2, 3, 2, 0, 0], // 12	[1, 2, 2, 1, 3, 2, 0, 0], // 13	[1, 2, 2, 2, 3, 1, 0, 0], // 14	[1, 1, 3, 2, 2, 2, 0, 0], // 15	[1, 2, 3, 1, 2, 2, 0, 0], // 16	[1, 2, 3, 2, 2, 1, 0, 0], // 17	[2, 2, 3, 2, 1, 1, 0, 0], // 18	[2, 2, 1, 1, 3, 2, 0, 0], // 19	[2, 2, 1, 2, 3, 1, 0, 0], // 20	[2, 1, 3, 2, 1, 2, 0, 0], // 21	[2, 2, 3, 1, 1, 2, 0, 0], // 22	[3, 1, 2, 1, 3, 1, 0, 0], // 23	[3, 1, 1, 2, 2, 2, 0, 0], // 24	[3, 2, 1, 1, 2, 2, 0, 0], // 25	[3, 2, 1, 2, 2, 1, 0, 0], // 26	[3, 1, 2, 2, 1, 2, 0, 0], // 27	[3, 2, 2, 1, 1, 2, 0, 0], // 28	[3, 2, 2, 2, 1, 1, 0, 0], // 29	[2, 1, 2, 1, 2, 3, 0, 0], // 30	[2, 1, 2, 3, 2, 1, 0, 0], // 31	[2, 3, 2, 1, 2, 1, 0, 0], // 32	[1, 1, 1, 3, 2, 3, 0, 0], // 33	[1, 3, 1, 1, 2, 3, 0, 0], // 34	[1, 3, 1, 3, 2, 1, 0, 0], // 35	[1, 1, 2, 3, 1, 3, 0, 0], // 36	[1, 3, 2, 1, 1, 3, 0, 0], // 37	[1, 3, 2, 3, 1, 1, 0, 0], // 38	[2, 1, 1, 3, 1, 3, 0, 0], // 39	[2, 3, 1, 1, 1, 3, 0, 0], // 40	[2, 3, 1, 3, 1, 1, 0, 0], // 41	[1, 1, 2, 1, 3, 3, 0, 0], // 42	[1, 1, 2, 3, 3, 1, 0, 0], // 43	[1, 3, 2, 1, 3, 1, 0, 0], // 44	[1, 1, 3, 1, 2, 3, 0, 0], // 45	[1, 1, 3, 3, 2, 1, 0, 0], // 46	[1, 3, 3, 1, 2, 1, 0, 0], // 47	[3, 1, 3, 1, 2, 1, 0, 0], // 48	[2, 1, 1, 3, 3, 1, 0, 0], // 49	[2, 3, 1, 1, 3, 1, 0, 0], // 50	[2, 1, 3, 1, 1, 3, 0, 0], // 51	[2, 1, 3, 3, 1, 1, 0, 0], // 52	[2, 1, 3, 1, 3, 1, 0, 0], // 53	[3, 1, 1, 1, 2, 3, 0, 0], // 54	[3, 1, 1, 3, 2, 1, 0, 0], // 55	[3, 3, 1, 1, 2, 1, 0, 0], // 56	[3, 1, 2, 1, 1, 3, 0, 0], // 57	[3, 1, 2, 3, 1, 1, 0, 0], // 58	[3, 3, 2, 1, 1, 1, 0, 0], // 59	[3, 1, 4, 1, 1, 1, 0, 0], // 60	[2, 2, 1, 4, 1, 1, 0, 0], // 61	[4, 3, 1, 1, 1, 1, 0, 0], // 62	[1, 1, 1, 2, 2, 4, 0, 0], // 63	[1, 1, 1, 4, 2, 2, 0, 0], // 64	[1, 2, 1, 1, 2, 4, 0, 0], // 65	[1, 2, 1, 4, 2, 1, 0, 0], // 66	[1, 4, 1, 1, 2, 2, 0, 0], // 67	[1, 4, 1, 2, 2, 1, 0, 0], // 68	[1, 1, 2, 2, 1, 4, 0, 0], // 69	[1, 1, 2, 4, 1, 2, 0, 0], // 70	[1, 2, 2, 1, 1, 4, 0, 0], // 71	[1, 2, 2, 4, 1, 1, 0, 0], // 72	[1, 4, 2, 1, 1, 2, 0, 0], // 73	[1, 4, 2, 2, 1, 1, 0, 0], // 74	[2, 4, 1, 2, 1, 1, 0, 0], // 75	[2, 2, 1, 1, 1, 4, 0, 0], // 76	[4, 1, 3, 1, 1, 1, 0, 0], // 77	[2, 4, 1, 1, 1, 2, 0, 0], // 78	[1, 3, 4, 1, 1, 1, 0, 0], // 79	[1, 1, 1, 2, 4, 2, 0, 0], // 80	[1, 2, 1, 1, 4, 2, 0, 0], // 81	[1, 2, 1, 2, 4, 1, 0, 0], // 82	[1, 1, 4, 2, 1, 2, 0, 0], // 83	[1, 2, 4, 1, 1, 2, 0, 0], // 84	[1, 2, 4, 2, 1, 1, 0, 0], // 85	[4, 1, 1, 2, 1, 2, 0, 0], // 86	[4, 2, 1, 1, 1, 2, 0, 0], // 87	[4, 2, 1, 2, 1, 1, 0, 0], // 88	[2, 1, 2, 1, 4, 1, 0, 0], // 89	[2, 1, 4, 1, 2, 1, 0, 0], // 90	[4, 1, 2, 1, 2, 1, 0, 0], // 91	[1, 1, 1, 1, 4, 3, 0, 0], // 92	[1, 1, 1, 3, 4, 1, 0, 0], // 93	[1, 3, 1, 1, 4, 1, 0, 0], // 94	[1, 1, 4, 1, 1, 3, 0, 0], // 95	[1, 1, 4, 3, 1, 1, 0, 0], // 96	[4, 1, 1, 1, 1, 3, 0, 0], // 97	[4, 1, 1, 3, 1, 1, 0, 0], // 98	[1, 1, 3, 1, 4, 1, 0, 0], // 99	[1, 1, 4, 1, 3, 1, 0, 0], // 100	[3, 1, 1, 1, 4, 1, 0, 0], // 101	[4, 1, 1, 1, 3, 1, 0, 0], // 102	[2, 1, 1, 4, 1, 2, 0, 0], // 103	[2, 1, 1, 2, 1, 4, 0, 0], // 104	[2, 1, 1, 2, 3, 2, 0, 0], // 105	[2, 3, 3, 1, 1, 1, 2, 0] // 106]
 |