skia是个2D向量图形处理函数库

时间:2023-02-05 11:13:29

【原创文章,转载请保留或注明出处:http://blog.csdn.net/yinyhy/article/details/9963273

概述

skia是个2D向量图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现。不仅用于Google Chrome浏览器,新兴的Android开放手机平台也采用skia作为绘图处理,搭配OpenGL/ES与特定的硬件特征,强化显示的效果。

发展过程

自2005年Skia被Google收购后,一直相当神秘低调,直到2007年初,Skia GL相关的源代码才被揭露,作为Google Android平台的图形引擎,稍后的Google Chrome浏览器也采用Skia引擎。随着Android与Chrome (开放版本称为"Chromium")两大专案公布源代码后,Skia也一并公开原始源代码,以Apache License v2发布(注意,这意味着与GPLv2授权不相容) ,而Android与Chrome的源代码库中都有一份[Skia]的复制,因需求不同,做了部份的修改,比方说Chrome专案底下的  [chrome/trunk/src/skia],需要注意的是,Skia本身是不涉及底层环境,如Linux Framebuffer或Gtk+衔接的处理,这也是何以Android (透过Linux Framebuffer)与Chrome (开发中的Linux版本使用Gtk+)需要提供一份修改,以便系统接轨。

目录结构

skia是个2D向量图形处理函数库

Skia引擎在android源代码库当中的位置

头文件(也可以说是internal API, 因为google没有在NDK里面提供他)位置:android/external/skia/include

源文件位于: android/external/skia/src

封装层:android对Skia引擎进行了封装,以便让java代码方便的调用,对skia封装的代码存在于android/framework/base/core/jni以及android/framework/base/core/jni/android/graphics目录下面。主要是对Canvas, Bitmap, Graphics, Picture等等的封装,以及和libui库的结合使用。

Skia主要包含三个库

libcorecg.so:包含/skia/src/core的部分内容,比如其中的RegionRect是在SurfaceFlinger里面用来计算可视区域的。

libsgl.so:包含/skia/src/core|effects|images|ports|utils的部分和全部内容,这个实现了skia大部分的图形效果,以及图形格式的编解码。
libskiagl.so:
包含/skia/src/gl里面的内容,主要用来调用opengl实现部分效果。

Skia对上层的接口

Skia的源文件及部分头文件都在external/skia/src目录下,导出的头文件在external/skia/include目录下。最主要的是SKCanvas类,几乎整个Android GUI系统的底层绘制都是由这个类来完成的。

SKCanvas类主要有三种绘制功能:

a基本图形绘制(drawARGB,drawLine函数)

b图像文件绘制(drawBitmap函数)

c文本绘制(drawText函数)

Skia的图像编解码部分

这部分的接口主要是:

external/include/image/SKImageDecoder.h // 把图像文件或者流解码到skia的内部内存SKBitmap中;

external/include/image/SKImageEncoder.h // skia内部内存SKBitmap编码成文件或流的形式;

这些接口需要具体的类实现,主要代码在src/image文件中。

Android图形系统的JNI接口

主要提供了从Skia底层库到Java上层的支持,代码路径为:

frameworks/base/core/jni/android/graphic/

主要为Canvas.cpp文件。

Android的图形包 

Android图形类的包是android.graphics,它通过调用图形系统的JNI提供了对Java框架中图形系统的支持,在AndroidJava框架中和Java应用程序中,2D绘制的功能(基本图形、图片文件,文字)也是通过调用它来实现的。代码路径为:

frameworks/base/graphics/java/android/graphics/

其中Canvas.cpp文件实现了Android图形系统中最重要的一个类android.graphic.canvas

Android2D图形硬件加速 

目前Android 2D图形硬件加速主要是通过copybit模块来实现,Copybit是封装在Android系统opengl软件实现库(libagl)的一部分,仅对openGL ES 2D API进行封装,实现openGL ES 2D API到硬件的加速功能。

copybit模块以HAL的形式实现,代码hardware/msm7k/libcopybit/copybit.c

源码结构说明

Skia的源代码主要位于external\skia目录下。与Firefox采用的Cairo相比,Skia更加小而高效,接口也更加简洁。

external\skia\src\animator目录下的文件用来实现Skia的动画效果,分为Animator、Display、Draw、SkScript等逻辑模块。其中Animator部分包括SkAnimatorActive、SkAnimatorBase、SkAnimatorField、SkAnimatorSet、SkAnimatorScript等;Display 部分包括SkDisplayAdle、SkDisplayAdd、SkDisplayEvents、SkDisplayList、SkDisplayInput、SkDisplayMovie等;Draw部分包括SkDraw3D、  SkDrawBitmap、SkDrawClip、SkDrawColor、SkDrawBlur、SkDrawLine、SkDrawPaint、SkDrawPath、SkDrawPoint等;SkScript部分包括SkScript、SkScriptRuntime、SkScriptDecompile等。

external\skia\src\core目录下的文件为Skia的核心部分,执行图形绘制功能,主要类包括SkColor、SkCanvas、SkBitmap、SkPicture、SkBlitter、SkCordic、SkPath、SkPoint、SkRect、SkRegion、SkMask 等。

external\skia\src\gl目录下的文件实现了Skia的图形库。其引擎为Open GL或者 Open GL ES,用于实现一些简单的3D效果。

external\skia\src\images目录下的文件实现了Skia的图像部分。支持常见图像的解码、部分图像的编码和动画等。

external\skia\src\ports目录下的文件定义了Skia的移植封装接口,包括Font、Event、File、Thread、Time、XMLParser等。

