文档概览
此文档详细介绍了 pa2d 库中的 Canvas 高级绘制接口,包含图像操作、形状绘制、文本渲染和混合模式功能。Canvas 作为 Buffer API 的代理层,每个 Canvas 包含一个内部 Buffer 并自动管理内存。
主要分为四个核心模块:
Canvas 画布:高级绘制接口,提供完整的图像处理和图形绘制功能
Color 结构体 :ARGB 颜色表示
Buffer 像素缓冲区 : 底层像素数据容器
文本系统 : 字体渲染配置,包含抗锯齿、编码和样式控制
重要提示
所有绘制操作默认使用抗锯齿。对于最佳性能,建议直接访问 Buffer 的颜色指针而非使用 at() 方法。所有渲染都是离屏到 Buffer 中,Window 将 Buffer 渲染到显示器。
Canvas 画布
高级绘制接口(Buffer API 的代理),每个 Canvas 包含一个内部 Buffer 并自动管理内存。
构造与赋值
| 方法 | 说明 |
|---|---|
Canvas() |
默认构造,创建空画布 |
Canvas(int width, int height, Color background = White) |
指定尺寸和背景色构造 |
Canvas(const Canvas& rhs) |
复制构造 |
Canvas(Canvas&& rhs) noexcept |
移动构造 |
Canvas(const Buffer& rhs) |
从 Buffer 构造 |
Canvas(Buffer&& rhs) noexcept |
从 Buffer 移动构造 |
Canvas(const char* filePath) |
从图像文件构造 |
Canvas(int resourceID) |
从资源 ID 构造 |
Canvas& operator=(const Canvas& rhs) |
复制赋值 |
Canvas& operator=(Canvas&& rhs) noexcept |
移动赋值 |
Canvas& operator=(const Buffer& rhs) |
从 Buffer 赋值 |
Canvas& operator=(Buffer&& rhs) noexcept |
从 Buffer 移动赋值 |
尺寸与访问
| 方法 | 返回类型 | 说明 |
|---|---|---|
width() const |
int |
获取画布宽度 |
height() const |
int |
获取画布高度 |
at(int x, int y) |
Color& |
访问指定位置的像素(引用) |
at(int x, int y) const |
const Color& |
访问指定位置的像素(常量引用) |
getBuffer() |
Buffer& |
获取底层 Buffer 引用 |
getBuffer() const |
const Buffer& |
获取底层 Buffer 常量引用 |
图像操作
| 方法 | 返回类型 | 说明 |
|---|---|---|
loadImage(const char* filePath, int width = -1, int height = -1) |
bool |
从文件加载图像(可指定目标尺寸) |
loadImage(int resourceID, int width = -1, int height = -1) |
bool |
从资源 ID 加载图像 |
clear(Color color = White) |
Canvas& |
清除画布为指定颜色 |
crop(int left, int top, int width, int height) |
Canvas& |
裁剪画布区域 |
resize(int width, int height) |
Canvas& |
调整画布尺寸 |
resizeBuffer(int newWidth, int newHeight, uint32_t color = White) |
Canvas& |
调整底层 Buffer 尺寸 |
基本图形绘制
| 方法 | 说明 |
|---|---|
line(float startX, float startY, float endX, float endY, const Style& style) |
绘制直线段 |
polyline(const std::vector<Point>& points, const Style& style, bool closed = false) |
绘制折线(可选闭合) |
polygon(const std::vector<Point>& vertices, const Style& style) |
绘制多边形 |
triangle(float x0, float y0, float x1, float y1, float x2, float y2, const Style& style) |
绘制三角形 |
rect(float left, float top, float width, float height, const Style& style) |
绘制矩形(左上角坐标) |
rect(float centerX, float centerY, float width, float height, float angle, const Style& style) |
绘制旋转矩形(中心坐标) |
circle(float centerX, float centerY, float radius, const Style& style) |
绘制圆形 |
ellipse(float centerX, float centerY, float width, float height, const Style& style) |
绘制椭圆 |
ellipse(float centerX, float centerY, float width, float height, float angle, const Style& style) |
绘制旋转椭圆 |
sector(float centerX, float centerY, float radius, float startAngle, float endAngle, const Style& style) |
绘制扇形 |
面向对象绘制
| 方法 | 说明 |
|---|---|
draw(const Shape& shape, const Style& style) |
绘制几何对象(支持所有 Shape 派生类) |
// 创建画布
pa2d::Canvas canvas(800, 600);
// 创建几何对象
pa2d::Circle circle(400, 300, 100);
pa2d::Rect rect(400, 300, 150, 100, 45.0f);
pa2d::Triangle triangle(200, 200, 300, 100, 400, 200);
// 创建样式
pa2d::Style circleStyle = pa2d::Red_fill + 2.0_w;
pa2d::Style rectStyle = pa2d::Style().fill(0x8000FF00).stroke(0xFF00FF00).width(3.0f);
pa2d::Style triStyle = 0xFFFFA500_fill + 0xFF000000_stroke + 1.5_w;
// 绘制几何对象
canvas.draw(circle, circleStyle)
.draw(rect, rectStyle)
.draw(triangle, triStyle);
图像混合
| 方法 | 说明 |
|---|---|
copy(const Canvas& src, int dstX = 0, int dstY = 0) |
直接复制(覆盖目标) |
blend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255, int mode = 0) |
通用混合(指定混合模式) |
alphaBlend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255) |
Alpha 混合(默认) |
addBlend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255) |
加法混合(变亮) |
multiplyBlend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255) |
乘法混合(变暗) |
screenBlend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255) |
屏幕混合(变亮) |
overlayBlend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255) |
叠加混合(增强对比) |
destAlphaBlend(const Canvas& src, int dstX = 0, int dstY = 0, int alpha = 255) |
目标 Alpha 混合 |
图像变换绘制
| 方法 | 说明 |
|---|---|
draw(const Canvas& src, float centerX, float centerY, int alpha = 255) |
在指定中心点绘制图像 |
drawResized(const Canvas& src, float centerX, float centerY, int width, int height) |
绘制调整尺寸的图像 |
drawScaled(const Canvas& src, float centerX, float centerY, float scaleX, float scaleY) |
绘制非均匀缩放的图像 |
drawScaled(const Canvas& src, float centerX, float centerY, float scale) |
绘制等比例缩放的图像 |
drawRotated(const Canvas& src, float centerX, float centerY, float rotation) |
绘制旋转的图像 |
drawTransformed(const Canvas& src, float centerX, float centerY, float scale, float rotation) |
绘制等比例缩放和旋转的图像 |
drawTransformed(const Canvas& src, float centerX, float centerY, float scaleX, float scaleY, float rotation) |
绘制非均匀缩放和旋转的图像 |
图像变换副本
| 方法 | 返回类型 | 说明 |
|---|---|---|
cropped(int left, int top, int width, int height) const |
Canvas |
返回裁剪后的副本 |
resized(int width, int height) const |
Canvas |
返回调整尺寸后的副本 |
scaled(float scaleX, float scaleY) const |
Canvas |
返回非均匀缩放后的副本 |
scaled(float scale) const |
Canvas |
返回等比例缩放后的副本 |
rotated(float rotation) const |
Canvas |
返回旋转后的副本 |
transformed(float scale, float rotation) const |
Canvas |
返回等比例缩放和旋转后的副本 |
transformed(float scaleX, float scaleY, float rotation) const |
Canvas |
返回非均匀缩放和旋转后的副本 |
// 创建源图像
pa2d::Canvas srcCanvas("image.png");
// 创建目标画布
pa2d::Canvas destCanvas(800, 600);
// 直接绘制
destCanvas.draw(srcCanvas, 200, 150, 200); // 半透明
// 绘制变换后的图像
destCanvas.drawScaled(srcCanvas, 400, 300, 0.5f); // 缩小50%
destCanvas.drawRotated(srcCanvas, 600, 300, 45.0f); // 旋转45度
destCanvas.drawTransformed(srcCanvas, 200, 450, 1.2f, 30.0f); // 缩放并旋转
// 创建变换副本
pa2d::Canvas rotatedCopy = srcCanvas.rotated(90.0f);
pa2d::Canvas scaledCopy = srcCanvas.scaled(0.75f);
pa2d::Canvas transformedCopy = srcCanvas.transformed(1.5f, 1.0f, 15.0f);
文本渲染
| 方法 | 说明 |
|---|---|
text(int x, int y, const std::wstring& text, int fontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::wstring& fontName = L"Microsoft YaHei") |
在指定位置绘制宽字符文本 |
text(int x, int y, const std::string& text, int fontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::string& fontName = "Microsoft YaHei") |
在指定位置绘制多字节文本 |
textCentered(int centerX, int centerY, const std::wstring& text, int fontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::wstring& fontName = L"Microsoft YaHei") |
在中心点绘制宽字符文本 |
textCentered(int centerX, int centerY, const std::string& text, int fontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::string& fontName = "Microsoft YaHei") |
在中心点绘制多字节文本 |
textInRect(int rectX, int rectY, int rectWidth, int rectHeight, const std::wstring& text, int fontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::wstring& fontName = L"Microsoft YaHei") |
在矩形中心绘制宽字符文本 |
textInRect(int rectX, int rectY, int rectWidth, int rectHeight, const std::string& text, int fontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::string& fontName = "Microsoft YaHei") |
在矩形中心绘制多字节文本 |
textFitRect(int rectX, int rectY, int rectWidth, int rectHeight, const std::wstring& text, int preferredFontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::wstring& fontName = L"Microsoft YaHei") |
在矩形内自适应字体大小绘制宽字符文本 |
textFitRect(int rectX, int rectY, int rectWidth, int rectHeight, const std::string& text, int preferredFontSize = 16, const Color& color = 0xFF000000, FontStyle style = FontStyle::Regular, const std::string& fontName = "Microsoft YaHei") |
在矩形内自适应字体大小绘制多字节文本 |
// 创建画布
pa2d::Canvas canvas(800, 600);
// 基本文本绘制
canvas.text(50, 50, L"Hello World!", 24, pa2d::Red, pa2d::FontStyle::Bold, L"Arial")
.text(50, 100, "你好世界!", 20, 0xFF0000FF, pa2d::FontStyle::Regular, "SimSun");
// 居中文本
canvas.textCentered(400, 200, L"居中文本", 32, pa2d::Black, pa2d::FontStyle::Bold | pa2d::FontStyle::Italic);
// 矩形内文本
std::wstring longText = L"这是一段很长的文本,会在指定的矩形区域中心显示。";
canvas.textInRect(100, 250, 300, 150, longText, 18, pa2d::DarkGray);
// 自适应字体大小
canvas.textFitRect(450, 250, 250, 100, L"自适应大小", 20, pa2d::Green);
Color 结构体
ARGB 颜色表示,支持多种构造方式和预定义颜色常量。
| 方法/成员 | 说明 |
|---|---|
Color() |
默认构造(黑色透明) |
Color(uint32_t argb) |
从32位ARGB值构造 |
Color(uint8_t a, uint8_t r, uint8_t g, uint8_t b) |
从ARGB分量构造 |
Color(uint8_t r, uint8_t g, uint8_t b) |
从RGB分量构造(Alpha=255) |
Color(uint8_t alpha, const Color& base) |
从基础颜色和透明度构造 |
operator uint32_t() const |
转换为32位整数值 |
uint32_t data, argb |
32位ARGB数据 |
struct { uint8_t b, g, r, a; } |
BGRA分量(注意字节序) |
struct { uint32_t rgb : 24, _ : 8; } |
24位RGB掩码 |
| 常量 | 值 | 说明 |
|---|---|---|
White |
0xFFFFFFFF |
白色 |
Black |
0xFF000000 |
黑色 |
None |
0x00000000 |
透明黑色 |
Red |
0xFFFF0000 |
红色 |
Green |
0xFF00FF00 |
绿色 |
Blue |
0xFF0000FF |
蓝色 |
Cyan |
0xFF00FFFF |
青色 |
Magenta |
0xFFFF00FF |
品红 |
Yellow |
0xFFFFFF00 |
黄色 |
Gray |
0xFF808080 |
灰色 |
LightGray |
0xFFC0C0C0 |
浅灰 |
DarkGray |
0xFF404040 |
深灰 |
Buffer 像素缓冲区
像素缓冲区容器,支持 SIMD 优化操作。所有渲染都是离屏到 Buffer 中,Window 将 Buffer 渲染到显示器。
性能提示
对于最佳性能,建议直接访问 color 指针而非使用 at() 方法。Buffer 使用行主序布局。
| 方法 | 说明 |
|---|---|
Buffer(int width = 0, int height = 0, const Color& color = None) |
构造指定尺寸的缓冲区 |
Buffer(const Buffer& rhs) |
复制构造 |
Buffer(Buffer&& rhs) noexcept |
移动构造 |
~Buffer() |
析构函数 |
size() const |
获取像素总数 |
at(int x, int y) |
访问指定位置像素(边界检查) |
at(int x, int y) const |
访问指定位置像素(常量) |
resize(int width, int height, const Color& color = None) |
调整缓冲区尺寸 |
clear(const Color& color = None) |
清除缓冲区为指定颜色 |
operator=(const Buffer& rhs) |
复制赋值 |
operator=(Buffer&& rhs) noexcept |
移动赋值 |
operator bool() const |
布尔转换(检查有效性) |
Color* color |
直接像素数据访问(行主序布局) |
int width, height |
缓冲区宽度和高度 |
// 创建缓冲区
pa2d::Buffer buffer(800, 600, pa2d::White);
// 直接访问像素(高性能)
for (int y = 0; y < buffer.height; ++y) {
for (int x = 0; x < buffer.width; ++x) {
buffer.color[y * buffer.width + x] = pa2d::Color(x % 256, y % 256, 128);
}
}
// 使用 at() 方法(边界安全)
buffer.at(400, 300) = pa2d::Red;
// 调整尺寸
buffer.resize(1024, 768, pa2d::Blue);
// 转换为 Canvas
pa2d::Canvas canvas(buffer);
文本系统
Windows GDI 文本渲染配置,支持抗锯齿和多种编码。
字体抗锯齿
| 函数 | 说明 |
|---|---|
setTextAntialias(bool enable) |
启用或禁用文本抗锯齿 |
字体编码
| 函数 | 说明 |
|---|---|
TextEncoding getTextEncoding() |
获取当前文本编码 |
setTextEncoding(TextEncoding encoding) |
设置文本编码 |
| 枚举值 | 说明 |
|---|---|
TextEncoding::ANSI |
ANSI 编码(多字节) |
TextEncoding::UTF8 |
UTF-8 编码 |
FontStyle 字体样式
| 方法/常量 | 说明 |
|---|---|
FontStyle::Regular |
常规样式 |
FontStyle::Bold |
粗体 |
FontStyle::Italic |
斜体 |
FontStyle::Underline |
下划线 |
FontStyle::Strikeout |
删除线 |
italicAngle(float angle) const |
设置斜体角度 |
rotation(float angle) const |
设置旋转角度 |
operator|(const FontStyle& rhs) const |
样式组合(或运算) |
operator&(const FontStyle& rhs) const |
样式检查(与运算) |
operator==(const FontStyle& rhs) const |
样式相等性比较 |
// 配置文本系统
pa2d::setTextAntialias(true); // 启用抗锯齿
pa2d::setTextEncoding(pa2d::TextEncoding::UTF8); // 使用UTF-8编码
// 创建字体样式
pa2d::FontStyle boldItalic = pa2d::FontStyle::Bold | pa2d::FontStyle::Italic;
pa2d::FontStyle underlined = pa2d::FontStyle::Underline;
pa2d::FontStyle rotatedStyle = pa2d::FontStyle::Regular.rotation(15.0f); // 旋转15度
// 检查样式
if (boldItalic & pa2d::FontStyle::Bold) {
// 包含粗体样式
}
// 在Canvas中使用
pa2d::Canvas canvas(400, 200);
canvas.text(50, 50, L"抗锯齿文本", 24, pa2d::Black, boldItalic)
.text(50, 100, u8"旋转文本", 20, pa2d::Blue, rotatedStyle);