skia是个2D矢量图形
处理函数库,包含转换字型,坐标及点阵图
void onDraw( SkCanvas* canvas);//未调用
行类:
virtual void onDraw( SkCanvas* canvas);
virtual void Render(SkCanvas* canvas,const SkRect & rect);
virtual void RenderEx( SkCanvas* canvas,float fx,float fy );
virtual bool hitTest( float x,float y);
virtual void UpData();
virtual void Transform(float fx, float fy);
面板视类:
void CreateFont();
virtual float getPaintWidth(); // 取当前绘图宽
virtual float getPaintHeight(); // 取当前绘图高
virtual std::string getViewData(); // 取当前视图数据
virtual std::string getViewState(); // 取当前视图状态
virtual std::string getObjectTypeID(); // 取当前活动对象ID
virtual std::string getObjectData(); // 取当前活动对象数据
virtual std::string getObjectProperty(); // 取当前活动对象属性
virtual std::string getObjectState(); // 取当前活动对象状态
跟踪类:
virtual void drawTracking( SkCanvas* canvas); // 绘制Tracking
virtual void doLButtonDown(float x,float y); // 左键单击事件
virtual void doMouseMove(float x,float y); // 鼠标移动事件
virtual void doLButtonUp(float x,float y); // 左键单击事件
virtual void doRButtonDown(float x,float y); // 右键单击事件
virtual void doLButtonDblClk(float x,float y); // 左键双击事件
virtual void doKeyDown(const std::string& assistKey,const std::string& keyCode); // 键盘按下事件
virtual void doKeyUp(const std::string& assistKey,const std::string& keyCode); // 键盘弹起事件
渲染视类工厂:
virtual int buildRenderView() override;//
SkCanvas类
核心类,封装画图操作
,包含设备引用,矩阵和裁剪栈
,记录了整个设备绘画状态
,由SkPaint
记录.传递给drawPoints,drawLine,drawRect,drawCircle
,记录颜色(color)
,字体(typeface)
,文字大小(textSize)
,文字粗细(strokeWidth)
,渐变(gradients
,patterns)
.
构造函数:
SkCanvas(const SkBitmap&bitmap);
SkCanvas(SkDevice*device=NULL);
//位图/设备
支持opengl
,setViewport
,getViewport
.保存和恢复显示矩阵,剪切,过滤堆栈
:save
,saveLayer
,saveLayerAlpha
,restore
移位,缩放,旋转,变形
translate(SkiaScalar dx, SkiaScalar dy);
scale(SkScalar sx, SkScalar sy);
rotate(SkScalar degrees);
skew(SkScalar sx, SkScalar sy);
变换矩阵:
cancat(const SkMatrix& matrix);
移位,缩放,旋转,变形
等操作,可通过定义特定矩阵
,再调用该操作来实现.
clipRect(SkRect&...);
clipPath(SkPath&...);
clipRegion(SkRegion&...);
显示指定区域.
画图 背景色:drawARGB(u8 a, u8 r, u8 g, u8 b....)
//红绿蓝透
void clear(SkColor);
drawColor(SkColor color...)
//画颜色,指定颜色填充整个绘图
drawPaint(SkPaint& paint)
//画笔填充区域
// 背景色
canvas->drawARGB(255, 0, 255, 0);
canvas->clear(SK_ColorDKGRAY);
canvas->drawColor(SK_ColorRED);
SkPaint paintLgyBkColor;
paintLgyBkColor.setColor(SK_ColorBLUE);
canvas->drawPaint(paintLgyBkColor);
点:
void drawPoint(SkScalar x, SkScalar y, SkColor color);
void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],constSkPaint& paint);
//根据不同参数绘制不同点
drawVertices(...)
//绘制顶点,可以有纹理,颜色,等附加选项
//示例:
canvas->drawPoint(1, 1, SK_ColorRED);
SkPaint paintLgyPoint;
paintLgyPoint.setColor(SK_ColorBLUE);
canvas->drawPoint(3, 1, paintLgyPoint);
SkPoint ptsPoints[] = {SkPoint::Make(4,1), SkPoint::Make(8,1), SkPoint::Make(4,5), SkPoint::Make(8,5)};
size_t countPoints = sizeof(ptsPoints)/sizeof(SkPoint);
canvas->drawPoints(SkCanvas::kPoints_PointMode, countPoints, ptsPoints, paintLgyPoint);
SkPoint ptsLines[] = {SkPoint::Make(10,1), SkPoint::Make(14,1), SkPoint::Make(10,5), SkPoint::Make(14,5)};
size_t countLines = sizeof(ptsLines)/sizeof(SkPoint);
canvas->drawPoints(SkCanvas::kLines_PointMode, countLines, ptsLines, paintLgyPoint);
SkPoint ptsPolygon[] = {SkPoint::Make(16,1), SkPoint::Make(20,1), SkPoint::Make(16,5), SkPoint::Make(20,5)};
size_t countPolygon = sizeof(ptsPolygon)/sizeof(SkPoint);
canvas->drawPoints(SkCanvas::kPolygon_PointMode, countPolygon, ptsPolygon, paintLgyPoint);
SkPoint vertices[] = {SkPoint::Make(22,1), SkPoint::Make(26,1), SkPoint::Make(22,5), SkPoint::Make(26,5)};
int vertexCount = sizeof(vertices)/sizeof(SkPoint);
canvas->drawVertices(SkCanvas::kTriangles_VertexMode, vertexCount, vertices, NULL, NULL, NULL, NULL, 0, paintLgyPoint);
SkPoint verticesStrip[] = {SkPoint::Make(28,1), SkPoint::Make(32,1), SkPoint::Make(28,5), SkPoint::Make(32,5)};
int vertexCountStrip = sizeof(verticesStrip)/sizeof(SkPoint);
canvas->drawVertices(SkCanvas::kTriangleStrip_VertexMode, vertexCountStrip, verticesStrip, NULL, NULL, NULL, NULL, 0, paintLgyPoint);
SkPoint verticesFan[] = {SkPoint::Make(34,1), SkPoint::Make(38,1), SkPoint::Make(34,5), SkPoint::Make(38,5)};
int vertexCountFan = sizeof(verticesFan)/sizeof(SkPoint);
canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, vertexCountFan, verticesFan, NULL, NULL, NULL, NULL, 0, paintLgyPoint);
线:
drawLine(x0, y0, x1, y1, paint)
//画线,起点(x0, y0), 终点(x1, y1), 使用paint作为画笔
SkPaint paintLgyLine;
paintLgyLine.setColor(SK_ColorRED);
canvas->drawLine(1, 7, 38, 7, paintLgyLine);
矩形
drawRect(rect, paint)
//画矩形,矩形大小由rect指定,画笔由paint指定
drawRectCoords(left, top, right, bottom, paint)
//给定4个边界画矩阵
drawRoundRect(rect, rx, ry, paint)
//画圆角矩形,x, y方向的弧度用rx, ry指定
//示例:
// 矩形
SkRect rectLgy;
rectLgy.iset(1, 9, 38, 11);
SkPaint paintLgyRect;
paintLgyRect.setColor(SK_ColorBLUE);
canvas->drawRect(rectLgy, paintLgyRect);
椭圆
drawOval(SkRect& oval, SkPaint& paint)
//画椭圆,椭圆大小由oval矩形指定
//示例:
// 椭圆
SkRect rectOval;
rectOval.iset(1, 15, 38, 19);
SkPaint paintOval;
paintOval.setColor(SK_ColorRED);
canvas->drawOval(rectOval, paintOval);
圆
drawCicle(cx, cy, radius, paint)
//给定圆心坐标和半径画圆
//示例:
// 圆
SkScalar radius((38-1)/2);
SkPaint paintCircle;
paintCircle.setColor(SK_ColorBLUE);
canvas->drawCircle(1+radius, 21+radius, radius, paintCircle);
弧线
drawArcSkRect& oval...)
//画弧线,类似画椭圆
//示例:
// 弧线
SkRect rectArc;
rectArc.iset(1, 64, 38, 64+20);
SkPaint paintArc;
paintArc.setColor(SK_ColorRED);
paintArc.setStyle(SkPaint::kStroke_Style);
//canvas->drawArc(rectArc, 0, 180, true, paintArc);
//canvas->drawArc(rectArc, 30, 180, true, paintArc);
canvas->drawArc(rectArc, 0, 180, false, paintArc);
路径
drawPath(path, paint)
//绘制路径,根据path指定路径绘制路径
//示例:
// 路径
SkPath path;
path.moveTo(SkPoint::Make(44,1));
path.lineTo(SkPoint::Make(50,19));
path.lineTo(SkPoint::Make(56,25));
path.lineTo(SkPoint::Make(62,22));
path.lineTo(SkPoint::Make(68,10));
path.lineTo(SkPoint::Make(74,5));
path.lineTo(SkPoint::Make(44,1));// 或者path.close();
SkPaint paintPath;
paintPath.setColor(SK_ColorRED);
paintPath.setStyle(SkPaint::kStroke_Style);
canvas->drawPath(path, paintPath);
位图
drawBitmap(SkBitmap& bitmap, left, top, paint = NULL)
//绘制指定的位图, paint可以为空
drawBitmapRect(bitmap, src, dest, paint=NULL)
//绘制给定位图由src指定区域,然后绘制截取部分位图到dest指定区域,可能进行缩放;
//第一个Rect是图片裁剪区域,第二个Rect是屏幕裁剪区域
drawBitmapMatrix(bitmap, matrix, paint=NULL),
//同上,可通过给定矩阵来裁剪和缩放变换
drawSprite(bitmap, left, top, paint=NULL)
//绘制位图,不受当前变换矩阵影响
drawPicture(SkPicture& picture)
//在画布上绘制图片,比较高效绘图函数
//示例:
// 位图
SkBitmap bitmap;
//FILE *p = fopen("E:\\test.png", "r");
bool ret = SkImageDecoder::DecodeFile("E:\\test.png", &bitmap);
if(ret){
//canvas->drawBitmap(bitmap, 44, 28);
// SkIRect src;
// SkRect dest;
// src.fLeft = 0;
// src.fTop = 0;
// src.fRight = 0 +bitmap.width();
// src.fBottom = 0 + bitmap.height();
// dest.fLeft = 44;
// dest.fTop = 28;
// dest.fRight = 44 +bitmap.width();
// dest.fBottom = 28 + bitmap.height();
// canvas->drawBitmapRect(bitmap, &src, dest);
//SkMatrix matrix;
// matrix.reset();// 矩阵初始化
//matrix.postRotate(30 );// 旋转
//matrix.postTranslate(44 , 28 );// 平移
// canvas->drawBitmapMatrix(bitmap, matrix);
//canvas->drawSprite(bitmap, 44, 28);
SkPicture picture;
SkCanvas* pCanvasLgy = picture.beginRecording(44 +bitmap.width(), 28 + bitmap.height());
pCanvasLgy->drawBitmap(bitmap, 44, 28);
picture.endRecording();
canvas->drawPicture(picture);
}
文字
drawText(void* text, byteLength, x, y, paint)
//以(x,y)为起始点写文字,文字存储在text指针内,长度由byteLength指定
drawPosText(...)
//功能同上,不过每个文字可以单独指定位置
drawPosTextH(...)
//功能同上,不过由一个变量指定了当前所有文字的统一Y坐标,即在同一条水平线上以不同的间隔写字
drawTextOnPath
drawTextOnPathHV
//以不同方式在给点定的path上面绘制文字
示例:
// 文字
SkPaint paintText;
paintText.setColor(SK_ColorBLUE);
SkTypeface* font = SkTypeface::CreateFromFile("C:\\Windows\\Fonts\\simkai.ttf");
paintText.setTypeface(font);
paintText.setTextSize(16);
char pszQq[] = "腾讯Qq";
WCHAR*strA;
int len = MultiByteToWideChar( CP_ACP, 0, (char*)pszQq, -1, NULL, 0);
strA = new WCHAR[len];
MultiByteToWideChar( CP_ACP, 0, (char*)pszQq, -1, strA, len);
len = WideCharToMultiByte(CP_UTF8,0,strA,-1,NULL,0,NULL,NULL);
char* strB = new char[len];
WideCharToMultiByte(CP_UTF8,0,strA,-1,strB,len,NULL,NULL);
SkPath pointPath;
pointPath.moveTo(SkPoint::Make(100,20));
for (unsigned int i = 1; i < strlen(strB); i++)
{
pointPath.lineTo(SkPoint::Make(100+20*i,20+4*i));
}
SkMatrix* pMatrixTextPath = new SkMatrix[strlen(strB)];
for (unsigned int i = 0; i < strlen(strB); i++)
{
pMatrixTextPath[i].reset();// 矩阵初始化
}
//pMatrixTextPath[0].postRotate(60);// 旋转
canvas->drawTextOnPath(strB, strlen(strB), pointPath, pMatrixTextPath, paintText);
delete [] pMatrixTextPath;
//canvas->drawTextOnPathHV(strB, strlen(strB), pointPath, 40, -10, paintText);
//strB即为所求
delete [] strA;
delete [] strB;
SkPaint
SkPaint保存绘制的风格和颜色信息:
函数 |
意思 |
---|---|
setAntiAlias |
设置画笔锯齿效果; |
setColor |
设置画笔颜色; |
setARGB |
设置画笔的a,r,p,g 值; |
setAlpha |
设置Alpha 值; |
setTextSize |
设置字体尺寸; |
setStyle |
设置画笔风格,空心或者实心; |
setStrokeWidth |
设置空心的边框宽度; |
getColor |
得到画笔的颜色; |
getAlpha |
得到画笔的Alpha 值. |
paintEffect.setAntiAlias(true);
颜色
paintEffect.setColor(SK_ColorRED);// 红色
填充样式
paintEffect.setStyle(SkPaint::kStroke_Style);// 空心 实心为kFill_Style
线宽
paintEffect.setStrokeWidth(6);
渐变色
// 设置渐变色
SkShader* shader = SkShader::CreateBitmapShader(bitmap,
SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode);
paintEffect.setShader(shader);
// 画圆形
canvas->drawCircle(190+30*2, 40, 30, paintEffect);
shader->unref();
SkBitmap
SkMatrix
public boolean setRectToRect(RectF src, RectF dst, Matrix.ScaleToFit stf)
//src 坐标变换前的矩形
//dst 坐标变换后的矩形
//stf 矩形缩放选项
由于提供坐标变换前后参数可为任意矩形,这样,变换前后矩形的长宽比不一定一样,提供指定Matrix.ScaleToFit
选项来确定缩放选项.Matrix.ScaleToFit定义了四种选项:
选项 |
意思 |
---|---|
CENTER |
保持坐标变换前矩形长宽比 ,并最大限度填充变换后矩形.至少有一边和目标矩形重叠. |
END |
保持坐标变换前矩形长宽比 ,并最大限度的填充变换后矩形.至少有一边和目标矩形重叠.END 提供右下对齐. |
FILL |
可能会变换矩形长宽比,保证变换和目标 矩阵长宽一致. |
START |
保持坐标变换前矩形的长宽比,并最大限度的填充变换后的矩形.至少有一边和目标矩形重叠.START 提供左上对齐. |
oid DrawArrow_lgy( SkCanvas* canvas )
{
SkPoint pointLineS = SkPoint::Make(130,40);// 线段起始点
SkScalar angleLine(300);// 角度 0 30 90 120 180 210 270 300 360
SkScalar lenLine(30);// 线段长度
SkScalar lenSideEquilateralTriangle(10);
SkPoint pointLineE;// 线段终止点
pointLineE.fX = pointLineS.fX+lenLine*cos(3.1415926*angleLine/180);// eX=sX+l*cosα
pointLineE.fY = pointLineS.fY+lenLine*sin(3.1415926*angleLine/180);// eY=sY+l*sinα
// 画线
SkPaint paintLine;
paintLine.setColor(SK_ColorBLACK);
canvas->drawLine(pointLineS.fX, pointLineS.fY, pointLineE.fX, pointLineE.fY, paintLine);
// 画等边三角形
SkPath pathEquilateralTriangle;
pathEquilateralTriangle.moveTo(SkPoint::Make(
pointLineE.fX+sin(3.1415926*angleLine/180)*10/2,
pointLineE.fY-cos(3.1415926*angleLine/180)*10/2));// (x1=eX+sinα*s/2,y1=eY-cosα*s/2)
pathEquilateralTriangle.lineTo(SkPoint::Make(
pointLineE.fX-sin(3.1415926*angleLine/180)*10/2,
pointLineE.fY+cos(3.1415926*angleLine/180)*10/2));// (x2=eX-sinα*s/2,y2=eY+cosα*s/2)
pathEquilateralTriangle.lineTo(SkPoint::Make(
pointLineE.fX+cos(3.1415926*angleLine/180)*10*sqrt(3)/2,
pointLineE.fY+sin(3.1415926*angleLine/180)*10*sqrt(3)/2));// (x3=eX+cosα*s*(Γ3)/2,y3=eY+ sinα*s*(Γ3)/2)
pathEquilateralTriangle.close();
SkPaint paintPathEquilateralTriangle;
paintPathEquilateralTriangle.setColor(SK_ColorBLACK);
paintPathEquilateralTriangle.setStyle(SkPaint::kFill_Style);
canvas->drawPath(pathEquilateralTriangle, paintPathEquilateralTriangle);
}
画鞋
void DrawBakerShoe_lgy( SkCanvas* canvas )
{
SkPoint pointRectS = SkPoint::Make(130,40);// 矩形起始点
SkScalar angleRect(300);// 角度 0 30 90 120 180 210 270 300 360
SkScalar lenRect(30);// 矩形长
SkScalar widthRect(10);// 矩形宽
SkScalar heightTrapezium(10);// 梯形高
SkScalar lenBottomSideTrapezium(36);// 梯形底边长
// 计算出矩形的另外三个顶点
SkPoint pointRectA;// 矩形A点
pointRectA.fX = pointRectS.fX+widthRect*cos(3.1415926*angleRect/180);// a(sX+w*cosα,
pointRectA.fY = pointRectS.fY+widthRect*sin(3.1415926*angleRect/180);//sY+w*sinα)
SkPoint pointRectB;// 矩形B点
pointRectB.fX = pointRectS.fX-lenRect*sin(3.1415926*angleRect/180);// b(sX-l*sinα,
pointRectB.fY = pointRectS.fY+lenRect*cos(3.1415926*angleRect/180);//sY+l*cosα)
SkPoint pointRectC;// 矩形C点
pointRectC.fX = pointRectB.fX+widthRect*cos(3.1415926*angleRect/180);// c(b.x+w*cosα,
pointRectC.fY = pointRectB.fY+widthRect*sin(3.1415926*angleRect/180);//b.y+w*sinα)
// 画矩形(鞋管)
SkPaint paintRect;
paintRect.setColor(SK_ColorBLACK);
paintRect.setStyle(SkPaint::kStroke_Style);
SkPath pathRect;
pathRect.moveTo(pointRectB);
pathRect.lineTo(pointRectS);
pathRect.lineTo(pointRectA);
pathRect.lineTo(pointRectC);
//pathRect.close();
canvas->drawPath(pathRect, paintRect);
// 计算出梯形的另外两个顶点 ,),点,;
SkPoint pointTrapeziumE;// 梯形E点
pointTrapeziumE.fX = pointRectC.fX-heightTrapezium*sin(3.1415926*angleRect/180);// e(c.x-h*sinα,
pointTrapeziumE.fY = pointRectC.fY+heightTrapezium*cos(3.1415926*angleRect/180);//c.y+h*cosα)
SkPoint pointTrapeziumD;// 梯形D点
pointTrapeziumD.fX = pointTrapeziumE.fX-lenBottomSideTrapezium*cos(3.1415926*angleRect/180);// d(e.x-s*cosα,
pointTrapeziumD.fY = pointTrapeziumE.fY-lenBottomSideTrapezium*sin(3.1415926*angleRect/180);//e.y-s*sinα)
// 画出梯形(鞋)
SkPaint paintTrapezium;
paintTrapezium.setColor(SK_ColorBLACK);
paintTrapezium.setStyle(SkPaint::kStroke_Style);
SkPath pathTrapezium;
pathTrapezium.moveTo(pointRectB);
pathTrapezium.lineTo(pointTrapeziumD);
pathTrapezium.lineTo(pointTrapeziumE);
pathTrapezium.lineTo(pointRectC);
//pathRect.close();
canvas->drawPath(pathTrapezium, paintTrapezium);
}