pdf示例.
SkDocument和SkCanvasAPI用Skia的PDF后端(SkPDF)的示例,[这里](https://fiddle.skia.org/c/@PDF docs/examples/PDF.cpp).
SkPDF限制
Skia的公共API有几个角落是SkPDF目前无法处理的,因为或没有已知的客户使用该功能,或没有简单的PDF式方法来处理它.
本文档中:
1,drop表示什么都不画.
2,忽略表明不带特效的绘画
3,expand表明按非PDF方式实现.表明
栅格化向量图形,扩展带路径特效的路径至多个单独路径,或转换文本为路径.
特效 | 文本 | 图 | 其他 |
|---|---|---|---|
SkMaskFilter | drop | ignore | ignore |
SkPathEffect | ignore | n/a | expand |
SkColorFilter | ignore | expand | ignore |
SkImageFilter | expand | expand | expand |
不支持SkXferModes | ignore | ignore | ignore |
非渐进SkShader | expand | n/a | expand |
注意:
1,SkImageFilter:展开SkImageFilter时,文本作为文本丢失.
2,SkXferMode:PDF自身不支持以下传输模式:
DstOver,SrcIn,DstIn,SrcOut,DstOut,SrcATop,DstATop和Modulate.
SkiaViewer
SkiaViewer显示一系列展示了Skia包括SkiaGM和允许交互的编程示例指定功能的幻灯片.此外,查看器还用来调试和理解Skia系统的不同部分.
1,观察渲染性能,按统计信息模式看查看器可显示平均帧时间
2,试不同的渲染方法,可在三个渲染方法之间循环:(在支持的平台上)光栅(raster),OpenGL和Vulkan.
可与统计信息模式一起使用此功能,以查看不同渲染方法对绘图性能的影响.
3,显示和操作你自己的图片.
某些幻灯片需要在程序外部存储的资源.在<skia-path>/resources目录中存储这些资源.
Linux,Macintosh和Windows
可用普通的GN构建进程构建查看器,如
bin/gn gen out/Release --args='is_debug=false' ninja -C out/Release viewer
要在桌面查看器中加载资源,用--resourcePath选项:
<skia-path>/out/Release/viewer --resourcePath <skia-path>/resources
同样,--skps <skp-file-path>加载该目录中的.skp文件,以便在查看器中显示.
其他有用的命令行选项:使用--match <pattern>加载仅与该名匹配的skp或幻灯片;使用--slide<name>在该幻灯片上启动;
你可用--backend,即--backend sw,--backend gl,--backend vk或--backend mtl来启动特定渲染方法.
用键盘和鼠标控制桌面查看器:左和右箭头在幻灯片间移动;上下箭头来放大和缩小;点击和拖动将平移.
可在工具UI中找到其他显示选项和幻灯片选取器,可通过按空格键切换.
d更改渲染操作.s显示渲染时间和图.空格切换显示.
安卓
要为安卓应用构建Viewer,请先按安卓构建说明设置AndroidNDK和ninja out目录.此外,还需要安装AndroidSDK并设置ANDROID_HOME环境变量.
mkdir ~/android-sdk( cd ~/android-sdk; unzip ~/Downloads/sdk-tools-*.zip )yes | ~/android-sdk/tools/bin/sdkmanager --licensesexport ANDROID_HOME=~/android-sdk
# 安装Android SDK的目录.
如果你不用AndroidSDK附带的NDK(在本例中为~/android-sdk/ndk-bundle),则需要设置环境变量为ANDROID_NDK_HOME,如:
export ANDROID_NDK_HOME=/tmp/ndk
必须由gradle构建查看器APK,可在命令行上调用以下脚本:
platform_tools/android/bin/android_build_app -C <out_dir> viewer
<out_dir>是创建的ninja out目录(如out/arm64).完成脚本后,可在<out_dir>/viewer.apk找到APK.用adb install安装.
如何使用应用
大多数应用功能(触摸手势和箭头按钮除外)都放在左侧抽屉中.点击左上角的汉堡包按钮以打开该抽屉.
切换幻灯片
在右上角,有两个箭头:下一张,上一张幻灯片.
左侧抽屉中,可直接从列表(微调器)中选择幻灯片.在该微调器上方,有一个应用至幻灯片列表的文本过滤器.有数百张幻灯片,如果知道幻灯片名,可用该过滤器快速找到并显示它.
缩放/翻译
支持幻灯片上的触摸手势,因此可拖动和捏合以缩放.
更改后端
在左侧抽屉中,可从OpenGL,Vulkan和Raster列表中选择后端.
软键/统计
在左边抽屉里,有一个软键列表.对应桌面查看器应用的键盘命令.如,可切换颜色模式或统计信息窗口.可像幻灯片一样过滤它们.
对动画幻灯片,还显示FPS(每帧秒数),以毫秒为单位的帧刷新率.
加载资源或skps
TODO(https://issues.skia.org/295805469):这曾经可通过以下说明实现,但它们不再适合最新版本的Android.
要在安卓查看器中加载资源,请在/data/local/tmp/resources中放置它们;要加载SKP,在/data/local/tmp/skps中放置它们.
iOS系统
用普通GN进程构建iOS上的查看器,如
bin/gn gen out/Release --args='target_os="ios" is_debug=false'ninja -C out/Release viewer
与其他iOS应用一样,可用ios-deploy这里等来部署,也可通过在Xcode中构建,并启动IDE来部署.
在顶级Skia目录中Viewer会自动绑定资源目录,如果也在Skia目录中放置skps目录,则会绑定skps目录.
在iOS上,查看器提供基本触摸功能:可查看幻灯片,在幻灯片之间轻扫,捏合缩放以缩放及通过平移翻译.尚不支持显示选项或从幻灯片列表中选择.
sksl与运行时特效
概述
SkSL是Skia的着色语言.SkRuntimeEffect是一个Skia的可用来创建行为由SkSL代码控制的SkShader,SkColorFilter和SkBlender对象的C++对象.
你可在https://shaders.skia.org/试用SkSL.语法与GLSL类似.在Skia应用中使用SkSL特效时,需要记住一些(与GLSL)重要的差异.
差异大多源于:使用GPU着色语言,你正在对GPU管道的一个阶段编程.使用SkSL,你正在对Skia管道的一个阶段编程.
即,GLSL片段着色器控制GPU在光栅化器和混合硬件之间的整个行为.该着色器负责计算颜色,再把生成的颜色填充到管道的固定函数混合阶段的颜色.
SkSL特效作为更大的Skia管道的一部分存在.当发出画布绘画操作时,Skia(一般)会组装单个GPU的片段着色器来完成工作.
此着色器一般包含多个部分.如,它可能包括:
1,求值像素是落在所绘画形状的内部还是外部(或在边框上,它可能会应用抗锯齿).
2,求值像素是落在剪切区域内还是外(同样,边界像素可能有抗锯齿逻辑).
3,SkPaint上SkShader的逻辑.(由于SkShaders::Blend和下面描述的其他特征)SkShader可以是对象树.
4,SkColorFilter的类似逻辑(由于SkColorFilters::Compose,SkColorFilters::Blend及下面描述的特征,也可以是树).
5,混合代码(对某些SkBlendModes,或用SkPaint::setBlender指定的自定义混合).
6,转换颜色空间代码,作为Skia管理颜色的一部分.
在SkShader,SkColorFilter或SkBlender字段中,即使SkPaint有复杂的对象树,也只有一个GPU片段着色器.
该树中的每个节点都会创建一个函数.裁剪和几何代码各自创建一个函数.混合代码可能会创建一个函数.然后,整个片段着色器调用所有这些函数(这些函数可能会调用其他函数,如在SkShader树时).
SkSL特效为GPU的片段着色器贡献了一个函数.
求值(采样)其他SkShader
在GLSL中,片段着色器可采样纹理.使用运行时特效时,(用C++)绑定的对象是一个由SkSL中的着色器表示的SkShader.
为表明,你正在操作发出自己的着色器代码的对象,请不要使用sample.相反,着色器对象有.eval()方法.
Skia有从SkImage创建SkShader的简单方法,因此在运行时特效中使用图像很容易.
因为绑定和计算的对象是SkShader,因此可直接用Skia着色器,而不必先转换为图像(纹理).如,可计算线性梯度.
此例中,没有创建纹理来保持渐变.Skia生成一个片段着色器,来计算渐变颜色,再从图像的纹理中采样,然后再两者相乘.
当然,甚至可调用另一个运行时特效,从而可动态组合着色器片段.
坐标空间
要了解坐标在SkSL中的工作原理,你首先需要了解它们在Skia中的工作原理.如果你对Skia的坐标空间感到满意,则记住,提供给main()的坐标是本地坐标.
它们相对于SkShader的坐标空间.匹配画布的本地空间和localMatrix转换.此外,如果另一个着色器调用着色器,则该父着色器可任意修改它们.
此外,从SkImage生成的SkShader(如GLSL中的纹理)不使用归一化坐标.它在左上角使用(0,0),在右下角使用(w,h).
一般,这正是你想要的.如果要使用基于传递给你的坐标来求值SkImageShader,则该比例是正确的.但是,如果要调整这些坐标(重新映射图像),请记住,把坐标放大到图像尺寸.
颜色空间
一般由颜色管理管理使用Skia的应用.表面(目标)的颜色空间决定了绘画的工作颜色空间.(如包括SkImageShader的着色器)源内容也有颜色空间.
默认,把SkSL着色器的输入转换为工作颜色空间.但是,某些输入需要特别小心才能获得(或抑制)此行为.
首先,看看Skia管理颜色的实际应用.在此,绘画了两次山魈图像的一部分.
第一次,正常绘画,尊重在文件中存储的(恰好是sRGB)颜色空间.
第二次,为图像赋值Rec.2020颜色空间.这仅告诉Skia按好像为该颜色空间来存储图像.然后,Skia将这些值从Rec.2020转换为目标表面的(sRGB)颜色空间.
因此,所有颜色都更加生动.更重要的是,如果图像确实在其他颜色空间中,或目标表面在其他颜色空间中,则该自动转换是值得的,因为它可确保在用户的屏幕上内容总是正确.
统一
Skia和SkSL不知道你的统一变量是否包含颜色,因此它不会自动转换应用颜色.下例中,声明了两个统一:
color和not_a_color.SkSL只是水平淡入两个统一"颜色"中的一个,为着色器的上半和下半部分选择不同的统一.该代码传递相同的值给两个统一,{1,0,0,1}四个浮点值表示"红色".
为了真正看到自动统一转换的特效,在Rec.2020颜色空间中的屏幕外表面绘画小提琴.Rec.2020有非常宽的色域,即可表示比常见的默认sRGB颜色空间更鲜艳的颜色.
特别是,与Rec.2020中的纯红色相比,sRGB中最纯的红色相当暗淡.
为了理解它,解释两种不同情况下的步骤.对上半部分,使用not_a_color.Skia和SkSL不知道你打算将它用作颜色,因此直接把提供的原始浮点值传递给SkSL着色器.
即,当SkSL执行时,不论表面的颜色空间,not_a_color包含{1,0,0,1}.这会在目的颜色空间中产生最鲜艳的红色(此时,最终像非常鲜艳的红色).
对下半部分,用特殊的layout(color)语法声明了统一颜色.告诉SkSL该变量将用作颜色.只能在vec3(即RGB)或vec4(即RGBA)的统一值上用layout(color).
总之,提供统一数据时,提供的颜色都应是未预乘的sRGB颜色.如果提供广色域颜色,它们可包含[0,1]区间外的值.
与Skia在SkPaint上接受和存储颜色的方式相同.当SkSL执行时,Skia会把统一值转换为工作颜色空间.此时,即把(开始时为sRGB红色)颜色转换为表示Rec.2020颜色空间中相同颜色的值.
总体特效是使正确标记的统一更加暗淡,但这是在使用统一颜色时想要的.这样标记统一颜色,不论目标表面的颜色空间,(放在统一中的颜色)源颜色表示相同且一致的颜色.
原始图像着色器
尽管大多数图像都包含应管理颜色的颜色,但某些图像包含的数据不是颜色.这包括存储法线,材料属性(如粗糙度),高度图或恰好存储在图像中的其他纯数学数据的图像.
在SkSL中使用这类图像时,想用用SkImage::makeRawShader创建的原始图像着色器.它们(包括过滤和平铺)的工作方式与普通图像着色器类似,但有一些主要区别:从未转换颜色空间(忽略图像的颜色空间).
不会自动预乘alpha类型为kUnpremul的图像.不支持双三次过滤.调用makeRawShader时,请求双三次过滤,会返回nullptr.
在此,创建包含球面法线贴图的图像.然后,用浅着色器来显示渲染到不同颜色空间时的情况.如果使用普通图像着色器,会把法线颜色转换为工作颜色空间.
这会错误地改变法线.最后绘画中,使用忽略工作颜色空间并返回原始法线的原始图像着色器.
在已知颜色空间中工作
在SkSL着色器中,你不知道工作颜色空间.对许多特效,这没事.求值图像着色器,简单颜色数学运算,一般正确(如,如果知道应用的工作颜色空间总是是sRGB).
但是,对某些特效,在固定的已知颜色空间中搞一些数学运算可能很重要.最常见示例是照明,为了获得物理上准确的照明,应该在线性颜色空间中完成数学运算.
为此,SkSL提供了两个内部函数:
vec3 toLinearSrgb(vec3 color);
vec3 fromLinearSrgb(vec3 color);
它们在工作和线性sRGB颜色空间之间转换颜色.该空间使用sRGB原色(色域)和线性传递函数.它使用扩展区间值(低于0.0和高于1.0)表示sRGB色域之外的值.
如,这对应安卓的LINEAR_EXTENDED_SRGB或Apple的extendedLinearSRGB这里和这里.
如可在(sRGB)默认工作空间中完成照明数学运算,并在线性空间中再次数学运算.
预乘Alpha
处理透明颜色时,有两个(常见的)可能的表示.Skia称为非预乘和预乘.在Skia管道中,每个SkShader都会返回预乘的颜色.
如果熟悉OpenGL混合,则可当作混合等式.对常见的alpha混合(叫source-over),一般配置混合函数为(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA).
Skia混合源过度定义为(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)混合函数.
Skia使用预乘alpha表明:
1,如果从未预乘的SkImage(如PNG)开始,请转换其为SkImageShader,并计算该着色器,生成颜色将是[R*A,G*A,B*A,A],而不是[R,G,B,A].
2,如果SkSL返回透明颜色,则必须确保用A乘以RGB.
3,对更复杂着色器,必须了解哪种颜色是预乘与未预乘.如果混合两个颜色在一起,许多操作就没有意义.
可随着alpha的减少,正确预乘颜色会产生平滑渐变.未预乘的颜色会导致错误显示渐变,变得太亮,并随alpha变化而改变色调.
减小SkSL
Skia包含一个压缩器工具,可自动减小RuntimeEffect或SkMesh代码的大小.它消除了空格和注释,缩短了函数和变量名,并删除了未引用代码.
要启用此工具,请添加skia_compile_modules=true到gn参数列表中.(在命令行中,键入gn args out/yourbuild以访问参数,或直接编辑out/yourbuild/args.gn文件.
使用ninja再次编译Skia,现在输出目录中将有叫sksl-minify的新工具.
在缩小网格程序时,必须提供与SkMeshSpecification对应的struct Varyings和struct Attributes.为了方便,会从缩小程序中删除这些结构.
sksl-minify带以下命令行参数:
1,输出路径,如MyShader.minified.sksl
2,输入路径,如MyShader.sksl
3,(可选)传递--stringify以在带引号的C++串中包装缩小的SkSL文本.默认,输出文件包含普通SkSL.上面示例代码中缩小的着色器串是使用--stringify创建的.
4,(可选)传递--shader,--colorfilter,--blender,--meshfrag或--meshvert来设置程序类型.默认值为--shader.