【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 绘图引擎的基础组件之一。

相关推荐
油炸自行车3 小时前
【Qt】Qt Creator Debug模式提示“缺少 Windows CDB 调试器配套的扩展组件“”
开发语言·windows·qt
我要升天!3 小时前
QT -- 网络编程
c语言·开发语言·网络·c++·qt
墨月白3 小时前
[QT]QList 相关接口
qt
GIS阵地4 小时前
Qt实现简易仪表盘
开发语言·c++·qt·pyqt·qgis·qt5·地理信息系统
电子_咸鱼5 小时前
【QT SDK 下载安装步骤详解 + QT Creator 导航栏使用教程】
服务器·开发语言·网络·windows·vscode·qt·visual studio code
CC.GG7 小时前
【Qt】Qt初识
开发语言·qt
xun_xin6668 小时前
如何解决Qt与OpenCV编译器不匹配问题
开发语言·qt·opencv
2401_853448238 小时前
QT控制----单片机控制外设项目
stm32·qt·uart
塵觴葉10 小时前
基于Rust/Qt的五笔编码查询工具
qt·rust·新世纪五笔