| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 | import FillStylePattern from './FillStylePattern';import FillStyleLinearGradient from './FillStyleLinearGradient';import FillStyleRadialGradient from './FillStyleRadialGradient';import GImage from '../env/image.js';import {	ArrayBufferToBase64,	Base64ToUint8ClampedArray} from '../env/tool.js';export default class CanvasRenderingContext2D {	_drawCommands = '';	_globalAlpha = 1.0;	_fillStyle = 'rgb(0,0,0)';	_strokeStyle = 'rgb(0,0,0)';	_lineWidth = 1;	_lineCap = 'butt';	_lineJoin = 'miter';	_miterLimit = 10;	_globalCompositeOperation = 'source-over';	_textAlign = 'start';	_textBaseline = 'alphabetic';	_font = '10px sans-serif';	_savedGlobalAlpha = [];	timer = null;	componentId = null;	_notCommitDrawImageCache = [];	_needRedrawImageCache = [];	_redrawCommands = '';	_autoSaveContext = true;	// _imageMap = new GHashMap();	// _textureMap = new GHashMap();	constructor() {		this.className = 'CanvasRenderingContext2D';		//this.save()	}	setFillStyle(value) {		this.fillStyle = value;	}	set fillStyle(value) {		this._fillStyle = value;		if (typeof(value) == 'string') {			this._drawCommands = this._drawCommands.concat("F" + value + ";");		} else if (value instanceof FillStylePattern) {			const image = value._img;			if (!image.complete) {				image.onload = () => {					var index = this._needRedrawImageCache.indexOf(image);					if (index > -1) {						this._needRedrawImageCache.splice(index, 1);						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);						this._redrawflush(true);					}				}				this._notCommitDrawImageCache.push(image);			} else {				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);			}			//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");		} else if (value instanceof FillStyleLinearGradient) {			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +				value._stop_count;			for (var i = 0; i < value._stop_count; ++i) {				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);			}			this._drawCommands = this._drawCommands.concat(command + ";");		} else if (value instanceof FillStyleRadialGradient) {			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r				.toFixed(2) + "," +				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +				value._stop_count;			for (var i = 0; i < value._stop_count; ++i) {				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);			}			this._drawCommands = this._drawCommands.concat(command + ";");		}	}	get fillStyle() {		return this._fillStyle;	}	get globalAlpha() {		return this._globalAlpha;	}	setGlobalAlpha(value) {		this.globalAlpha = value;	}	set globalAlpha(value) {		this._globalAlpha = value;		this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");	}	get strokeStyle() {		return this._strokeStyle;	}	setStrokeStyle(value) {		this.strokeStyle = value;	}	set strokeStyle(value) {		this._strokeStyle = value;		if (typeof(value) == 'string') {			this._drawCommands = this._drawCommands.concat("S" + value + ";");		} else if (value instanceof FillStylePattern) {			CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");		} else if (value instanceof FillStyleLinearGradient) {			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +				value._stop_count;			for (var i = 0; i < value._stop_count; ++i) {				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);			}			this._drawCommands = this._drawCommands.concat(command + ";");		} else if (value instanceof FillStyleRadialGradient) {			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r				.toFixed(2) + "," +				value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +				value._stop_count;			for (var i = 0; i < value._stop_count; ++i) {				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);			}			this._drawCommands = this._drawCommands.concat(command + ";");		}	}	get lineWidth() {		return this._lineWidth;	}	setLineWidth(value) {		this.lineWidth = value;	}	set lineWidth(value) {		this._lineWidth = value;		this._drawCommands = this._drawCommands.concat("W" + value + ";");	}	get lineCap() {		return this._lineCap;	}	setLineCap(value) {		this.lineCap = value;	}	set lineCap(value) {		this._lineCap = value;		this._drawCommands = this._drawCommands.concat("C" + value + ";");	}	get lineJoin() {		return this._lineJoin;	}	setLineJoin(value) {		this.lineJoin = value	}	set lineJoin(value) {		this._lineJoin = value;		this._drawCommands = this._drawCommands.concat("J" + value + ";");	}	get miterLimit() {		return this._miterLimit;	}	setMiterLimit(value) {		this.miterLimit = value	}	set miterLimit(value) {		this._miterLimit = value;		this._drawCommands = this._drawCommands.concat("M" + value + ";");	}	get globalCompositeOperation() {		return this._globalCompositeOperation;	}	set globalCompositeOperation(value) {		this._globalCompositeOperation = value;		let mode = 0;		switch (value) {			case "source-over":				mode = 0;				break;			case "source-atop":				mode = 5;				break;			case "source-in":				mode = 0;				break;			case "source-out":				mode = 2;				break;			case "destination-over":				mode = 4;				break;			case "destination-atop":				mode = 4;				break;			case "destination-in":				mode = 4;				break;			case "destination-out":				mode = 3;				break;			case "lighter":				mode = 1;				break;			case "copy":				mode = 2;				break;			case "xor":				mode = 6;				break;			default:				mode = 0;		}		this._drawCommands = this._drawCommands.concat("B" + mode + ";");	}	get textAlign() {		return this._textAlign;	}	setTextAlign(value) {		this.textAlign = value	}	set textAlign(value) {		this._textAlign = value;		let Align = 0;		switch (value) {			case "start":				Align = 0;				break;			case "end":				Align = 1;				break;			case "left":				Align = 2;				break;			case "center":				Align = 3;				break;			case "right":				Align = 4;				break;			default:				Align = 0;		}		this._drawCommands = this._drawCommands.concat("A" + Align + ";");	}	get textBaseline() {		return this._textBaseline;	}	setTextBaseline(value) {		this.textBaseline = value	}	set textBaseline(value) {		this._textBaseline = value;		let baseline = 0;		switch (value) {			case "alphabetic":				baseline = 0;				break;			case "middle":				baseline = 1;				break;			case "top":				baseline = 2;				break;			case "hanging":				baseline = 3;				break;			case "bottom":				baseline = 4;				break;			case "ideographic":				baseline = 5;				break;			default:				baseline = 0;				break;		}		this._drawCommands = this._drawCommands.concat("E" + baseline + ";");	}	get font() {		return this._font;	}	setFontSize(size) {		var str = this._font;		var strs = str.trim().split(/\s+/);		for (var i = 0; i < strs.length; i++) {			var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",				"bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",				"normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",				"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"			];			if (-1 == values.indexOf(strs[i].trim())) {				if (typeof size === 'string') {					strs[i] = size;				} else if (typeof size === 'number') {					strs[i] = String(size) + 'px';				}				break;			}		}		this.font = strs.join(" ");	}	set font(value) {		this._font = value;		this._drawCommands = this._drawCommands.concat("j" + value + ";");	}	setTransform(a, b, c, d, tx, ty) {		this._drawCommands = this._drawCommands.concat("t" +			(a === 1 ? "1" : a.toFixed(2)) + "," +			(b === 0 ? "0" : b.toFixed(2)) + "," +			(c === 0 ? "0" : c.toFixed(2)) + "," +			(d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");	}	transform(a, b, c, d, tx, ty) {		this._drawCommands = this._drawCommands.concat("f" +			(a === 1 ? "1" : a.toFixed(2)) + "," +			(b === 0 ? "0" : b.toFixed(2)) + "," +			(c === 0 ? "0" : c.toFixed(2)) + "," +			(d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");	}	resetTransform() {		this._drawCommands = this._drawCommands.concat("m;");	}	scale(a, d) {		this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +			d.toFixed(2) + ";");	}	rotate(angle) {		this._drawCommands = this._drawCommands			.concat("r" + angle.toFixed(6) + ";");	}	translate(tx, ty) {		this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");	}	save() {		this._savedGlobalAlpha.push(this._globalAlpha);		this._drawCommands = this._drawCommands.concat("v;");	}	restore() {		this._drawCommands = this._drawCommands.concat("e;");		this._globalAlpha = this._savedGlobalAlpha.pop();	}	createPattern(img, pattern) {		if (typeof img === 'string') {			var imgObj = new GImage();			imgObj.src = img;			img = imgObj;		}		return new FillStylePattern(img, pattern);	}	createLinearGradient(x0, y0, x1, y1) {		return new FillStyleLinearGradient(x0, y0, x1, y1);	}	createRadialGradient = function(x0, y0, r0, x1, y1, r1) {		return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);	};	createCircularGradient = function(x0, y0, r0) {		return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);	};	strokeRect(x, y, w, h) {		this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");	}	clearRect(x, y, w, h) {		this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +			"," + h + ";");	}	clip() {		this._drawCommands = this._drawCommands.concat("p;");	}	resetClip() {		this._drawCommands = this._drawCommands.concat("q;");	}	closePath() {		this._drawCommands = this._drawCommands.concat("o;");	}	moveTo(x, y) {		this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");	}	lineTo(x, y) {		this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");	}	quadraticCurveTo = function(cpx, cpy, x, y) {		this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");	}	bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {		this._drawCommands = this._drawCommands.concat(			"z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +			x.toFixed(2) + "," + y.toFixed(2) + ";");	}	arcTo(x1, y1, x2, y2, radius) {		this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");	}	beginPath() {		this._drawCommands = this._drawCommands.concat("b;");	}	fillRect(x, y, w, h) {		this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +			"," + h + ";");	}	rect(x, y, w, h) {		this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");	}	fill() {		this._drawCommands = this._drawCommands.concat("L;");	}	stroke(path) {		this._drawCommands = this._drawCommands.concat("x;");	}	arc(x, y, radius, startAngle, endAngle, anticlockwise) {		let ianticlockwise = 0;		if (anticlockwise) {			ianticlockwise = 1;		}		this._drawCommands = this._drawCommands.concat(			"y" + x.toFixed(2) + "," + y.toFixed(2) + "," +			radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +			";"		);	}	fillText(text, x, y) {		let tmptext = text.replace(/!/g, "!!");		tmptext = tmptext.replace(/,/g, "!,");		tmptext = tmptext.replace(/;/g, "!;");		this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");	}	strokeText = function(text, x, y) {		let tmptext = text.replace(/!/g, "!!");		tmptext = tmptext.replace(/,/g, "!,");		tmptext = tmptext.replace(/;/g, "!;");		this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");	}	measureText(text) {		return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);	}	isPointInPath = function(x, y) {		throw new Error('GCanvas not supported yet');	}	drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {		if (typeof image === 'string') {			var imgObj = new GImage();			imgObj.src = image;			image = imgObj;		}		if (image instanceof GImage) {			if (!image.complete) {				imgObj.onload = () => {					var index = this._needRedrawImageCache.indexOf(image);					if (index > -1) {						this._needRedrawImageCache.splice(index, 1);						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);						this._redrawflush(true);					}				}				this._notCommitDrawImageCache.push(image);			} else {				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);			}			var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];			var args = [];			for (var arg in srcArgs) {				if (typeof(srcArgs[arg]) != 'undefined') {					args.push(srcArgs[arg]);				}			}			this.__drawImage.apply(this, args);			//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);		}	}	__drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {		const numArgs = arguments.length;		function drawImageCommands() {			if (numArgs === 3) {				const x = parseFloat(sx) || 0.0;				const y = parseFloat(sy) || 0.0;				return ("d" + image._id + ",0,0," +					image.width + "," + image.height + "," +					x + "," + y + "," + image.width + "," + image.height + ";");			} else if (numArgs === 5) {				const x = parseFloat(sx) || 0.0;				const y = parseFloat(sy) || 0.0;				const width = parseInt(sw) || image.width;				const height = parseInt(sh) || image.height;				return ("d" + image._id + ",0,0," +					image.width + "," + image.height + "," +					x + "," + y + "," + width + "," + height + ";");			} else if (numArgs === 9) {				sx = parseFloat(sx) || 0.0;				sy = parseFloat(sy) || 0.0;				sw = parseInt(sw) || image.width;				sh = parseInt(sh) || image.height;				dx = parseFloat(dx) || 0.0;				dy = parseFloat(dy) || 0.0;				dw = parseInt(dw) || image.width;				dh = parseInt(dh) || image.height;				return ("d" + image._id + "," +					sx + "," + sy + "," + sw + "," + sh + "," +					dx + "," + dy + "," + dw + "," + dh + ";");			}		}		this._drawCommands += drawImageCommands();	}	_flush(reserve, callback) {		const commands = this._drawCommands;		this._drawCommands = '';		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);		this._needRender = false;	}	_redrawflush(reserve, callback) {		const commands = this._redrawCommands;		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);		if (this._needRedrawImageCache.length == 0) {			this._redrawCommands = '';		}	}	draw(reserve, callback) {		if (!reserve) {			this._globalAlpha = this._savedGlobalAlpha.pop();			this._savedGlobalAlpha.push(this._globalAlpha);			this._redrawCommands = this._drawCommands;			this._needRedrawImageCache = this._notCommitDrawImageCache;			if (this._autoSaveContext) {				this._drawCommands = ("v;" + this._drawCommands);				this._autoSaveContext = false;			} else {				this._drawCommands = ("e;X;v;" + this._drawCommands);			}		} else {			this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);			this._redrawCommands += this._drawCommands;			if (this._autoSaveContext) {				this._drawCommands = ("v;" + this._drawCommands);				this._autoSaveContext = false;			}		}		this._notCommitDrawImageCache = [];		if (this._flush) {			this._flush(reserve, callback);		}	}	getImageData(x, y, w, h, callback) {		CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {			res.data = Base64ToUint8ClampedArray(res.data);			if (typeof(callback) == 'function') {				callback(res);			}		});	}	putImageData(data, x, y, w, h, callback) {		if (data instanceof Uint8ClampedArray) {			data = ArrayBufferToBase64(data);			CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {				if (typeof(callback) == 'function') {					callback(res);				}			});		}	}	toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {		CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,			fileType, quality,			function(res) {				if (typeof(callback) == 'function') {					callback(res);				}			});	}}
 |