dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
1,065 lines (984 loc) • 42.3 kB
text/typescript
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
namespace egret.native {
let blendModesForGL = {
"source-over": [1, 771],
"lighter": [770, 1],
"destination-out": [0, 771],
"destination-in": [0, 770]
};
/**
* @version Egret 2.4
* @platform Web,Native
* @private
*/
export class NativeCanvasRenderContext extends HashObject {
private $matrix:Matrix = new Matrix();
public $nativeContext:any = null;
/**
* @private
* 与绘图上线文关联的画布实例
* @version Egret 2.4
* @platform Web,Native
*/
canvas:NativeCanvas;
private $globalCompositeOperation:string = "source-over";
/**
* @private
* 设置新图像如何绘制到已有的图像上的规制
* @version Egret 2.4
* @platform Web,Native
*/
public get globalCompositeOperation():string {
return this.$globalCompositeOperation;
}
public set globalCompositeOperation(value:string) {
this.$globalCompositeOperation = value;
let arr = blendModesForGL[value];
if (arr) {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.setBlendArg(arr[0], arr[1]);
}
}
private $globalAlpha:number = 1;
/**
* @private
* 设置接下来绘图填充的整体透明度
* @version Egret 2.4
* @platform Web,Native
*/
public get globalAlpha():number {
return this.$globalAlpha;
}
public set globalAlpha(value:number) {
this.$globalAlpha = value;
$cmdManager.setContext(this.$nativeContext);
$cmdManager.setGlobalAlpha(value);
}
/**
* @private
* 用于表示剪切斜接的极限值的数字。
* @default 10
* @version Egret 2.4
* @platform Web,Native
*/
public miterLimit:number;
/**
* @private
* 指定如何绘制每一条线段末端的属性。有3个可能的值,分别是:<br/>
* <ul>
* <li>"butt": 线段末端以方形结束。</li>
* <li>"round": 线段末端以圆形结束。</li>
* <li>"square": 线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域。</li>
* </ul>
* @default "butt"
* @version Egret 2.4
* @platform Web,Native
*/
public lineCap:string;
/**
* @private
* 指定用于拐角的连接外观的类型,有3个可能的值,分别是:<br/>
* <ul>
* <li>"round": 圆角连接</li>
* <li>"bevel": 斜角连接。</li>
* <li>"miter": 尖角连接。当使用尖角模式时,还可以同时使用 miterLimit 参数限制尖角的长度。</li>
* </ul>
* @default "miter"
* @version Egret 2.4
* @platform Web,Native
*/
public lineJoin:string;
private $lineWidth:number = 0;
/**
* @private
* 设置线条粗细,以像素为单位。设置为0,负数,Infinity 或 NaN 将会被忽略。
* @default 1
* @version Egret 2.4
* @platform Web,Native
*/
public get lineWidth():number {
return this.$lineWidth;
}
public set lineWidth(value:number) {
//console.log("set lineWidth" + value);
this.$lineWidth = value;
$cmdManager.setContext(this.$nativeContext);
$cmdManager.setLineWidth(value);
}
private $strokeStyle:any = "#000000";
/**
* @private
* 设置要在图形边线填充的颜色或样式
* @default "#000000"
* @version Egret 2.4
* @platform Web,Native
*/
public get strokeStyle():any {
return this.$strokeStyle;
}
public set strokeStyle(value:any) {
this.$strokeStyle = value;
if (value != null) {
if (value.indexOf("rgba") != -1) {
value = this.$parseRGBA(value);
}
else if (value.indexOf("rgb") != -1) {
value = this.$parseRGB(value);
}
$cmdManager.setContext(egret_native.Label);
$cmdManager.setStrokeColor(parseInt(value.replace("#", "0x")));
}
$cmdManager.setContext(this.$nativeContext);
let s1 = $cmdManager.pushString(value);
$cmdManager.setStrokeStyle(s1);
}
private $fillStyle:any = "#000000";
/**
* @private
* 设置要在图形内部填充的颜色或样式
* @default "#000000"
* @version Egret 2.4
* @platform Web,Native
*/
public get fillStyle():any {
return this.$fillStyle;
}
public set fillStyle(value:any) {
this.$fillStyle = value;
if (value != null) {
if (value.indexOf("rgba") != -1) {
value = this.$parseRGBA(value);
}
else if (value.indexOf("rgb") != -1) {
value = this.$parseRGB(value);
}
$cmdManager.setContext(egret_native.Label);
$cmdManager.setTextColor(parseInt(value.replace("#", "0x")));
}
$cmdManager.setContext(this.$nativeContext);
let s1 = $cmdManager.pushString(value);
$cmdManager.setFillStyle(s1);
}
private $fillColorStr(s:string):string {
if (s.length < 2) {
s = "0" + s;
}
return s;
}
private $parseRGBA(str:string):string {
let index:number = str.indexOf("(");
str = str.slice(index + 1, str.length - 1);
let arr:string[] = str.split(",");
let a:string = parseInt(<any>(parseFloat(arr[3]) * 255)).toString(16);
let r:string = parseInt(arr[0]).toString(16);
let g:string = parseInt(arr[1]).toString(16);
let b:string = parseInt(arr[2]).toString(16);
str = "#" + this.$fillColorStr(a) + this.$fillColorStr(r) + this.$fillColorStr(g) + this.$fillColorStr(b);
return str;
}
private $parseRGB(str:string):string {
let index:number = str.indexOf("(");
str = str.slice(index + 1, str.length - 1);
let arr:string[] = str.split(",");
let r:string = parseInt(arr[0]).toString(16);
let g:string = parseInt(arr[1]).toString(16);
let b:string = parseInt(arr[2]).toString(16);
str = "#" + this.$fillColorStr(r) + this.$fillColorStr(g) + this.$fillColorStr(b);
return str;
}
/**
* @private
* 控制在缩放时是否对位图进行平滑处理。
* @default true
* @version Egret 2.4
* @platform Web,Native
*/
public imageSmoothingEnabled:boolean;
/**
* @private
* 文本的对齐方式的属性,有5个可能的值,分别是:<br/>
* <ul>
* <li>"left" 文本左对齐。</li>
* <li>"right" 文本右对齐。</li>
* <li>"center" 文本居中对齐。</li>
* <li>"start" 文本对齐界线开始的地方 (对于从左向右阅读的语言使用左对齐,对从右向左的阅读的语言使用右对齐)。</li>
* <li>"end" 文本对齐界线结束的地方 (对于从左向右阅读的语言使用右对齐,对从右向左的阅读的语言使用左对齐)。</li>
* </ul>
* @default "start"
* @version Egret 2.4
* @platform Web,Native
*/
public textAlign:string;
/**
* @private
* 决定文字垂直方向的对齐方式。有6个可能的值,分别是:<br/>
* <ul>
* <li>"top" 文本基线在文本块的顶部。</li>
* <li>"hanging" 文本基线是悬挂基线。</li>
* <li>"middle" 文本基线在文本块的中间。</li>
* <li>"alphabetic" 文本基线是标准的字母基线。</li>
* <li>"ideographic" 文字基线是表意字基线;如果字符本身超出了alphabetic 基线,那么ideograhpic基线位置在字符本身的底部。</li>
* <li>"bottom" 文本基线在文本块的底部。 与 ideographic 基线的区别在于 ideographic 基线不需要考虑下行字母。</li>
* </ul>
* @default "alphabetic"
* @version Egret 2.4
* @platform Web,Native
*/
public textBaseline:string;
private $font:string = "normal normal 10px sans-serif";
private $fontSize:number = 10;
private $fontFamily:string = "";
/**
* @private
* 当前的字体样式
* @version Egret 2.4
* @platform Web,Native
*/
public get font():string {
return this.$font;
}
public set font(value:string) {
this.$font = value;
let arr:string[] = value.split(" ");
let sizeTxt:string = arr[2];
if (sizeTxt.indexOf("px") != -1) {
this.$fontSize = parseInt(sizeTxt.replace("px", ""));
//console.log("set font" + this.$lineWidth);
}
if(useFontMapping) {
let fontFamilyText:string;
if(arr.length == 4) {
fontFamilyText = arr[3];
}
else {
fontFamilyText = arr.slice(3).join(" ");
}
let arr2;
if(fontFamilyText.indexOf(", ") != -1) {
arr2 = fontFamilyText.split(", ");
}
else if(fontFamilyText.indexOf(",") != -1) {
arr2 = fontFamilyText.split(",");
}
if(arr2) {
let length:number = arr2.length;
for(let i = 0 ; i < length ; i++) {
let fontFamily = arr2[i];
//暂时先不考虑带有引号的情况
if(fontMapping[fontFamily]) {
this.$fontFamily = fontMapping[fontFamily];
return;
}
}
}
else {
this.$fontFamily = fontMapping[fontFamilyText];
}
if(!this.$fontFamily) {
this.$fontFamily = "/system/fonts/DroidSansFallback.ttf";
}
}
else {
//兼容旧版本直接将 default_fontFamily 设置为字体路径的情况
this.$fontFamily = TextField.default_fontFamily;
}
}
/**
* @private
* 绘制一段圆弧路径。圆弧路径的圆心在 (x, y) 位置,半径为 r ,根据anticlockwise (默认为顺时针)指定的方向从 startAngle 开始绘制,到 endAngle 结束。
* @param x 圆弧中心(圆心)的 x 轴坐标。
* @param y 圆弧中心(圆心)的 y 轴坐标。
* @param radius 圆弧的半径。
* @param startAngle 圆弧的起始点, x轴方向开始计算,单位以弧度表示。
* @param endAngle 圆弧的重点, 单位以弧度表示。
* @param anticlockwise 如果为 true,逆时针绘制圆弧,反之,顺时针绘制。
* @version Egret 2.4
* @platform Web,Native
*/
public arc(x:number, y:number, radius:number, startAngle:number, endAngle:number, anticlockwise?:boolean):void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.arc(x, y, radius, startAngle, endAngle, anticlockwise ? 1 : 0);
// this.$nativeContext.arc(x, y, radius, startAngle, endAngle, anticlockwise);
}
/**
* @private
* 绘制一段二次贝塞尔曲线路径。它需要2个点。 第一个点是控制点,第二个点是终点。 起始点是当前路径最新的点,当创建二次贝赛尔曲线之前,可以使用 moveTo() 方法进行改变。
* @param cpx 控制点的 x 轴坐标。
* @param cpy 控制点的 y 轴坐标。
* @param x 终点的 x 轴坐标。
* @param y 终点的 y 轴坐标。
* @version Egret 2.4
* @platform Web,Native
*/
public quadraticCurveTo(cpx:number, cpy:number, x:number, y:number):void {
//console.log("quadraticCurveTo " + cpx + " " + cpy + " " + x + " " + y);
$cmdManager.setContext(this.$nativeContext);
$cmdManager.quadraticCurveTo(cpx, cpy, x, y);
// this.$nativeContext.quadraticCurveTo(cpx, cpy, x, y);
}
/**
* @private
* 使用直线连接子路径的终点到x,y坐标。
* @param x 直线终点的 x 轴坐标。
* @param y 直线终点的 y 轴坐标。
* @version Egret 2.4
* @platform Web,Native
*/
public lineTo(x:number, y:number):void {
//console.log("lineTo " + x + " " + y);
$cmdManager.setContext(this.$nativeContext);
$cmdManager.lineTo(x, y);
}
/**
* @private
* 根据当前的填充样式,填充当前或已存在的路径的方法。采取非零环绕或者奇偶环绕规则。
* @param fillRule 一种算法,决定点是在路径内还是在路径外。允许的值:
* "nonzero": 非零环绕规则, 默认的规则。
* "evenodd": 奇偶环绕规则。
* @version Egret 2.4
* @platform Web,Native
*/
public fill(fillRule?:string):void {
$cmdManager.setContext(this.$nativeContext);
let s1 = $cmdManager.pushString(fillRule);
$cmdManager.fill(s1);
}
/**
* @private
* 使笔点返回到当前子路径的起始点。它尝试从当前点到起始点绘制一条直线。如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。
* @version Egret 2.4
* @platform Web,Native
*/
public closePath():void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.closePath();
if (this.clipRectArray) {
this.$clipRectArray = this.clipRectArray;
this.clipRectArray = null;
}
}
/**
* @private
* 创建一段矩形路径,矩形的起点位置是 (x, y) ,尺寸为 width 和 height。矩形的4个点通过直线连接,子路径做为闭合的标记,所以你可以填充或者描边矩形。
* @param x 矩形起点的 x 轴坐标。
* @param y 矩形起点的 y 轴坐标。
* @param width 矩形的宽度。
* @param height 矩形的高度。
* @version Egret 2.4
* @platform Web,Native
*/
public rect(x:number, y:number, w:number, h:number):void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.rect(x, y, w, h);
this.$clipRectArray.push({x: x, y: y, w: w, h: h});
}
/**
* @private
* 将一个新的子路径的起始点移动到(x,y)坐标
* @param x 点的 x 轴
* @param y 点的 y 轴
* @version Egret 2.4
* @platform Web,Native
*/
public moveTo(x:number, y:number):void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.moveTo(x, y);
}
public setLineDash(segments: number[]):void {
// $cmdManager.setLineDash(segments);
}
/**
* @private
* 绘制一个填充矩形。矩形的起点在 (x, y) 位置,矩形的尺寸是 width 和 height ,fillStyle 属性决定矩形的样式。
* @param x 矩形起始点的 x 轴坐标。
* @param y 矩形起始点的 y 轴坐标。
* @param width 矩形的宽度。
* @param height 矩形的高度。
* @version Egret 2.4
* @platform Web,Native
*/
public fillRect(x:number, y:number, w:number, h:number):void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.fillRect(x, y, w, h);
// this.$nativeContext.fillRect(x, y, w, h);
}
/**
* @private
* 绘制一段三次贝赛尔曲线路径。该方法需要三个点。 第一、第二个点是控制点,第三个点是结束点。起始点是当前路径的最后一个点,
* 绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改。
* @param cp1x 第一个控制点的 x 轴坐标。
* @param cp1y 第一个控制点的 y 轴坐标。
* @param cp2x 第二个控制点的 x 轴坐标。
* @param cp2y 第二个控制点的 y 轴坐标。
* @param x 结束点的 x 轴坐标。
* @param y 结束点的 y 轴坐标。
* @version Egret 2.4
* @platform Web,Native
*/
public bezierCurveTo(cp1x:number, cp1y:number, cp2x:number, cp2y:number, x:number, y:number):void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
// this.$nativeContext.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
/**
* @private
* 根据当前的画线样式,绘制当前或已经存在的路径的方法。
* @version Egret 2.4
* @platform Web,Native
*/
public stroke():void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.stroke();
// this.$nativeContext.stroke();
}
/**
* @private
* 使用当前的绘画样式,描绘一个起点在 (x, y) 、宽度为 w 、高度为 h 的矩形的方法。
* @param x 矩形起点的 x 轴坐标。
* @param y 矩形起点的 y 轴坐标。
* @param w 矩形的宽度。
* @param h 矩形的高度。
* @version Egret 2.4
* @platform Web,Native
*/
public strokeRect(x:number, y:number, w:number, h:number):void {
//console.log("strokeRect");
$cmdManager.setContext(this.$nativeContext);
$cmdManager.strokeRect(x, y, w, h);
// this.$nativeContext.strokeRect(x, y, w, h);
}
private clipRectArray = null;
/**
* @private
* 清空子路径列表开始一个新路径。 当你想创建一个新的路径时,调用此方法。
* @version Egret 2.4
* @platform Web,Native
*/
public beginPath():void {
$cmdManager.setContext(this.$nativeContext);
$cmdManager.beginPath();
this.clipRectArray = this.$clipRectArray.concat();
}
/**
* @private
* 根据控制点和半径绘制一段圆弧路径,使用直线连接前一个点。
* @param x1 第一个控制点的 x 轴坐标。
* @param y1 第一个控制点的 y 轴坐标。
* @param x2 第二个控制点的 x 轴坐标。
* @param y2 第二个控制点的 y 轴坐标。
* @param radius 圆弧的半径。
* @version Egret 2.4
* @platform Web,Native
*/
public arcTo(x1:number, y1:number, x2:number, y2:number, radius:number):void {
this.$nativeContext.arcTo(x1, y1, x2, y2, radius);
}
/**
* @private
* 使用方法参数描述的矩阵多次叠加当前的变换矩阵。
* @param a 水平缩放。
* @param b 水平倾斜。
* @param c 垂直倾斜。
* @param d 垂直缩放。
* @param tx 水平移动。
* @param ty 垂直移动。
* @version Egret 2.4
* @platform Web,Native
*/
public transform(a:number, b:number, c:number, d:number, tx:number, ty:number):void {
this.$matrix.append(a, b, c, d, tx, ty);
this.setTransformToNative();
}
/**
* @private
* 通过在网格中移动 surface 和 surface 原点 x 水平方向、原点 y 垂直方向,添加平移变换
* @param x 水平移动。
* @param y 垂直移动。
* @version Egret 2.4
* @platform Web,Native
*/
public translate(x:number, y:number):void {
this.$matrix.translate(x, y);
this.setTransformToNative();
}
/**
* @private
* 根据 x 水平方向和 y 垂直方向,为 surface 单位添加缩放变换。
* @param x 水平方向的缩放因子。
* @param y 垂直方向的缩放因子。
* @version Egret 2.4
* @platform Web,Native
*/
public scale(x:number, y:number):void {
this.$matrix.scale(x, y);
this.setTransformToNative();
}
/**
* @private
* 在变换矩阵中增加旋转,角度变量表示一个顺时针旋转角度并且用弧度表示。
* @param angle 顺时针旋转的弧度。
* @version Egret 2.4
* @platform Web,Native
*/
public rotate(angle:number):void {
this.$matrix.rotate(angle);
this.setTransformToNative();
}
/**
* @private
* 恢复到最近的绘制样式状态,此状态是通过 save() 保存到”状态栈“中最新的元素。
* @version Egret 2.4
* @platform Web,Native
*/
public restore():void {
//console.log("restore");
if (this.$saveList.length) {
let data = this.$saveList.pop();
for (let key in data) {
this[key] = data[key];
}
this.setTransformToNative();
$cmdManager.setContext(this.$nativeContext);
$cmdManager.restore();
this.clipRectArray = null;
}
}
private $saveList:any[] = [];
/**
* @private
* 使用栈保存当前的绘画样式状态,你可以使用 restore() 恢复任何改变。
* @version Egret 2.4
* @platform Web,Native
*/
public save():void {
//console.log("save");
let transformMatrix = new Matrix();
transformMatrix.copyFrom(this.$matrix);
this.$saveList.push({
lineWidth: this.$lineWidth,
globalCompositeOperation: this.$globalCompositeOperation,
globalAlpha: this.$globalAlpha,
strokeStyle: this.$strokeStyle,
fillStyle: this.$fillStyle,
font: this.$font,
$matrix: transformMatrix,
$clipRectArray: this.$clipRectArray.concat()
});
$cmdManager.setContext(this.$nativeContext);
$cmdManager.save();
}
private $clipRectArray:any[] = [];
private $clipRect:Rectangle = new Rectangle();
private $saveCount:number = 0;
private $clipList:number[] = [];
/**
* @private
* 从当前路径创建一个剪切路径。在 clip() 调用之后,绘制的所有信息只会出现在剪切路径内部。
* @version Egret 2.4
* @platform Web,Native
*/
public clip(fillRule?:string):void {
if (this.$clipRectArray.length > 0) {
let arr = [];
for (let i:number = 0; i < this.$clipRectArray.length; i++) {
let clipRect = this.$clipRectArray[i];
arr.push(clipRect.x);
arr.push(clipRect.y);
arr.push(clipRect.w);
arr.push(clipRect.h);
}
//console.log("pushRectStencils " + arr.toString());
$cmdManager.setContext(this.$nativeContext);
$cmdManager.pushRectStencils(arr);
this.$clipRectArray.length = 0;
}
}
/**
* @private
* 设置指定矩形区域内(以 点 (x, y) 为起点,范围是(width, height) )所有像素变成透明,并擦除之前绘制的所有内容。
* @param x 矩形起点的 x 轴坐标。
* @param y 矩形起点的 y 轴坐标。
* @param width 矩形的宽度。
* @param height 矩形的高度。
* @version Egret 2.4
* @platform Web,Native
*/
public clearRect(x:number, y:number, width:number, height:number):void {
//console.log("clearRect x:" + x + " y:" + y + " width:" + width + " height:" + height);
$cmdManager.setContext(this.$nativeContext);
$cmdManager.clearRect(x, y, width, height);
}
/**
* @private
* 重新设置当前的变换为单位矩阵,并使用同样的变量调用 transform() 方法。
* @param a 水平缩放。
* @param b 水平倾斜。
* @param c 垂直倾斜。
* @param d 垂直缩放。
* @param tx 水平移动。
* @param ty 垂直移动。
* @version Egret 2.4
* @platform Web,Native
*/
public setTransform(a:number, b:number, c:number, d:number, tx:number, ty:number):void {
this.$matrix.setTo(a, b, c, d, tx, ty);
this.setTransformToNative();
}
private setTransformToNative():void {
let m = this.$matrix;
//console.log("setTransformToNative::a=" + m.a + " b=" + m.b + " c=" + m.c + " d=" + m.d + " tx=" + m.tx + " ty=" + m.ty);
$cmdManager.setContext(this.$nativeContext);
$cmdManager.setTransform(m.a, m.b, m.c, m.d, m.tx, m.ty);
}
private savedMatrix:Matrix = new Matrix();
/**
* @private
* 保存矩阵,这里只能保存一次,嵌套无效
*/
public saveTransform():void {
this.savedMatrix.copyFrom(this.$matrix);
}
/**
* @private
* 保存矩阵,这里只能保存一次,嵌套无效
*/
public restoreTransform():void {
this.$matrix.copyFrom(this.savedMatrix);
}
/**
* @private
* 创建一个沿参数坐标指定的直线的渐变。该方法返回一个线性的 GraphicsGradient 对象。
* @param x0 起点的 x 轴坐标。
* @param y0 起点的 y 轴坐标。
* @param x1 终点的 x 轴坐标。
* @param y1 终点的 y 轴坐标。
* @version Egret 2.4
* @platform Web,Native
*/
public createLinearGradient(x0:number, y0:number, x1:number, y1:number):CanvasGradient {
return this.$nativeContext.createLinearGradient(x0, y0, x1, y1);
}
/**
* @private
* 根据参数确定的两个圆的坐标,创建一个放射性渐变。该方法返回一个放射性的 GraphicsGradient。
* @param x0 开始圆形的 x 轴坐标。
* @param y0 开始圆形的 y 轴坐标。
* @param r0 开始圆形的半径。
* @param x1 结束圆形的 x 轴坐标。
* @param y1 结束圆形的 y 轴坐标。
* @param r1 结束圆形的半径。
* @version Egret 2.4
* @platform Web,Native
*/
public createRadialGradient(x0:number, y0:number, r0:number, x1:number, y1:number, r1:number):CanvasGradient {
return this.$nativeContext.createRadialGradient(x0, y0, r0, x1, y1, r1);
}
/**
* @private
* 在(x,y)位置绘制(填充)文本。
* @version Egret 2.4
* @platform Web,Native
*/
public fillText(text:string, x:number, y:number, maxWidth?:number):void {
//console.log("drawText" + text);
$cmdManager.setContext(this.$nativeContext);
let s1 = $cmdManager.pushString(this.$fontFamily);
let s2 = $cmdManager.pushString("");
$cmdManager.createLabel(s1, this.$fontSize, s2, this.$hasStrokeText ? this.$lineWidth : 0);
this.$hasStrokeText = false;
let s3 = $cmdManager.pushString(text);
$cmdManager.drawText(s3, x, y);
}
private $hasStrokeText:boolean = false;
public strokeText(text:string, x:number, y:number, maxWidth?:number):void {
this.$hasStrokeText = true;
}
/**
* @private
* 测量指定文本宽度,返回 TextMetrics 对象。
* @version Egret 2.4
* @platform Web,Native
*/
public measureText(text:string):TextMetrics {
$cmdManager.setContext(egret_native.Label);
let s1 = $cmdManager.pushString(this.$fontFamily);
let s2 = $cmdManager.pushString("");
$cmdManager.createLabel(s1, this.$fontSize, s2, this.$hasStrokeText ? this.$lineWidth : 0);
//同步更新
$cmdManager.flush();
return {width: egret_native.Label.getTextSize(text)[0]};
}
/**
* @private
* 注意:如果要对绘制的图片进行缩放,出于性能优化考虑,系统不会主动去每次重置imageSmoothingEnabled属性,因此您在调用drawImage()方法前请务必
* 确保 imageSmoothingEnabled 已被重置为正常的值,否则有可能沿用上个显示对象绘制过程留下的值。
* @version Egret 2.4
* @platform Web,Native
*/
public drawImage(image:BitmapData | NativeCanvas, offsetX:number, offsetY:number, width?:number, height?:number,
surfaceOffsetX?:number, surfaceOffsetY?:number, surfaceImageWidth?:number, surfaceImageHeight?:number):void {
let bitmapData;
let isNative:boolean;
if ((<NativeCanvas><any>image).$nativeCanvas) {
bitmapData = (<NativeCanvas><any>image).$nativeCanvas;
isNative = true;
}
else {
bitmapData = image;
isNative = false;
}
if (!bitmapData) {
return;
}
if (arguments.length == 3) {
surfaceOffsetX = offsetX;
surfaceOffsetY = offsetY;
offsetX = 0;
offsetY = 0;
width = surfaceImageWidth = image.width;
height = surfaceImageHeight = image.height;
}
else if (arguments.length == 5) {
surfaceOffsetX = offsetX;
surfaceOffsetY = offsetY;
surfaceImageWidth = width;
surfaceImageHeight = height;
offsetX = 0;
offsetY = 0;
width = image.width;
height = image.height;
}
else {
if (width == void 0) {
width = image.width;
}
if (height == void 0) {
height = image.height;
}
if (surfaceOffsetX == void 0) {
surfaceOffsetX = 0;
}
if (surfaceOffsetY == void 0) {
surfaceOffsetY = 0;
}
if (surfaceImageWidth == void 0) {
surfaceImageWidth = width;
}
if (surfaceImageHeight == void 0) {
surfaceImageHeight = height;
}
}
//console.log("drawImage::" + offsetX + " " + offsetY + " " + width + " " + height + " " + surfaceOffsetX + " " + surfaceOffsetY + " " + surfaceImageWidth + " " + surfaceImageHeight);
//console.log("drawImage::" + bitmapData);
let imageAdress;
if(!isNative) {
if(!bitmapData._native_tex_loc) {
bitmapData._native_tex_loc = bitmapData.___native_texture__p;
}
imageAdress = bitmapData._native_tex_loc;
} else {
imageAdress = bitmapData.___native_texture__p;
}
native.$cmdManager.setContext(this.$nativeContext);
$cmdManager.drawImage(imageAdress, offsetX, offsetY, width, height, surfaceOffsetX, surfaceOffsetY, surfaceImageWidth, surfaceImageHeight);
}
/**
* @private
* draw mesh
*/
public drawMesh(image, offsetX, offsetY, width, height, surfaceOffsetX, surfaceOffsetY, surfaceImageWidth, surfaceImageHeight,
textureSourceWidth, textureSourceHeight, meshUVs, meshVertices, meshIndices):void {
let bitmapData;
if (image.$nativeCanvas) {
bitmapData = image.$nativeCanvas;
}
else {
bitmapData = image;
}
if (!bitmapData) {
return;
}
if (arguments.length == 3) {
surfaceOffsetX = offsetX;
surfaceOffsetY = offsetY;
offsetX = 0;
offsetY = 0;
width = surfaceImageWidth = image.width;
height = surfaceImageHeight = image.height;
}
else if (arguments.length == 5) {
surfaceOffsetX = offsetX;
surfaceOffsetY = offsetY;
surfaceImageWidth = width;
surfaceImageHeight = height;
offsetX = 0;
offsetY = 0;
width = image.width;
height = image.height;
}
else {
if (!width) {
width = image.width;
}
if (!height) {
height = image.height;
}
if (!surfaceOffsetX) {
surfaceOffsetX = 0;
}
if (!surfaceOffsetY) {
surfaceOffsetY = 0;
}
if (!surfaceImageWidth) {
surfaceImageWidth = width;
}
if (!surfaceImageHeight) {
surfaceImageHeight = height;
}
}
this.vertices = new Float32Array(meshVertices.length / 2 * 5);
this.indicesForMesh = new Uint32Array(meshIndices.length);
this.cacheArrays(this.$matrix, 1, offsetX, offsetY, width, height, surfaceOffsetX, surfaceOffsetY,
surfaceImageWidth, surfaceImageHeight, textureSourceWidth, textureSourceHeight, meshUVs, meshVertices, meshIndices);
// 打断批渲染
$cmdManager.flush();
this.$nativeContext.drawMesh(bitmapData, this.vertices, this.indicesForMesh, this.vertices.length, this.indicesForMesh.length);
}
private vertices:Float32Array;
private indicesForMesh:Float32Array;
private cacheArrays(transform, alpha, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight,
textureSourceWidth, textureSourceHeight, meshUVs, meshVertices, meshIndices) {
//计算出绘制矩阵,之后把矩阵还原回之前的
let locWorldTransform = transform;
let originalA = locWorldTransform.a;
let originalB = locWorldTransform.b;
let originalC = locWorldTransform.c;
let originalD = locWorldTransform.d;
let originalTx = locWorldTransform.tx;
let originalTy = locWorldTransform.ty;
if (destX != 0 || destY != 0) {
locWorldTransform.append(1, 0, 0, 1, destX, destY);
}
if (sourceWidth / destWidth != 1 || sourceHeight / destHeight != 1) {
locWorldTransform.append(destWidth / sourceWidth, 0, 0, destHeight / sourceHeight, 0, 0);
}
let a = locWorldTransform.a;
let b = locWorldTransform.b;
let c = locWorldTransform.c;
let d = locWorldTransform.d;
let tx = locWorldTransform.tx;
let ty = locWorldTransform.ty;
locWorldTransform.a = originalA;
locWorldTransform.b = originalB;
locWorldTransform.c = originalC;
locWorldTransform.d = originalD;
locWorldTransform.tx = originalTx;
locWorldTransform.ty = originalTy;
if (meshVertices) {
// 计算索引位置与赋值
let vertices = this.vertices;
// 缓存顶点数组
let i = 0, iD = 0, l = 0;
let u = 0, v = 0, x = 0, y = 0;
for (i = 0, l = meshUVs.length; i < l; i += 2) {
iD = i * 5 / 2;
x = meshVertices[i];
y = meshVertices[i + 1];
u = meshUVs[i];
v = meshUVs[i + 1];
// xy
vertices[iD + 0] = a * x + c * y + tx;
vertices[iD + 1] = b * x + d * y + ty;
// uv
vertices[iD + 2] = (sourceX + u * sourceWidth) / textureSourceWidth;
vertices[iD + 3] = (sourceY + v * sourceHeight) / textureSourceHeight;
// alpha
vertices[iD + 4] = alpha;
}
for (i = 0; i < meshIndices.length; i++) {
this.indicesForMesh[i] = meshIndices[i];
}
}
else {
console.log("meshVertices not exist");
}
}
/**
* @private
* 基于指定的源图象(BitmapData)创建一个模板,通过repetition参数指定源图像在什么方向上进行重复,返回一个GraphicsPattern对象。
* @param bitmapData 做为重复图像源的 BitmapData 对象。
* @param repetition 指定如何重复图像。
* 可能的值有:"repeat" (两个方向重复),"repeat-x" (仅水平方向重复),"repeat-y" (仅垂直方向重复),"no-repeat" (不重复).
* @version Egret 2.4
* @platform Web,Native
*/
public createPattern(image:BitmapData, repetition:string):CanvasPattern {
return null;
}
/**
* @private
* 返回一个 ImageData 对象,用来描述canvas区域隐含的像素数据,这个区域通过矩形表示,起始点为(sx, sy)、宽为sw、高为sh。
* @version Egret 2.4
* @platform Web,Native
*/
public getImageData(sx:number, sy:number, sw:number, sh:number):ImageData {
$cmdManager.flush();
let res;
if (sx != Math.floor(sx)) {
sx = Math.floor(sx);
sw++;
}
if (sy != Math.floor(sy)) {
sy = Math.floor(sy);
sh++;
}
res = this.$nativeContext.getPixels(sx, sy, sw, sh);
if (res.pixelData) {
res.data = res.pixelData;
}
return res;
}
/**
* @private
* 设置全局shader
* @param filter filter属性生成的json
*/
public setGlobalShader(filter:egret.Filter):void {
$cmdManager.setContext(this.$nativeContext);
let s1;
if(filter) {
s1 = $cmdManager.pushString(filter.$toJson());
} else {
s1 = $cmdManager.pushString("");
}
$cmdManager.setGlobalShader(s1);
}
}
}