【LibreCAD】RS_Pen 类详解

1. 默认构造函数实现

cpp 复制代码
RS_Pen::RS_Pen() :
    RS_Pen(RS_Color{Qt::black}, RS2::WidthByLayer, RS2::LineByLayer)
{}

关键点:

  1. 委托构造函数:使用 C++11 的委托构造函数特性
  2. 默认值
    • 颜色:黑色(Qt::black
    • 线宽:按图层(RS2::WidthByLayer
    • 线型:按图层(RS2::LineByLayer
  3. 设计意图:创建一个"继承图层属性"的默认笔

2. 流输出运算符实现

cpp 复制代码
std::ostream& operator << (std::ostream& os, const RS_Pen& p) {
    os << " pen color: " << p.getColor()
    << " pen width: " << p.getWidth()
    << " pen screen width: " << p.getScreenWidth()
    << " pen line type: " << p.getLineType()
    << " flags: " << (p.getFlag(RS2::FlagInvalid) ? "INVALID" : "")
    << std::endl;
    return os;
}

输出内容:

  1. 颜色 :通过 getColor() 获取
  2. 线宽:逻辑线宽(枚举值)
  3. 屏幕宽度:实际显示像素宽度
  4. 线型:线条样式
  5. 标志:显示是否为无效笔

3. 类设计的完整理解

3.1 构造函数的三种模式

cpp 复制代码
// 1. 默认构造:黑色,属性继承图层
RS_Pen pen1;

// 2. 指定属性构造
RS_Pen pen2(RS_Color(Qt::red), RS2::Width03, RS2::DashLine);

// 3. 标志位构造(常用于无效笔)
RS_Pen pen3(RS2::FlagInvalid);

3.2 属性继承机制

cpp 复制代码
// 检查各种继承状态
pen.isColorByLayer();    // 颜色是否继承图层
pen.isWidthByLayer();    // 线宽是否继承图层
pen.isLineTypeByLayer(); // 线型是否继承图层

3.3 属性更新机制

cpp 复制代码
// 从另一个笔复制属性
pen.updateBy(otherPen);
// 这会复制颜色、线型、线宽、透明度、虚线偏移等

// 选择性复制
pen.setColorFromPen(otherPen);
pen.setWidthFromPen(otherPen);

4. 重要特性详解

4.1 透明度支持

cpp 复制代码
float alpha = pen.getAlpha();  // 获取透明度 (0.0-1.0)
pen.setAlpha(0.5);             // 设置为半透明

4.2 虚线偏移

cpp 复制代码
pen.setDashOffset(2.5);        // 设置虚线图案偏移
double offset = pen.dashOffset(); // 获取偏移值

4.3 有效性检查

cpp 复制代码
if (pen.isValid()) {
    // 笔有效,可以使用
}

4.4 比较操作

cpp 复制代码
// 简单比较(忽略alpha和dashOffset)
if (pen1 == pen2) { ... }

// 精确比较(包含所有属性)
if (pen1.isSameAs(pen2, patternOffset)) { ... }

5. 实际应用示例

示例1:创建和使用笔

cpp 复制代码
// 创建红色实线,中等宽度
RS_Pen drawingPen(RS_Color(Qt::red), 
                  RS2::Width03, 
                  RS2::SolidLine);

// 设置为半透明
drawingPen.setAlpha(0.7);

// 设置虚线偏移
drawingPen.setDashOffset(10.0);

// 检查有效性
if (drawingPen.isValid()) {
    // 使用笔进行绘制
}

示例2:图层继承

cpp 复制代码
// 创建按图层继承的笔
RS_Pen layerPen;  // 默认就是按图层

// 检查属性继承
if (layerPen.hasByLayerAttributes()) {
    // 当实体添加到图层时,会自动获取图层属性
}

示例3:调试输出

cpp 复制代码
RS_Pen pen;
std::cout << pen;  // 输出: "pen color: [black] pen width: -1 ..."

6. 设计模式分析

6.1 Builder模式元素

虽然不完全是Builder模式,但提供了链式设置的潜力:

cpp 复制代码
pen.setColor(red).setWidth(RS2::Width03).setLineType(RS2::DashLine);

6.2 Flyweight模式元素

  • 可能共享常用笔设置以减少内存使用
  • 通过比较运算符支持对象复用

6.3 Strategy模式元素

  • 笔的渲染策略(线型、宽度)可以在运行时改变
  • 支持按图层/图块动态切换属性

7. 与其他类的关系

RS_Color

cpp 复制代码
RS_Color color = pen.getColor();  // 获取颜色对象
pen.setColor(RS_Color(255, 0, 0)); // 设置颜色

RS_Entity

cpp 复制代码
// 实体类会包含RS_Pen成员
class RS_Entity {
    RS_Pen pen;  // 实体的绘制属性
    // ...
};

RS_Layer

cpp 复制代码
// 图层提供默认笔属性
class RS_Layer {
    RS_Pen pen;  // 图层的默认笔设置
    // ...
};

8. 性能考虑

  1. 小对象优化RS_Pen 是值类型,适合按值传递
  2. 内联函数:大部分getter/setter已内联声明
  3. 默认成员初始化:C++11的类内成员初始化
  4. 移动语义:支持高效的复制和赋值

总结

RS_Pen 类是 LibreCAD 中一个精心设计的工具类,它:

  1. 封装了绘图属性:颜色、线宽、线型、透明度
  2. 支持继承机制:按图层、图块继承属性
  3. 提供完整接口:getter/setter、比较、输出
  4. 注重性能:小对象、内联函数
  5. 扩展性强:支持虚线偏移等高级特性

这个类的设计体现了 CAD 软件对图形属性管理的专业需求,是 LibreCAD 绘图引擎的基础组件之一。

相关推荐
郝学胜-神的一滴18 小时前
Qt与Web混合编程:CEF与QCefView深度解析
开发语言·前端·javascript·c++·qt·程序人生·软件构建
SunkingYang1 天前
QT中使用Lambda表达式作为槽函数用法,以及捕获列表和参数列表用法与区别
c++·qt·用法·lambda表达式·捕获列表·槽函数·参数列表
千疑千寻~1 天前
【Qt图形】详细介绍Qt中的图形场景、图元、视图
qt
千疑千寻~1 天前
【Qt图形】Qt中的图形场景、图元、视图 的坐标的转换
qt
cuicuiniu5212 天前
如何将CAD图纸进行黑白打印?
cad·cad看图·cad看图软件·cad看图王
一叶之秋14122 天前
Qt常用控件(三)
开发语言·qt
_OP_CHEN2 天前
【从零开始的Qt开发指南】(二十三)Qt 界面优化之绘图实战:解锁自定义界面的无限可能
开发语言·qt
闻缺陷则喜何志丹2 天前
【.NetAPI]统计标注的值、上公差、下公差
数学·.net·cad·netapi
郝学胜-神的一滴2 天前
使用QVideoWidget实现高效视频播放:从基础到高级应用
开发语言·c++·qt·程序人生·音视频
叶之道2 天前
MacOS 配置 Qt 开发环境
qt·macos