external\skia\src\svg目录下的文件实现了Skia对矢量图像SVG的支持。

external\skia\src\utils目录下的文件实现了Skia的一些辅助工具,包括SkCamera、SkColorMatrix、SkOSFile、SkProxyCanvas、SkInterpolator等。

external\skia\src\views目录下的文件实现了Skia的界面UI库,控件包括Window、Menu、TextBox、ListView、ProgressBar、Widget、 ScrollBar、TagList、Image等。目前Skia的UI库暂未被Android使用。

external\skia\src\xml目录下的文件实现了Skia对XML的DOM、解析器的封装。具体的XML解析器的实现需要根据不同的操作系统及宿主程序来实现。相关的类包括SkDOM、SkDOMNode、SkDOMAttr、SkXMLParser、SkXMLParserError、SkXMLPullParser、SkDisplayXMLParser、SkXMLWriter、SkXMLStreamWriter、SkXMLAnimatorWriter等。相关的实现位于external\skia\src\xml目录下。

重要类简介

(1)SkCanvas

这个类是Skia引擎的一个核心类,他封装了所有对设备进行的画图操作。这个类自身包含了一个设备的引用,以及一个矩阵和裁剪栈。所有的画图操作,都是在经过栈内存放的矩阵变幻之后才进行的(这点和OpenGL类似)。当然,最终显示给用户的图像,还必须经过裁剪堆栈的运算。
SkCanvas记录着整个设备的绘画状态,而设备上面绘制的对象的状态又是由SkPaint类来记录的,SkPaint类作为参数,传递给不同SkCanvas类的成员函数drawXXXX().(比如:drawPoints, drawLine, drawRect, drawCircle)。SkPaint类里记录着如颜色(color),字体(typeface),文字大小(textSize),文字粗细(strokeWidth),渐变(gradients, patterns)等。
SkCanvas类的主要成员函数:
> 构造函数,给定一个Bitmap或者Device,在给定的这个对象上进行画图,Device可以为空。
            SkCanvas(const SkBitmap& bitmap);
            SkCanvas(SkDevice* device = NULL);
> setViewport, getViewport, 这2个函数只有在支持OpenGL视图时才有效。
> save, saveLayer, saveLayerAlpha, restore,这4个函数用于保存和恢复显示矩阵,剪切,过滤堆栈,不同函数有不同的附加功能。
> 移位,缩放,旋转,变形函数。
            translate(SkiaScalar dx, SkiaScalar dy);
            scale(SkScalar sx, SkScalar sy);
            rotate(SkScalar degrees);
            skew(SkScalar sx, SkScalar sy);
>  指定具体矩阵,进行相应的变换的函数,以上4个方法都可以通过定义特定的矩阵,再调用此函数实现。
            cancat(const SkMatrix& matrix);
>  图像剪辑,把指定的区域显示出来。
            clipRect(SkRect&...);
            clipPath(SkPath&...);
            clipRegion(SkRegion&...);
 > 在当前画布内画图,有以下多种画图方式:
            drawARGB(u8 a, u8 r, u8 g, u8 b....) 给定透明度以及红,绿,兰3色,填充整个可绘制区域。
            drawColor(SkColor color...) 给定颜色color, 填充整个绘制区域。
            drawPaint(SkPaint& paint) 用指定的画笔填充整个区域。
            drawPoint(...)/drawPoints(...) 根据各种不同参数绘制不同的点。
            drawLine(x0, y0, x1, y1, paint) 画线,起点(x0, y0),终点(x1, y1), 使用paint作为画笔。
            drawRect(rect, paint) 画矩形,矩形大小由rect指定,画笔由paint指定。
            drawRectCoords(left, top, right, bottom, paint), 给定4个边界画矩阵。
            drawOval(SkRect& oval, SkPaint& paint) 画椭圆,椭圆大小由oval矩形指定。
            drawCicle(cx,cy,radius, paint), 给定圆心坐标和半径画圆。
            drawArcSkRect& oval...) 画弧线,用法类似于画椭圆。
            drawRoundRect(rect, rx, ry, paint) 画圆角矩形,x,y方向的弧度用rx,ry指定。
            drawPath(path, paint) 路径绘制,根据path指定的路径绘制路径。
            drawBitmap(SkBitmap& bitmap, left, top, paint = NULL) 绘制指定的位图,paint可以为空。
            drawBitmapRect(bitmap, src, dest, paint=NULL),绘制给定位图的一部分区域,此区域由src指定,然后把截取的部分位图绘制到dest指定的区域,可能进行缩放。
            drawBitmapMatrix(bitmap, matrix, paint=NULL),功效同上,可以通过给定矩阵来进行裁剪和缩放变换。
            drawSprite(bitmap, left, top, paint=NULL),绘制位图,不受当前变换矩阵影响。
            drawText(void* text, byteLength, x,y,paint),以(x,y)为起始点写文字,文字存储在text指针内,长度有byteLength指定。
            drawPosText(...) 功能同上,不过每个文字可以单独指定位置。
            drawPosTextH(...) 功能同上,不过由一个变量指定了当前所有文字的统一Y坐标,即在同一条水平线上以不同的间隔写字。
            drawTextOnPathHV, drawTextOnPath, drawTextOnPath, 以不同方式在给点定的path上面绘制文字。
            drawPicture(SkPicture& picture) 在画布上绘制图片,比较高效的绘图函数。
            drawShape(SkShape*) 在画布上绘制指定形状的图像。
            drawVertices(...) 绘制点,可以有纹理,颜色,等附加选项。

(2)SkBitmap

(3)SkTypeface