SkiaSharp 1.55.0 API 变更解析:SkiaSharp.dll 从 1.54.0 到 1.55.0 的破坏性改动与新 API 详解

原创2026-10-12 14:27:091,814 阅读
文章标签:图形学跨平台

SkiaSharp 1.55.0 API 变更解析:SkiaSharp.dll 从 1.54.0 到 1.55.0 的破坏性改动与新 API 详解

本篇基于 SkiaSharp 官方发布的 1.55.0 版本 API diff 文档(documentation/docfx/releases/1.55.0/SkiaSharp/SkiaSharp.md)逐条解析 SkiaSharp.dll 相对 1.54.0 的全部接口变化:哪些签名属于破坏性改动、新增的 SKBlendMode/SKLattice/SKPathMeasure/SKRegion 等类型如何使用,并结合同一仓库中 1.55.0 发布说明 和当前 binding/SkiaSharp/ 目录下的实现源码,给出可落地的迁移对照与升级检查清单。读完本篇后,你将能够:判断自己的代码是否受 1.55.0 破坏性变更影响、按类型逐项完成 API 替换,并理解新版 API(如颜色混合模式、lattice 纹理绘制、路径测量)的设计意图。

1. 版本背景:1.55.0 是一次"API 大扫除"

assembly 版本变更为 1.55.0.0(对比基线 1.54.0.0),该版本于 2016 年 11 月 10 日发布,官方将其定性为 API cleanup(API 清理),主题包括:

  • 裁剪公开 API 的可选参数:SKCanvas、GRContext、SKPath 上的多个方法去掉了默认参数值,使重载决议更确定、ABI 更稳定;
  • SKCodecOptions.Subset 变为可空类型:从 SKRectI 改为 SKRectI?,更准确地表达"子集是可选的";
  • 移除一批遗留辅助方法:SKCodec、SKDocument、SKMatrix 上的旧接口被替换或删除。

这一版本在发布索引 documentation/docfx/releases/1.55.0/index.md 中被标记为 ⚠️ breaking,同目录下的 SkiaSharp.breaking.md 则单独列出了 7 类"仅破坏性"变更(去掉默认值、Subset 变可空、HasSubset 失去 setter、删除 GetValidSubset/Close/MapRect 静态签名/SKPictureRecorder 原生句柄构造函数)。下面按"破坏性改动 → 逐类型变更 → 全新类型"的顺序完整展开 diff 文档中的每一项。

2. 破坏性改动详解(必须处理的 3 类)

2.1 公开 API 去掉了默认参数值

diff 文档与 1.55.0 发布说明 均指出:若干方法不再提供默认参数值,调用方必须显式传参或改用匹配的重载,这是一次 ABI 层面的变化,需要重新编译。涉及的方法:

 // GRContext
 public void Flush (GRContextFlushBits flagsBitfield--- = 0---)

 // SKCanvas
 public void ClipPath (SKPath path, SKRegionOperation operation--- = 1---, bool antialias = false)
 public void ClipRect (SKRect rect, SKRegionOperation operation--- = 1---, bool antialias = false)
 public void DrawColor (SKColor color, SKXferMode mode--- = 1---)

其中 --- = 值 --- 的标注表示"默认值被移除"。实际影响:

  • GRContext.Flush(GRContextFlushBits) 之前可省略参数,之后必须显式传入标志位(或改用新的无参 Flush(),见 3.1 节);
  • SKCanvas.ClipRect/ClipPath 的 operation、DrawColor 的 mode 都必须显式给出,例如 canvas.ClipRect(rect, SKRegionOperation.Intersect, false);
  • 动机是避免 C# 可选参数与 P/Invoke 签名绑定的 ABI 漂移问题——默认值只存在于调用方编译期,去掉后接口签名跨版本稳定。

从当前仓库源码结构看,这一思路在后来的版本中被保留并进一步强化:SKCanvas.cs 中 ClipPath (SKPath path, SKClipOperation operation = SKClipOperation.Intersect, bool antialias = false) 的参数类型已从 SKRegionOperation 演进为 1.55.0 引入的 SKClipOperation,说明 1.55.0 的枚举替换是后续演进的基础。

2.2 SKCodecOptions.Subset 变为可空类型

 public bool HasSubset { get; ---set;--- }
 -public SKRectI Subset { get; set; }
 +public SKRectI? Subset { get; set; }

