Skia
使用的所有颜色空间,通过如何从该颜色空间
,转换为叫XYZD50
的通用"连接"
颜色空间,来描述
自己.可从相同
描述中,推导出如何从XYZD50
空间转换回原颜色空间
.
XYZD50
是像RGB
一样以三维
表示的颜色空间,但XYZ
部分则根本不像RGB
,而是这些通道
的线性混杂.Y
最接近你认为的亮度
,但X和Z
则更抽象.
如果熟悉,这类似YUV
."D50"
部分指的是该空间大约5000
开尔文的白点
.
所有管理颜色
绘图分为六个部分
,三个步骤
连接源颜色
到该XYZD50
空间,然后三个对称步骤
从XYZD50
连接回目标颜色空间
.
一些步骤可约掉
.步骤如下:
1,如果源颜色
是预乘
的,则取消乘法
,α
不参与管理颜色
,如果乘了
它,就要除掉.
2,使用源颜色空间
的传递
函数来线性化源颜色
3,通过乘以3x3
矩阵,把这些未预乘
的线性源颜色
转换为XYZD50
色域.
4,通过乘以3x3
矩阵,来转换这些XYZD50
颜色到目标色域
.
5,用目标颜色空间
的传递函数
的逆函数
编码该颜色
.
6,如果目的
是预乘
的,则按α
预乘.
该逻辑在SkColorSpaceXformSteps
类型中.会看到它有5个
步骤:总是合并最里面
的两个运算
为一个3x3
矩阵乘法.
画画时,跳过基本无操作
步骤:
1,如果已去掉预乘源
则跳过1
.
2,如果已线性编码
源,则跳过2
3,如果单个连接矩阵
是相同(即源和目标
颜色空间带相同
色域),则跳过3
和4
4,如果目标需要线性编码
,则跳过5
5,如果目标想要去掉预乘
,则跳过6
更高级优化:
1,如果已跳过3
和4
,则传递函数
相同时,可跳过2
和5
.通过给定传递函数
发送颜色,它自己
的逆是无操作的
2,如果跳过了2-5
的所有步骤,如果要同时
做1和6
,则可跳过1
和6
,不必去掉预乘
,再预乘
.
3,根据可允许跳过更多
步骤,来按未预乘或预乘
对待不透明的颜色
.
多数时候,都是"闲着
".如果要把给定
颜色空间中的不透明颜色
绘画到使用相同
颜色空间标记的目标位置
,会注意到可跳过
所有这六个步骤.
一般,如果需要转换色域
,应期望所有6步都有.2和5
是计算成本
最高的.
SkColorSpace
默认值现在空针SkColorSpace
默认值如何融入所有这些?用该小片段
作为序言:
if (srcCS == nullptr) { srcCS = sRGB; }
if (dstCS == nullptr) { dstCS = srcCS; }
顺序
很重要.要点是,假设未标记
来源都是sRGB
.如果未标记你的表面
,就会表现得好像目的地与你绘画的来源
流畅匹配,这至少跳过了上面列举的2-5
步骤,保持了与引入
管理颜色前,复古的Skia
过去的工作方式兼容的非管理颜色绘画模式
.
它不是很有原则,但维护很方便.
Skia
一般有两个不同坐标空间
:设备和本地
坐标空间.设备坐标
由要渲染的表面
(或其他设备
)定义.它们从表面
左上角的(0,0)
到右下角的(w,h)
,它们以像素
为单位测量.
本地坐标
空间是向SkCanvas
提供几何图形
和着色器
的方式.默认,本地和设备
坐标系相同.即几何图形
一般按像素
指定.
在此,在(100,50)
定位矩形
,并指定它的宽高.
本地坐标
还定义和求值
绘画上的SkShader
.在此,定义了线性渐变
着色器,从绿色(当x==0
时)到蓝色(当x==50
时).
现在,试在(100,50)
处绘画渐变填充
正方形.
记住,本地坐标
空间没有改变.原点仍在曲面
的左上角.应在(100,50)
定位已指定
几何图形,但当x
从0
变为50
时,SkShader
仍产生梯度
.
滑动矩形
到SkShader
定义渐变
中.着色器
不会随几何图形
移动.
为了获得期望效果,可移动位置到100
和150
,来创建新的渐变着色器
.但使着色器
难以重用.相反,可用SkCanvas
上的方法来更改
本地坐标空间
.
这会在画布
变换矩阵定义的新空间
中求值,所有本地坐标
(几何体和着色器
).
最后,可转换相对画布
本地坐标空间的SkShader
的坐标空间
.为此,在创建SkShader
时提供localMatrix
参数.
此时,由SkCanvas
矩阵转换
几何图形.由SkCanvas
矩阵和该着色器的localMatrix
变换SkShader
.另一个视角:localMatrix
定义了一个映射着色器的坐标
到几何体
坐标空间的转换
.
如,这里是渐变填充框
.它首先平移了50
个单位.然后,(在盒子中心
)45
度旋转
画布.旋转盒子的几何形状,及其中的渐变.
比较第二个示例.仍平移50
个单位.不过,在此,仅按SkGradientShader::MakeLinear
函数的localMatrix
,旋转
着色器45
度.现在,该框
保持未旋转
状态,但在该框内旋转了渐变
.
depot_tools
和Git
按安装Chromium
的depot_tools
中的说明下载depot_tools
(包括gclient,git-cl
和Ninja
).以下是摘要.
git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git'
export PATH="${PWD}/depot_tools:${PATH}"
(如果尚未安装)depot_tools
还在系统
上安装Git
.
bazelisk
如果要添加或删除
文件或更改#include
,则要用Bazel
重新生成BUILD.bazel
文件的某些部分
.建议安装为你(由bazelversion
指定)选取适当的Bazel
版本的Bazelisk
这里,而不是手动安装Bazel
这里.
ninja
可用gclient
或bin/fetch-ninja
提供Ninja
.
Skia
仓库可用git
或随depot_tools
一起安装的fetch
工具克隆Skia
.
git clone https://skia.googlesource.com/skia.git
# //或
# fetch skia
cd skia
python3 tools/git-sync-deps
bin/fetch-ninja
Skia
现在可能想要构建Skia
这里构建步骤.