Skia 开源图形库:源码实现的规范与算法
简介
Skia 是一个完整的开源 2D 图形库,由 Google 维护,提供跨平台的硬件加速 2D 渲染能力。它是 Google Chrome / Chromium、Android、Flutter、Firefox 等主要项目的底层图形引擎。Skia 支持 CPU 软件渲染(通过优化的光栅化管线)和 GPU 硬件加速(通过 Vulkan / Metal / OpenGL / Direct3D / Dawn 等后端)。
Skia 并非一个简单的 API 封装层,而是一个实现了大量图形学规范和算法的独立引擎,涵盖路径几何、颜色科学、排版布局、图像编解码、动画合成等领域。
此文档由deepseek V4 flash AI生成,发布者不承担任何责任。
版本
本文档基于 Skia Milestone 148(Chromium M148 对应版本):
- 版权起始:2006 The Android Open Source Project
- 源码基线:
skia-main(GitHub 主分支),编译标记SK_MILESTONE 148 - 许可证:BSD 3-Clause ("Skia BSD-like license")
Skia 的里程碑号与 Chromium 版本号对齐,从中可以推断代码的大致时间线。版本演进轨迹见 RELEASE_NOTES.md。
一、核心渲染规范与算法
1.1 画布模型(Canvas Model)
规范来源:PostScript / PDF 图形模型 + SVG 状态栈
源码入口:SkCanvas.h、SkCanvas.cpp
SkCanvas 实现了一个状态机模型,包含:
- 矩阵栈(Matrix Stack):通过
save()/restore()管理变换矩阵的推入与弹出。支持的变换类型包括 translate、scale、rotate、skew、perspective(4x4 齐次矩阵SkM44)。矩阵栈深度无硬限制。 - 裁剪栈(Clip Stack):裁剪路径可以是非矩形的任意 SkPath,支持 Winding 和 Even-Odd 填充规则。裁剪操作通过
SkClipOp::kIntersect(求交)和SkClipOp::kDifference(求差)叠加。裁剪栈与矩阵栈同步保存和恢复。 - 绘制状态(Paint State):每个绘制调用携带一个
SkPaint对象,控制颜色、透明度、抗锯齿、描边/填充模式、着色器、图像滤镜、颜色滤镜、遮罩滤镜、路径特效、混合模式等。
算法:变换矩阵采用列优先顺序 —— 后加入的变换先作用于图形(与 PostScript 一致)。裁剪坐标始终在设备空间执行,以确保精确的像素级裁剪。
1.2 绘制管线(SkPaint Drawing Pipeline)
规范来源:SVG 2.0 绘制模型 + W3C Compositing and Blending Level 1
源码入口:SkPaint.h、SkPaint.cpp
SkPaint 的绘制管线依次处理以下阶段:
原始几何 → PathEffect → 变换矩阵 → Rasterize → MaskFilter
→ Shader → ColorFilter → BlendMode → 帧缓冲
各阶段说明:
| 阶段 | 类/接口 | 实现规范 | 算法 |
|---|---|---|---|
| PathEffect | SkPathEffect | 几何预处理 | dashing (SkDashPathEffect)、离散化 (SkDiscretePathEffect)、转角 (SkCornerPathEffect) |
| 光栅化 | 内部 | 抗锯齿扫描转换 | 亚像素精度边缘追踪、AAClip 算法 |
| MaskFilter | SkMaskFilter | 模糊/阴影 | 高斯模糊 (SkBlurMaskFilter)、基于分离式 Box Blur 的快速近似 |
| Shader | SkShader | 像素填充 | 线性渐变(SkGradientShader::MakeLinear)、径向渐变(MakeRadial)、锥形渐变(MakeSweep)、卷积(MakeConical)、柏林噪声(SkPerlinNoiseShader)、图像平铺(SkTileMode) |
| ColorFilter | SkColorFilter | 像素后处理 | 颜色矩阵、高对比度滤镜、亮度滤色器、运行时自定义 |
| BlendMode | SkBlendMode | Porter-Duff + 高级混合 | 共 29 种混合模式(见 1.3 节) |
1.3 混合模式(Blend Modes)
规范来源:Porter-Duff Compositing (Computer Graphics, 1984) + W3C Compositing and Blending Level 1 + SVG 1.2
源码入口:SkBlendMode.h
Skia 实现了 29 种混合模式,分为三类:
Porter-Duff 系数模式(12 种,kClear ~ kScreen):
kClear、kSrc、kDst、kSrcOver、kDstOver、kSrcIn、kDstIn、kSrcOut、kDstOut、kSrcATop、kDstATop、kXor、kPlus、kModulate、kScreen
可分离高级模式(7 种,kOverlay ~ kMultiply):
kOverlay、kDarken、kLighten、kColorDodge、kColorBurn、kHardLight、kSoftLight、kDifference、kExclusion、kMultiply
不可分离 HSL 模式(4 种,kHue ~ kLuminosity):
kHue、kSaturation、kColor、kLuminosity
混合系数由 SkBlendModeCoeff 枚举定义,每模式对应 (srcCoeff, dstCoeff) 两个系数,公式为 result = srcCoeff * src + dstCoeff * dst。HSL 模式在 HSL 颜色空间中混合色相、饱和度、亮度。
二、路径与几何(Path & Geometry)
2.1 路径类型与填充规则
规范来源:SVG 2.0 Paths + OpenVG 1.1 + PostScript path
源码入口:SkPathTypes.h、SkPath.h
路径段类型(SkPathVerb):
| 类型 | 控制点数 | 说明 |
|---|---|---|
kMove | 1 | 移动到新起点 |
kLine | 2 | 直线段 |
kQuad | 3 | 二次贝塞尔曲线 |
kConic | 3 + weight | 二次有理贝塞尔(圆锥曲线) |
kCubic | 4 | 三次贝塞尔曲线 |
kClose | 0 | 闭合当前子路径 |
填充规则(SkPathFillType):
| 规则 | 枚举值 | 算法 |
|---|---|---|
kWinding | 默认 | 非零环绕数:射线从点向右发射,每条顺时针过射线线段 +1,逆时针 -1,和为 0 则外部 |
kEvenOdd | 1 | 奇偶规则:射线穿过奇数条线段则内部 |
kInverseWinding | 2 | Winding 的反选 |
kInverseEvenOdd | 3 | EvenOdd 的反选 |
2.2 几何计算算法
源码目录:src/core/
| 算法 | 文件 | 说明 |
|---|---|---|
| 贝塞尔曲线求值 | SkGeometry.cpp | 二次/三次贝塞尔的 De Casteljau 算法、霍纳法、速度/加速度/曲率计算 |
| 贝塞尔分割 | SkGeometry.cpp | 递归细分至平坦度阈值 |
| 曲线相交 | SkGeometry.cpp | 贝塞尔裁剪算法(Bezier Clipping) |
| 曲线光栅化 | SkAnalyticEdge.cpp | 亚像素精度边缘追踪 |
| 三角形扇 | SkEdgeBuilder.cpp | 将复杂路径分解为单调扫描线段 |
| 裁剪(Clipper) | SkEdgeClipper.cpp | Sutherland-Hodgman 多边形裁剪 |
| 梯形/三角形填充 | SkScan.cpp | 活性边表算法(Active Edge Table, AET) |
| AABitmap 裁剪遮罩 | SkAAClip.cpp | 亚像素精度反走样裁剪区域生成 |
| 矩阵求逆 | SkMatrixInvert.cpp | Gauss-Jordan 消元法,行列式为零时返回不可逆 |
| 直线裁剪 | SkLineClipper.cpp | Cohen-Sutherland 线段裁剪算法 |
| 圆形/椭圆 | SkPath.cpp | 利用四段三次贝塞尔近似椭圆弧 |
2.3 路径运算(PathOps)
规范来源:Computational Geometry (Boolean operations on polygons)
源码入口:SkPathOps.h、src/pathops/
支持的五种布尔运算:
| 运算 | 枚举值 | 说明 |
|---|---|---|
kDifference | 0 | A - B |
kIntersect | 1 | A ∩ B |
kUnion | 2 | A ∪ B |
kXOR | 3 | A ⊕ B |
kReverseDifference | 4 | B - A |
实现算法:Bentley-Ottmann 平面扫描算法(扫描线 + 事件队列),用于检测所有线段间的交点。算法复杂度 O((n + k) log n),其中 n 为线段数,k 为交点数。modules/bentleyottmann/ 有独立的 Bentley-Ottmann 算法实现,提供概念验证和测试基准。
路径运算结果会自动降阶:三次贝塞尔 → 二次贝塞尔 → 直线段,以减少后续处理的计算量。
2.4 路径效果(Path Effects)
规范来源:SVG 1.1 stroke-dasharray + 自定义效果
源码入口:include/effects/
| 效果 | 类 | 算法 |
|---|---|---|
| 虚线 | SkDashPathEffect | 沿路径弧长累积,分段截取 on/off 交替 |
| 离散化 | SkDiscretePathEffect | 线段随机抖动,产生手绘效果 |
| 圆角 | SkCornerPathEffect | 用圆弧替换尖角 |
| 1D 贴图 | Sk1DPathEffect | 沿路径贴图 1D 图案 |
| 2D 贴图 | Sk2DPathEffect | 在路径包围盒上贴图矩阵变换图案 |
| 修边 | SkTrimPathEffect | 按比例截取路径首尾段 |
三、颜色科学(Color Science)
3.1 颜色空间管理
规范来源:ICC.1:2010 (Profile Version 4.3) + IEC 61966-2-1 (sRGB) + ITU-R BT.709/BT.2020 + SMPTE ST 2084 (PQ) + IEC 61966-2-4 (Display P3)
源码入口:SkColorSpace.h、modules/skcms/
Skia 通过内嵌子模块 skcms(Skia Color Management System)实现完整的颜色管理管线。skcms 是独立于 Skia 主库的 C 语言颜色科学库。
内置标准色域(SkNamedPrimaries,来自 ITU-T H.273 Table 2):
| 色域名 | 规范来源 |
|---|---|
kRec709 | ITU-R BT.709-6 |
kRec2020 | ITU-R BT.2020-2 |
kSrgb | IEC 61966-2-1 |
kDisplayP3 | Display P3 (Apple) |
kSMPTE_ST_428 | DCI-P3 (SMPTE ST 428-1) |
kAdobeRGB | Adobe RGB (1998) |
kCie1931 | CIE 1931 XYZ |
kACES | Academy Color Encoding System AP0 |
kAP1 | Academy Color Encoding System AP1 |
kNTSC_1953 | NTSC 1953 |
kSMPTE_C | SMPTE-C |
传递函数(skcms_TransferFunction):
使用 7 参数分段函数建模,统一框架可表达:
linear = sign(encoded) * (c * |encoded| + f) , 0 <= |encoded| < d
= sign(encoded) * ((a * |encoded| + b)^g + e) , d <= |encoded|
这个数学模型可以精确表示 sRGB、BT.1886(Rec.709/Rec.2020 的 EOTF)、PQ (ST 2084)、HLG (ARIB STD-B67) 等标准传递函数。
支持的曲线格式:
skcms_TFType_Parametric— 参数化传递函数(7 参数模型)skcms_TFType_Tablified— 表格化 LUTskcms_TFType_PQ— SMPTE ST 2084skcms_TFType_HLG— ARIB STD-B67 (Hybrid Log-Gamma)skcms_TFType_HLGinv— HLG 逆函数skcms_TFType_sRGBish— 带自定义 gamma 修正的 sRGB
色彩转换管线:
源颜色空间 → XYZ D50 中间空间 → 目标颜色空间
通过 toXYZD50 + 传递函数 → XYZ D50 → 通过 fromXYZD50 + 逆传递函数
3.2 高动态范围(HDR)支持
规范来源:SMPTE ST 2094-50 (AGTM) + CTA-861.3-G
源码入口:skcms_public.h、SkHdrAgtm.cpp
Skia 实现了 SMPTE ST 2094-50 Adaptive Global Tone Mapping(AGTM)元数据的解析、序列化和色调映射,支持 HDR10 到 SDR 的色调映射转换。
3.3 色深与格式
规范来源:Skia 定义的 26 种 SkColorType + 4 种 SkAlphaType
源码入口:SkColorType.h
| 像素格式 | 色深 | 字节序 | 用途 |
|---|---|---|---|
kAlpha_8 | 8-bit alpha | — | 单通道透明度掩码 |
kRGB_565 | 5-6-5 | — | 低内存 RGB |
kARGB_4444 | 4-4-4-4 | — | 低内存 RGBA |
kRGBA_8888 | 8-8-8-8 | RGBA | 标准 sRGB |
kBGRA_8888 | 8-8-8-8 | BGRA | Windows 默认 |
kRGBA_F16 | 16-bit float | — | HDR / 宽色域 |
kRGBA_F32 | 32-bit float | — | 最高精度 |
kR8G8_unorm | 8-8 | — | 双通道 |
kA16_unorm | 16-bit | — | 深度 alpha |
kA16_float | 16-bit float | — | 浮点 alpha |
kR16G16_float | 16-16 float | — | 双通道浮点 |
kR16G16_unorm | 16-16 | — | 双通道高精度 |
kR16G16B16A16_unorm | 16-16-16-16 | — | RGBA 高精度 |
kSRGBA_8888 | 8-8-8-8 sRGB | — | sRGB 编码 |
kR8_unorm | 8-bit | — | 单通道灰度 |
kR16_unorm | 16-bit | — | 单通道深度 |
kGray_8 | 8-bit | — | 灰度兼容 |
平台字节序选择:SK_R32_SHIFT 宏在 Windows 上为 16(BGRA 顺序),其他平台为 0(RGBA 顺序)。
四、排版与文本(Typography & Text)
4.1 字体度量
规范来源:OpenType 1.9 + TrueType 1.0 + CSS Fonts Module Level 3
源码入口:SkFontMetrics.h、SkFont.cpp
字体度量结构体(SkFontMetrics):
| 字段 | 符号 | 说明 |
|---|---|---|
fTop | 负值 | 字形包围盒最顶端(边界框上限) |
fAscent | 负值 | 基线到字形上沿(建议上沿) |
fDescent | 正值 | 基线到字形下沿(建议下沿) |
fBottom | 正值 | 字形包围盒最底端(边界框下限) |
fLeading | 正值 | 行间距(字体文件 lineGap) |
fAvgCharWidth | 正值 | 平均字符宽度 |
fMaxCharWidth | 正值 | 最大字符宽度 |
fXMin / fXMax | 正/负 | 水平方向最小/最大边界 |
fXHeight | 正值 | 小写 x 高度(ex 单位基准) |
fCapHeight | 正值 | 大写字母高度(cap 单位基准) |
fUnderlineThickness | 正值 | 下划线宽度 |
fUnderlinePosition | 正值 | 下划线位置 |
fStrikeoutThickness | 正值 | 删除线宽度 |
fStrikeoutPosition | 正值 | 删除线位置 |
坐标系:Y 轴向下为正,ascent 为负值(与 DWrite 的无符号 ascent 相反)。
单行原生行高公式(SkFont::getMetrics 实现):
行高 = -fAscent + fDescent + fLeading
4.2 段落排版(SkParagraph)
规范来源:CSS Text Module Level 3 + CSS Line Grid Module + Unicode Bidirectional Algorithm (UAX#9)
源码入口:modules/skparagraph/
CSS line-height 计算算法(Line.cpp):
// 字体原生内容高度
contentHeight = -metrics.fAscent + metrics.fDescent;
// CSS 倍数行高
cssLineHeight = fontSize * style.heightMultiplier;
// 上下均分额外空白(浏览器核心规则)
extra = cssLineHeight - contentHeight;
halfLeading = extra / 2.0f;
// 单行垂直范围
lineAscent = -metrics.fAscent + halfLeading;
lineDescent = metrics.fDescent + halfLeading;
lineTotalHeight = lineAscent + lineDescent;
关键算法:行间距 halfLeading 上下对半均分 —— 这是浏览器与 Skia 一致的 CSS 行为(不同于 DWrite 的 lineGap 全部放在两行之间)。
多字体混合行算法:取整行所有字体的最大 ascent 和最大 descent 作为统一上下边界,保证基线对齐。
双向文本(BiDi):通过 ICU 的 ubidi 实现 Unicode Bidirectional Algorithm,支持 LTR/RTL 混合排版。
4.3 字体引擎
规范来源:OpenType shaping + ICU Unicode 支持
源码入口:src/ports/
支持的字体管理器:
- Windows:DirectWrite (
SkFontMgr_win.cpp) - macOS/iOS:CoreText (
SkFontMgr_mac_ct.cpp) - Android:系统字体 + NDK (
SkFontMgr_android.cpp) - Linux:FontConfig (
SkFontMgr_fontconfig.cpp) - Fuchsia:Fuchsia 字体服务 (
SkFontMgr_fuchsia.cpp) - 目录/数据:从目录或内存加载 (
SkFontMgr_directory.cpp、SkFontMgr_data.cpp) - 空实现:无字体可用时的回退 (
SkFontMgr_empty.cpp) - 实验性:Fontations (Rust 字体解析,
SkFontMgr_Fontations.h)
字体扫描:通过 FreeType 或 Fontations 解析 OpenType/TrueType 字体文件。
五、图像编解码(Image Codecs)
5.1 编解码规范
规范来源:JPEG (ITU-T T.81)、PNG (ISO/IEC 15948)、GIF (87a/89a)、WebP (Google)、BMP (Microsoft)、ICO、WBMP、AVIF (AV1 Image File Format)、JPEG XL
源码入口:src/codec/、include/codec/
| 格式 | 解码器 | 编码器 | 后端依赖 |
|---|---|---|---|
| JPEG | SkJpegCodec | SkJpegEncoder | libjpeg-turbo |
| PNG | SkPngCodec | SkPngEncoder | libpng / Rust png crate |
| GIF | SkGifDecoder | — | Skia 内部实现(libwuffs) |
| WebP | SkWebpCodec | SkWebpEncoder | libwebp |
| BMP | SkBmpCodec | — | Skia 内部实现 |
| ICO | SkIcoCodec | — | 组合解码器(内嵌 BMP/PNG) |
| WBMP | SkWbmpCodec | — | Skia 内部实现 |
| AVIF | SkAvifCodec | — | libavif / dav1d / aom |
| JPEG XL | SkJpegxlCodec | — | libjxl |
| RAW | SkRawCodec | — | libraw / DNG SDK |
| HEIF | SkHeifCodec(Android) | — | Android 平台 API |
解码能力(SkCodec):
| 能力 | 说明 |
|---|---|
| 渐进式解码(Progressive) | JPEG 渐进、PNG 交插 |
| 缩放解码(Subset/Scale) | getScaledDimensions() 支持 1/n 缩放 |
| 帧动画 | GIF、WebP 动画的帧序列支持 |
| EXIF 方向 | 自动旋转至正确方向(SkEncodedOrigin) |
| 增益图(Gainmap) | HDR 增益图元数据解析 |
| ICC 色彩空间 | 自动 ICC 配置文件解析与转换 |
| 内存限制解码 | fMaxDecodeMemory 防止 OOM |
5.2 像素格式变换
规范来源:Skia 内部定义的像素格式路由表
源码入口:SkSwizzler.cpp
Skia 维护一套高效的像素重排和格式转换(Swizzle)引擎,支持编码格式到 Skia 内部 SkColorType 的各种转换路径。
六、图像滤镜与特效(Image Filters & Effects)
6.1 图像滤镜
规范来源:SVG 1.1 Filter Effects + CSS Filter Effects Module Level 1
源码入口:SkImageFilters.h
| 滤镜类型 | 工厂方法 | 算法 |
|---|---|---|
| 算术合成 | Arithmetic(k1,k2,k3,k4) | k1*src*dst + k2*src + k3*dst + k4 |
| 混合模式 | Blend(mode) | 29 种混合模式 |
| 模糊 | Blur(sigmaX, sigmaY) | 高斯模糊(可分离 Box Blur 近似) |
| 亮度 | Brightness(mult) | 逐像素乘法 |
| 颜色矩阵 | ColorFilter(filter) | 4x5 颜色矩阵变换 |
| 卷积 | MatrixConvolution(size, kernel) | NxN 卷积核 |
| 位移映射 | DisplacementMap(xChan,yChan,map) | 从映射图采样偏移坐标 |
| 膨胀/腐蚀 | Dilate/Erode(rx,ry) | 形态学膨胀/腐蚀 |
| 阴影 | DropShadow(dx,dy,sigma,color) | 先模糊后偏移混合 |
| 马赛克 | Magnifier(zoom) | 局部放大 |
| 位移 | Offset(dx,dy) | 像素平移 |
| 着色器 | Shader(shader) | 着色器输出作为滤镜 |
| 裁剪 | Crop(rect) | 输出裁剪 |
| 平铺 | Tile(src,dst) | 区域内的图案平铺 |
滤镜支持链式组合:多个滤镜通过输入输出管道相连,形成 DAG(有向无环图)。Skia 会自动合并相邻的滤镜管道以优化渲染。
6.2 着色器(Shaders)
规范来源:SVG 1.2 Gradients + W3C CSS Images
| 着色器类型 | 工厂函数 |
|---|---|
| 线性渐变 | SkGradient::MakeLinear |
| 径向渐变 | SkGradient::MakeRadial |
| 锥形渐变 | SkGradient::MakeSweep |
| 圆锥渐变 | SkGradient::MakeConical |
| 柏林噪声 | SkPerlinNoiseShader |
| 图像平铺 | SkShader::MakeImage |
| 颜色 | SkShader::MakeColor |
| 混合 | SkShaders::Blend |
| 空 | SkShaders::Empty |
渐变着色器支持 Degenerate Gradient(零长度/零半径退化为纯色)、Premultiplied Alpha Interpolation 和 Extrapolation Modes(clamp/repeat/mirror/decal)。
6.3 运行时着色器(SkSL Runtime Shaders)
规范来源:Skia Shading Language (SkSL) — 基于 GLSL 语法的自定义着色语言
源码入口:SkRuntimeEffect.h、src/sksl/
SkRuntimeEffect 允许以 SkSL 字符串定义自定义着色器、颜色滤镜和混合器,支持的 uniform 类型包括 float、float2-4、float2x2-4x4、int、int2-4。SkSL 编译器支持从 SkSL 到以下后端的代码生成:
| 后端 | 代码生成器 | 目标 |
|---|---|---|
| GLSL | SkSLGLSLCodeGenerator | OpenGL ES 3.0+ |
| SPIR-V | SkSLSPIRVCodeGenerator | Vulkan |
| Metal | SkSLMetalCodeGenerator | Metal |
| HLSL | SkSLHLSLCodeGenerator | Direct3D |
| WGSL | SkSLWGSLCodeGenerator | WebGPU |
| 光栅管线 | SkSLRasterPipelineCodeGenerator | CPU 软件渲染 |
SkSL 编译管线:Lexer → Parser (AST) → Semantic Analysis → IR 转换 → 优化 → 代码生成。
七、GPU 后端规范
7.1 Ganesh 后端(传统 GPU 引擎)
规范来源:OpenGL ES 3.0+ / Vulkan 1.1+ / Metal / Direct3D 12 / Dawn (WebGPU)
源码入口:include/gpu/ganesh/
Ganesh 是 Skia 的传统 GPU 引擎,支持的 GPU 后端:
| 后端 | 入口头文件 | 平台 |
|---|---|---|
| OpenGL | GrGLDirectContext.h | 跨平台(桌面 + 移动) |
| Vulkan | GrVkDirectContext.h | 跨平台 |
| Metal | GrMtlDirectContext.h | Apple |
| Direct3D | GrD3DDirectContext.h | Windows |
| Mock | GrMockTypes.h | 测试 |
关键特性:
- 批量提交(Deferred Context)
- 自动资源缓存(纹理、渲染目标、管线状态)
- Mipmap 自动生成
- MSAA 多重采样抗锯齿
- 延迟纹理上传
- GPU 端剪裁栈
7.2 Graphite 后端(新一代 GPU 引擎)
规范来源:Vulkan 1.2+ / Metal / Dawn (WebGPU)
Graphite 是 Skia 的新一代 GPU 引擎,从零设计,旨在解决 Ganesh 在高复杂度 2D 场景下的性能瓶颈。
关键技术:
- 命令录制与提交分离(
Recorder/Recording) - 通行证预编译(
Precompile) - 持久化管线缓存(
PersistentPipelineStorage) - 异步着色器编译
7.3 CPU 软件渲染(Raster Pipeline)
规范来源:Skia 优化的 SIMD 软件渲染管线
源码入口:src/opts/
通过 SSE / NEON / AVX / WASM SIMD 指令集优化的软件渲染。光栅管线(SkSLRasterPipelineCodeGenerator)将 SkSL 着色器编译为 CPU 可执行的 Stage 函数链,每个 pixel 经过流水线 Stage 逐级处理。
八、动画与合成(Animation & Composition)
8.1 Lottie / Bodymovin 动画(Skottie)
规范来源:Lottie Web (bodymovin JSON 格式, AE 导出规范)
源码入口:modules/skottie/
Skottie 是 Skia 的 Lottie 动画引擎,完全基于 Skia 原生绘制(不依赖 WebView 或 DOM)。
支持的 AE 特性:
- 形状图层(矩形、椭圆、圆角矩形、多段线、星形)
- 路径动画(贝塞尔曲线关键帧插值)
- 变换群组(位置/缩放/旋转/透明度 + 锚点)
- 填充、描边(渐变 + 纯色)
- 修边路径(Trim Paths)
- 仿射变换蒙版(Track Matte)
- 效果层(高斯模糊、发光、投影、色相/饱和度、校正等 20+ 种)
- 文本图层(字体、大小、字间距、行高)
- 预合成
- 插值类型(线性、贝塞尔、保持、缓入/缓出)
关键帧动画器(KeyframeAnimator):
// 标量、二维向量、形状路径、颜色 四种关键帧插值器
ScalarKeyframeAnimator
Vec2KeyframeAnimator
ShapeKeyframeAnimator
TextKeyframeAnimator
插值算法使用 De Casteljau 贝塞尔细分的立方贝塞尔缓动函数。
8.2 音频播放器(SkAudioPlayer)
规范来源:跨平台音频播放(多后端)
源码入口:modules/audioplayer/
支持 macOS (AVFoundation)、Oboe (Android)、SFML (桌面) 后端的音频播放接口,主要用于 Skottie 动画的音频轨道同步。
九、其他算法与工具
9.1 阴影计算
规范来源:CSS Filter Effects + 物理光照近似
源码入口:SkShadowUtils.h
使用环境光遮蔽(Ambient Occlusion)近似算法,结合模糊和透明度梯度生成逼真的平面阴影效果。
9.2 亚像素文本渲染
规范来源:Microsoft ClearType + Apple Quartz 亚像素定位 + FreeType LCD 渲染
Skia 支持:
- LCD 次像素渲染(RGB/BGR 条纹方向)
- 灰度抗锯齿
- 亚像素文本定位(fractional glyph positioning)
- 带
SkSurfaceProps配置的标志位控制(kUseDeviceIndependentFonts_Flag、kDynamicMSAA_Flag)
9.3 SVG 支持
规范来源:SVG 1.1 + SVG 2.0 (部分)
Skia 可以通过 SkSVGCanvas 将绘制命令输出为 SVG 文件,支持 PNG 嵌入(通过 libpng 或 Rust PNG)。
9.4 PDF 生成
规范来源:ISO 32000-1 (PDF 1.7)
源码入口:include/docs/SkPDFDocument.h
Skia 的 PDF 后端不依赖第三方库,完全由 Skia 自身生成符合 PDF 1.7 标准的文件,包括路径、文本、图像、渐变、透明度等 PDF 原生对象的输出。
十、此文档的用途
对本项目(ts-native)
本项目 ts-native 的目标是构建一个跨平台的原生 2D UI 引擎。Skia 的源码是本项目的重要参考:
-
排版系统参考:本文档第 4 章的 SkParagraph CSS line-height 算法、字体度量结构、多字体混合行的 ascent/descent 取最大值策略,已直接用于本项目渲染引擎的文本排版校正(参见现有基线文档 Skia(Chromium) 开源源码基线_行高_行距完整规则 + 对比 DWrite 差异根源.md)。
-
Blend Mode 实现:第 1.3 节的 29 种混合模式作为独立图形渲染引擎的混合模块参考。
-
CSS 值计算:第 4.2 节的 CSS 单位解析和 calc() 支持作为排版引擎参考。
-
路径运算:第 2.3 节的 PathOps 布尔运算在 UI 裁剪、SVG 路径裁剪中有直接用途。
-
颜色管理:第 3 节的 skcms 颜色空间转换是实现 HDR 和支持广色域的基础。
对其他项目
-
游戏引擎开发者:Skia 的 GPU 后端(Ganesh/Graphite)架构为 2D 游戏引擎的 GPU 绘制提供了成熟参考。
-
Flutter 引擎贡献者:Flutter 的 Impeller 引擎部分参考了 Skia 的路径光栅化和 GPU 批处理策略。
-
Web 浏览器开发者:Skia 在 Chrome 中承担所有 2D 图形绘制和排版,其 CSS line-height 实现、font-metrics 处理和 Canvas2D API 实现是参考实现。
-
图形学研究者:Skia 的路径布尔运算(Bentley-Ottmann 扫描线)、渐变插值、模糊算法实现了工业级优化,可作为对照基准。
-
字体/排版工具开发者:SkParagraph 的 CSS 排版实现(多字体混合行、BiDi 算法、line-height half-leading 均分)是理解浏览器排版行为的参考。
-
颜色科学工具开发者:skcms 的 ICC 配置解析、传递函数建模、色彩空间转换代码可独立作为 C 库使用。
-
嵌入式 UI 框架开发者:Skia 的 CPU 光栅管线(SIMD 优化)为无 GPU 环境下的 2D 渲染提供性能基线。
-
Lottie 播放器开发者:Skottie 的 LT 解析和动画插值是 Lottie Web 规范的替代实现,可用于对比验证。
本文档基于 Skia Milestone 148 源码编写。Skia 是一个活跃开发的项目,不同里程碑间的 API 和实现细节可能存在差异。