两处破坏点:Subset 的读取类型从结构体 SKRectI 改为可空 SKRectI?(未设置子集时为 null 而不是 default(SKRectI));HasSubset 失去 setter,成为只读属性。配套的新增是构造函数 public SKCodecOptions (SKRectI subset),推荐用法改为:

// 迁移前(1.54.0)
var options = new SKCodecOptions();
options.Subset = new SKRectI (0, 0, 100, 100);

// 迁移后(1.55.0+)
var options = new SKCodecOptions (new SKRectI (0, 0, 100, 100));
// 或者保持不设置子集:options.Subset 为 null,options.HasSubset == false

配套地,SKCodec.GetValidSubset 的签名从 void 变为返回 bool(属于 2.3 节"方法替换"的一部分),以便判断子集信息是否有效。

2.3 遗留方法删除与签名替换

类型 被移除 替代 说明
SKCodec void GetValidSubset (ref SKRectI) bool GetValidSubset (ref SKRectI) 当前 SKCodec.cs 中该方法保留 bool 返回值的签名,用于查询解码子集是否落在有效范围内
SKDocument bool Close () void Close () 当前 SKDocument.cs 中 Close() 已为 void,关闭文档不再以返回值报告失败
SKMatrix static MapRect(...) 实例方法 MapRect(...) 矩阵变换改为实例风格:matrix.MapRect(ref other, out dest, ref source)
SKPictureRecorder SKPictureRecorder (IntPtr handle, bool owns) 无(改用托管构造函数) 当前 SKPictureRecorder.cs 提供 RecordingCanvas 属性获取录制画布,原生句柄构造函数不再公开

此外 SKMatrix.MapXY (float, float) 被标记 [Obsolete] 并指向 MapPoint——注意它只是废弃而非删除,编译会产生警告:

// 迁移前
SKPoint p = matrix.MapXY (10, 20);
// 迁移后
SKPoint p = matrix.MapPoint (10, 20);

当前 SKMatrix.cs 中 MapPoint (SKPoint) 与 MapPoint (float, float) 两个重载均存在,且文档明确提示映射向量(vector)时请改用 MapVector,因为向量映射会忽略平移分量。

3. 逐类型变更详解

