# Service 目录绘制服务改造完成总结

## 改造目标

将所有绘制服务统一使用 `baseDraw.ts` 和 `baseHeaderDraw.ts` 作为基类，提取公共部分并统一 Header 绘制。

## 完成的工作

### 1. ✅ 统一基础服务类

所有绘制服务现在都继承自 `BaseDrawService`（位于 `service/baseDraw.ts`）：

- ✅ `TextDrawService` - 文字涂色服务
- ✅ `ShapeDrawService` - 图形涂色服务
- ✅ `FindWordDrawService` - 找字涂色服务
- ✅ `WordDrawService` - 田字格练字服务

### 2. ✅ 统一 Header 绘制

所有服务使用统一的 Header 绘制功能（位于 `service/baseHeaderDraw.ts`）：

- `drawBaseHeader()` - 完整 Header（包含 Logo、应用名称、标题、副标题）
- `drawBaseMiniHeader()` - 迷你 Header（简化版本）

### 3. ✅ 统一使用逻辑像素

所有服务现在使用逻辑像素（尺寸除以3），与数学模块保持一致：

- Canvas 尺寸通过 `setPaper()` 统一处理 DPR（device pixel ratio）
- 所有绘制代码中的硬编码尺寸都已转换为逻辑像素
- 坐标计算统一使用 `this.canvasWidth` 和 `this.canvasHeight`

### 4. ✅ 清理重复代码

删除了以下重复方法，统一使用基类实现：

- `setPrintConfig()` - 统一在基类中实现
- `setPaper()` - 统一在基类中实现
- `clear()` - 统一在基类中实现
- `drawHeader()` / `drawMiniHeader()` - 统一在基类中实现
- `drawDivider()` - 统一在基类中实现

## 改造详情

### TextDrawService

**改造内容：**

- 继承 `BaseDrawService`
- 移除自定义的 `setPaper()`, `clear()`, `drawHeader()`, `drawMiniHeader()`
- 所有尺寸转换为逻辑像素：
    - 半径：80 → 27
    - 字体：72px → 24px, 48px → 16px
    - 边距：80 → 27, 220 → 73
    - 坐标：200 → 67, 304 → 101

**关键方法：**

- `drawLegend()` - 绘制示例区域
- `drawContent()` - 绘制内容区域

### ShapeDrawService

**改造内容：**

- 继承 `BaseDrawService`
- 移除自定义的绘制方法
- 所有尺寸转换为逻辑像素：
    - 图形大小：200 → 67, 180 → 60
    - 字体：36px → 12px
    - 间距：120 → 40, 160 → 53

**关键方法：**

- `drawLegend()` - 绘制示例区域
- `drawContent()` - 绘制内容区域

### FindWordDrawService

**改造内容：**

- 继承 `BaseDrawService`
- 移除自定义的绘制方法
- 所有尺寸转换为逻辑像素：
    - 半径：80 → 27
    - 字体：72px → 24px
    - 模板坐标转换：`pos.x / 3`, `pos.y / 3`

**关键方法：**

- `drawContent()` - 绘制找字内容（中心大字 + 四周字符）

**特殊处理：**

- `getPositionsFromTemplate()` 函数中增加了坐标转换逻辑，将模板中的原始像素坐标转换为逻辑像素

### WordDrawService

**改造内容：**

- 继承 `BaseDrawService`
- 移除自定义的绘制方法
- 所有尺寸转换为逻辑像素：
    - 田字格大小：140 → 47
    - 边距：120 → 40, 50 → 17
    - 间距：24 → 8, 36 → 12

**关键方法：**

- `drawLayout()` - 绘制页眉和基础布局
- `drawContent()` - 绘制田字格和练字内容
- `drawPracticeContent()` - 绘制练习内容
- `getMaxGridLayout()` - 计算最大网格布局

## 架构优势

1. ✅ **代码复用**：公共逻辑集中在 `BaseDrawService` 基类中
2. ✅ **统一 Header**：所有服务使用相同的 Header 绘制逻辑
3. ✅ **统一像素标准**：所有服务使用逻辑像素，保持一致
4. ✅ **易于维护**：修改 Header 或基础功能只需修改一个地方
5. ✅ **类型安全**：TypeScript 类型支持完整

## 注意事项

### 坐标转换

所有硬编码的尺寸值都已转换为逻辑像素（除以3）：

```typescript
// 原始像素 → 逻辑像素
const radius = 27; // 80/3≈27
const fontSize = 24; // 72/3=24
const margin = 40; // 120/3=40
```

### 模板坐标转换

`FindWordDrawService` 中使用的 `POSITION_TEMPLATES` 坐标是基于原始像素的，需要在使用时转换：

```typescript
const x = centerX + pos.x / 3; // 转换为逻辑像素
const y = centerY + pos.y / 3; // 转换为逻辑像素
```

### Canvas 尺寸

所有服务现在统一使用：

- `this.canvasWidth` - 逻辑像素宽度
- `this.canvasHeight` - 逻辑像素高度

这些值在 `setPaper()` 中设置，已经处理了 DPR。

## 向后兼容性

- ✅ `drawServiceFactory.ts` 接口无需修改
- ✅ 所有服务的公共接口保持不变
- ✅ 只改变了内部实现方式

## 后续优化建议

1. 可以考虑将 `findWordTemplate.ts` 中的坐标模板也转换为逻辑像素，避免运行时转换
2. 可以考虑创建更多的基础绘制工具函数（如绘制表格、绘制网格等）
3. 可以考虑支持更多 Paper 尺寸（目前仅支持 A4）

## 测试建议

1. 验证所有绘制服务功能正常
2. 验证 Header 正确显示
3. 验证尺寸和比例正确
4. 验证不同 Header 类型（wechat, LogoImage, noLogoImage, minimal）
5. 验证打印输出质量