3.1 GRContext:无参 Flush() 与可选参数收紧

  • 新增无参重载 public void Flush (),并标记 <a href="https://link.gitcode.com/i/ebbe05877cc1a2822414a24d2f2b67fd" target="_blank">Obsolete ("Use Flush() instead.")] 的 Flush (GRContextFlushBits flagsBitfield) 作为迁移桥;当前实现 [GRContext.cs 中即为 public void Flush () => Flush (true);;
  • 带参 Flush (GRContextFlushBits flagsBitfield) 去掉默认值 = 0(见 2.1 节)。

日常绘制代码优先使用无参 Flush(),只有需要精细控制提交粒度(如与后台线程并发渲染时)才使用标志位版本。

3.2 GRContextOptions:5 个新增选项

public bool AllowPathMaskCaching { get; set; }
public static GRContextOptions Default { get; }
public bool DisableDistanceFieldPaths { get; set; }
public bool EnableInstancedRendering { get; set; }
public bool ForceSWPathMasks { get; set; }
  • Default 静态属性返回平台默认配置的上下文选项,创建 GRContext 时可直接使用而不是 new GRContextOptions();
  • 其余 4 个布尔开关分别控制路径遮罩缓存、距离场路径、实例化渲染和软件路径遮罩,用于针对特定 GPU/驱动问题做调优。实现见 GRContextOptions.cs。

3.3 SKCanvas:裁剪边界查询 + Lattice 绘制 + 新的裁剪/绘制方法

新增只读属性:

public SKRect ClipBounds { get; }
public SKRectI ClipDeviceBounds { get; }

用于在绘制前查询当前生效的裁剪范围(当前版本中这两个属性已进一步演化为 LocalClipBounds / DeviceClipBounds,见 SKCanvas.cs)。

新增方法一览:

public void ClipPath (SKPath path, SKClipOperation operation, bool antialias);
public void ClipRect (SKRect rect, SKClipOperation operation, bool antialias);
public void ClipRegion (SKRegion region, SKClipOperation operation);
public void DrawBitmapLattice (SKBitmap bitmap, SKLattice lattice, SKRect dst, SKPaint paint);
public void DrawImageLattice (SKImage image, SKLattice lattice, SKRect dst, SKPaint paint);
public void DrawColor (SKColor color, SKBlendMode mode);
public void DrawOval (float cx, float cy, float rx, float ry, SKPaint paint);
public void Scale (float s);

要点:

  • ClipPath/ClipRect 的操作参数由 SKRegionOperation 换为 2 值枚举 SKClipOperation { Difference, Intersect }(1.55.0 起裁剪语义收敛为"取差/取交"),旧签名被标记 [Obsolete];
  • ClipRegion 配合新增的 SKRegion 类型(见 4.7 节)支持按 1 位区域裁剪;
  • DrawBitmapLattice/DrawImageLattice 是九宫格(lattice)纹理贴图的核心入口:用 XDivs/YDivs 把位图/图像切成网格并分别映射到目标矩形,SKLatticeFlags.Transparent 可让格子间的缝隙透明;
  • DrawColor (SKColor, SKBlendMode) 与 SKPaint.BlendMode(见 3.8 节)共同取代了旧的 SKXferMode 路径。

3.4 SKColor:Parse / TryParse

public static SKColor Parse (string hexString);
public static bool TryParse (string hexString, out SKColor color);

支持 #RGB、#RRGGBB、#AARRGGBB 等十六进制颜色字符串。当前实现位于 SKColor.cs,并且后续版本又补充了 ReadOnlySpan<char> 重载以避免字符串解析分配——这一演进方向也印证了 1.55.0 引入 Parse 时的"低成本字符串转颜色"定位:

SKColor red = SKColor.Parse ("#FF3030");
if (SKColor.TryParse (input, out SKColor c))
    paint.Color = c;

3.5 SKColorFilter:色阶立方体常量重命名

 [Obsolete ("Use MaxColorCubeDimension instead.")]
 public static const int MaxCubeSize;
 [Obsolete ("Use MinColorCubeDimension instead.")]
 public static const int MinCubeSize;

新增:

public static const int ColorMatrixSize;
public static const int MaxColorCubeDimension;
public static const int MinColorCubeDimension;

ColorCube 滤镜的维度上下限常量改为更精确的 *Dimension 命名,同时补齐了 4×4 颜色矩阵尺寸常量 ColorMatrixSize(供 CreateColorMatrix 的数组大小使用)。

3.6 SKFontStyleWidth:拼写修正 UltaExpanded → UltraExpanded

UltaExpanded = 9,  // Obsolete
UltraExpanded = 9, // 新值

这是一个纯拼写修正,枚举数值保持 9 不变。迁移时只需替换标识符;从源码结构看当前 Definitions.cs 中保留的正是 UltraExpanded = 9,旧拼写已随废弃流程移除。

3.7 SKImageFilter:位移映射改名 + 4 个工厂方法

被废弃的 CreateCompose(实为位移映射效果)更名为语义正确的 CreateDisplacementMapEffect,并新增一批静态工厂:

public static SKImageFilter CreateArithmetic (float k1, float k2, float k3, float k4, bool enforcePMColor, SKImageFilter background, SKImageFilter foreground, SKImageFilter.CropRect cropRect);
public static SKImageFilter CreateBlendMode (SKBlendMode mode, SKImageFilter background, SKImageFilter foreground, SKImageFilter.CropRect cropRect);
public static SKImageFilter CreateDisplacementMapEffect (SKDisplacementMapEffectChannelSelectorType xChannelSelector, SKDisplacementMapEffectChannelSelectorType yChannelSelector, float scale, SKImageFilter displacement, SKImageFilter input, SKImageFilter.CropRect cropRect);
public static SKImageFilter CreateTile (SKRect src, SKRect dst, SKImageFilter input);

对应 Skia C++ 侧的 SkImageFilters::Arithmetic/BlendMode/DisplacementMap/Tile。当前 SKImageFilter.cs 中 CreateDisplacementMapEffect 保留了 3 个渐进式重载(input 与 cropRect 可省略),CreateTile (SKRect src, SKRect dst, SKImageFilter? input) 同样保留(SKImageFilter.cs),API 形态与 1.55.0 引入时一致。

3.8 SKPaint:BlendMode 取代 XferMode,新增克隆与字体度量

 [Obsolete ("Use BlendMode instead.")]
 public SKXferMode XferMode { get; set; }

新增:

public SKBlendMode BlendMode { get; set; }
public float FontSpacing { get; }
public SKPaint Clone ();
public bool GetFillPath (SKPath src, SKPath dst, float resScale);
public bool GetFillPath (SKPath src, SKPath dst, SKRect cullRect, float resScale);
public float GetFontMetrics (out SKFontMetrics metrics, float scale);
  • BlendMode 与 SKPaint.Color 配合实现 Porter-Duff 与扩展混合,XferMode 进入废弃通道(当前 SKPaint.cs 中 BlendMode 为主属性);
  • FontSpacing 给出按当前字体计算的一行文本间距,GetFontMetrics (out metrics, scale) 支持按缩放取字体度量(SKPaint.cs);
  • GetFillPath 把源路径按描边宽度"填充化"为新的闭合路径,常用于文本描边转填充、命中区域计算;
  • Clone () 提供值语义的完整拷贝(SKPaint.cs),避免多个绘制器共享同一 paint 造成状态污染。

3.9 SKPath:批量补齐路径构建与变换 API

新增方法覆盖 Skia SkPath 的主要能力面:

// 圆弧/椭圆弧
public void ArcTo (SKPoint point1, SKPoint point2, float radius);
public void ArcTo (SKRect oval, float startAngle, float sweepAngle, bool forceMoveTo);
public void ArcTo (SKPoint r, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, SKPoint xy);
public void ArcTo (float x1, float y1, float x2, float y2, float radius);
public void RArcTo (SKPoint r, float xAxisRotate, SKPathArcSize largeArc, SKPathDirection sweep, SKPoint xy);
// 相对坐标版本(R 前缀)
public void RLineTo (SKPoint point);  public void RMoveTo (SKPoint point);
public void RQuadTo (SKPoint point0, SKPoint point1);
public void RCubicTo (SKPoint point0, SKPoint point1, SKPoint point2);
public void RConicTo (SKPoint point0, SKPoint point1, float w);
// 曲线段
public void ConicTo (SKPoint point0, SKPoint point1, float w);
public void CubicTo (SKPoint point0, SKPoint point1, SKPoint point2);
public void LineTo (SKPoint point);  public void MoveTo (SKPoint point);
public void QuadTo (SKPoint point0, SKPoint point1);
// 变换与运算
public void Offset (SKPoint offset);
public SKPath Op (SKPath other, SKPathOp op);
public SKPath Simplify ();
// 圆锥曲线 → 二次曲线转换(SVG 路径解析常用)
public static SKPoint[] ConvertConicToQuads (SKPoint p0, SKPoint p1, SKPoint p2, float w, int pow2);
public static int ConvertConicToQuads (SKPoint p0, SKPoint p1, SKPoint p2, float w, SKPoint[] pts, int pow2);
public static int ConvertConicToQuads (SKPoint p0, SKPoint p1, SKPoint p2, float w, out SKPoint[] pts, int pow2);

其中 Op 是布尔路径运算(union/intersect/difference/reverseDifference/andReversed/xor),Simplify 做共线点简化,ConvertConicToQuads 的 pow2 控制细分精度(2 的幂)。

3.10 其余小类变更

  • SKPathEffect:Create1DPath 的样式参数由 SkPath1DPathEffectStyle(拼写缺失)改为新枚举 SKPath1DPathEffectStyle { Translate, Rotate, Morph };
  • SKPoint:新增 Offset (SKPoint p) 与 Offset (float dx, float dy),与原地的点平移语义对齐 SKPath.Offset;
  • SKRect / SKRectI:新增 MidX、MidY、Standardized 属性与 AspectFill (SKSize)、AspectFit (SKSize)(整型版对应 SKSizeI)。当前实现中 MidX 为 left + (Width / 2f)(MathTypes.cs),AspectFit 内部以 MidX/MidY 为锚点居中(MathTypes.cs)——这对图像缩放的"保持宽高比"场景是标准工具;
  • SKTypeface:新增只读属性 FontSlant、FontWeight、FontWidth、Style(SKTypefaceStyle),可直接读取字面体自身携带的风格信息,当前 SKTypeface.cs 中 FontWeight 仍在维护;
  • SKPictureRecorder:删除原生句柄构造函数,新增 RecordingCanvas 属性(SKPictureRecorder.cs)取代手工持有 canvas 句柄的写法。

4. 全新类型详解

4.1 SKBlendMode(29 个值)

1.55.0 引入完整混合模式枚举,数值与 Skia C++ 一一对应(SKBlendMode.generated.cs 中 Saturation = 26、Luminosity = 28 等值至今未变):

[Serializable]
public enum SKBlendMode {
	Clear = 0, Src = 1, Dst = 2, SrcOver = 3, DstOver = 4,
	SrcIn = 5, DstIn = 6, SrcOut = 7, DstOut = 8, SrcATop = 9, DstATop = 10,
	Xor = 11, Plus = 12, Modulate = 13, Screen = 14, Overlay = 15, Darken = 16,
	Lighten = 17, ColorDodge = 18, ColorBurn = 19, HardLight = 20, SoftLight = 21,
	Difference = 22, Exclusion = 23, Multiply = 24, Hue = 25, Saturation = 26,
	Color = 27, Luminosity = 28,
}

典型用法:paint.BlendMode = SKBlendMode.Multiply 实现图片叠加混合;canvas.DrawColor (SKColor.Red, SKBlendMode.SrcOver) 用指定混合模式清屏。

4.2 SKClipOperation

[Serializable]
public enum SKClipOperation {
	Difference = 0,
	Intersect = 1,
}

仅两个值,取代 SKRegionOperation 在裁剪路径/矩形上的重载参数,语义与 Skia SkClipOp 一致。

4.3 SKLattice 与 SKLatticeFlags

public struct SKLattice {
	public SKRectI? Bounds { get; set; }
	public SKLatticeFlags[] Flags { get; set; }
	public int[] XDivs { get; set; }
	public int[] YDivs { get; set; }
}

[Serializable]
public enum SKLatticeFlags {
	Default = 0,
	Transparent = 1,
}

XDivs/YDivs 数组长度分别决定网格的行数/列数(列数 = XDivs.Length + 1);Flags 数组与"格子"一一对应,Transparent 标记的格子不绘制,常用于九宫格 UI 贴图时让边框缝隙透明。配合 canvas.DrawImageLattice (image, lattice, dst, paint) 使用。

4.4 SKPath1DPathEffectStyle

[Serializable]
public enum SKPath1DPathEffectStyle {
	Translate = 0,
	Rotate = 1,
	Morph = 2,
}

1D 路径效果(沿路径重复绘制小图形)的三种排布方式:平移、旋转、变形。

4.5 SKPathMeasure

沿路径做"距离 → 位置/切线/矩阵"查询的核心类(当前实现 SKPathMeasure.cs 中 Length 属性与 NextContour 均保留):

public class SKPathMeasure : SKObject, IDisposable {
	public SKPathMeasure ();
	public SKPathMeasure (SKPath path, bool forceClosed, float resScale);
	public bool IsClosed { get; }
	public float Length { get; }
	public bool GetMatrix (float distance, out SKMatrix matrix, MatrixFlags flags);
	public bool GetPosition (float distance, out SKPoint position);
	public bool GetPositionAndTangent (float distance, out SKPoint position, out SKPoint tangent);
	public bool GetSegment (float start, float stop, SKPath dst, bool startWithMoveTo);
	public bool GetTangent (float distance, out SKPoint tangent);
	public bool NextContour ();
	public void SetPath (SKPath path, bool forceClosed);

	[Serializable]
	[Flags]
	public enum MatrixFlags {
		GetPosition = 1,
		GetTangent = 2,
		GetPositionAndTangent = 3,
	}
}

典型场景:让文字或粒子沿贝塞尔曲线运动。NextContour() 在多段子路径(contour)间推进,GetSegment 截取路径片段,resScale 控制近似精度。

4.6 SKRegion

1 位(黑白)区域对象,与 SKCanvas.ClipRegion 配合使用:

public class SKRegion : SKObject, IDisposable {
	public SKRegion ();
	public SKRegion (SKRegion region);
	public SKRectI Bounds { get; }
	public bool Contains (SKPointI xy);
	public bool Contains (SKRegion src);
	public bool Contains (int x, int y);
	public bool Intersects (SKRectI rect);
	public bool Intersects (SKRegion region);
	public bool Op (SKRectI rect, SKRegionOperation op);
	public bool Op (SKRegion region, SKRegionOperation op);
	public bool Op (int left, int top, int right, int bottom, SKRegionOperation op);
	public bool SetPath (SKPath path);
	public bool SetPath (SKPath path, SKRegion clip);
	public bool SetRect (SKRectI rect);
	public bool SetRegion (SKRegion region);
}

注意 Op 的运算参数仍是 5 值枚举 SKRegionOperation(与 4.2 节 SKClipOperation 不同——后者是裁剪专用的 2 值收敛版);SetPath 把抗锯齿前的路径轮廓栅格化为区域,clip 参数可限制栅格化范围以提升大路径的性能。

5. 升级迁移检查清单

将 1.54.0 项目升级到 1.55.0 时,按以下清单逐项排查:

# 检查项 旧写法 新写法
1 Flush 默认参数 context.Flush () 或省略标志 context.Flush ()(新增无参重载);带参版本须显式传 GRContextFlushBits
2 裁剪/清屏默认参数 canvas.ClipRect (rect)、canvas.DrawColor (color) 显式传 operation/antialias/mode,或改用 SKClipOperation 新重载
3 混合模式 paint.XferMode = SKXferMode.Multiply paint.BlendMode = SKBlendMode.Multiply
4 点映射 matrix.MapXY (x, y) matrix.MapPoint (x, y)
5 MapRect 静态调用 SKMatrix.MapRect (ref m, out d, ref s) m.MapRect (ref other, out d, ref s)
6 Codec 子集 options.Subset = new SKRectI (...) + void GetValidSubset new SKCodecOptions (new SKRectI (...)) + bool GetValidSubset (ref ...)
7 文档关闭 bool ok = doc.Close () doc.Close ()(返回 void)
8 录制器构造 new SKPictureRecorder (handle, owns) 托管构造函数 + recorder.RecordingCanvas
9 字面体宽度枚举 SKFontStyleWidth.UltaExpanded SKFontStyleWidth.UltraExpanded
10 色阶滤镜常量 SKColorFilter.MaxCubeSize/MinCubeSize MaxColorCubeDimension/MinColorCubeDimension
11 图像滤镜位移映射 SKImageFilter.CreateCompose (...) SKImageFilter.CreateDisplacementMapEffect (...)

由于改动集中在签名层面,多数场景下重新编译并跟随编译器错误/警告即可完成迁移;[Obsolete] 标记会保留在 1.55.0 中直到后续版本删除,为过渡期提供缓冲。

6. 配套验证:原生库版本兼容性

SkiaSharp.dll 与原生 libSkiaSharp 必须版本匹配。1.55.0 时代的版本校验逻辑沿用 SkiaSharpVersion:通过 sk_version_get_milestone()/sk_version_get_increment() 读取原生库版本,并要求其落在 <a href="https://link.gitcode.com/i/fd68119076353dfb9549986787aaee87" target="_blank">NativeMinimum, NativeMinimum + 1) 区间内,否则 CheckNativeLibraryCompatible (throwIfIncompatible: true) 抛出 InvalidOperationException([SkiaSharpVersion.cs)。升级 SkiaSharp 包时,NativeAssets 系列 NuGet 包(如 SkiaSharp.NativeAssets.Linux)会随主包一起更新,避免托管/原生版本错位。

7. 小结

1.55.0 的 API diff 可以归纳为三条主线:

  1. 签名收敛:去掉默认参数、删除 IntPtr 句柄构造与遗留静态方法,换取稳定的 ABI 与确定的重载决议;
  2. 语义更名:XferMode → BlendMode、UltaExpanded → UltraExpanded、CreateCompose → CreateDisplacementMapEffect、CubeSize → ColorCubeDimension,废弃标记为迁移保留缓冲;
  3. 能力补齐:SKBlendMode、SKLattice、SKPathMeasure、SKRegion 四个全新类型与 SKColor.Parse、SKRect.AspectFit/AspectFill、SKPath.Op/Simplify 等大量方法,把 SVG 路径解析、沿路径动画、九宫格贴图、区域裁剪等常用工作流沉淀为正式 API。

对照 完整 diff、破坏性变更清单 与 1.55.0 发布说明,即可在升级前评估影响面,并在升级后借编译器提示逐条完成迁移。

登录后查看全文
SkiaSharp