Files
Aislo/B07_DesignDetail/openwebcad/src/drawControllers/DrawController.ts
T
eomsangdonandClaude Opus 5 ea5ce92725 feat(B07): 표를 객체로 만들어 도면의 표가 진짜 표가 되게 한다
표가 DXF의 표로 나가야 한다(사용자 확정). 지금까지 도면의 표는 선과 문자 뭉치라
내보낼 때 고를 수 있는 길이 하나뿐이었다.

- TableEntity: 열별 폭·행별 높이·칸 문자·병합을 한 객체가 들고 있다. 격자선은 담지
  않고 병합 자리에서 선을 끊는 규칙을 표가 스스로 안다(helpers/table-geometry.ts).
  회전·대칭은 지원하지 않는다 — 표는 축에 붙어 있다.
- 명령: TABLE을 표 객체 생성으로 다시 쓰고 TABLEEDIT(칸 문자)·TABLEROW·TABLECOL·
  TABLEMERGE·TABLEUNMERGE를 더했다. EXPLODE는 표를 선과 문자로 흩는다.
- 그립: 좌측 상단으로 표를 옮기고, 열·행 경계로 폭·높이를 바꾼다.
- 백엔드: 유역 정보표와 횡단 수량 산출표를 표 객체로 낸다. 횡단표는 머리행이 폭
  8등분, 본문이 11열 가중치로 격자가 서로 달라 두 경계를 합친 18열로 만들고 병합으로
  원래 칸을 되살렸다 — 손으로 하던 가로선 끊기가 사라졌다.
- 수량 역추출: 값 Text의 결정적 id로 읽던 것을 칸에 실은 key로 읽도록 옮겼다. 이미
  저장된 도면을 위해 옛 방식을 폴백으로 남겼다.

토적도·종단표는 값이 칸이 아니라 측점 위치에 놓이는 성격이라 이관하지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:12:19 +09:00

66 lines
1.5 KiB
TypeScript

import { type Point, Vector } from '@flatten-js/core';
import { CANVAS_INPUT_FIELD_FONT_SIZE } from '../App.consts.ts';
export interface DrawController {
getCanvasSize(): Point;
getScreenScale(): number;
getScreenOffset(): Point;
worldToTarget(worldCoordinate: Point): Point;
worldsToTargets(worldCoordinates: Point[]): Point[];
targetToWorld(screenCoordinate: Point): Point;
targetsToWorlds(screenCoordinates: Point[]): Point[];
setLineStyles(
isHighlighted: boolean,
isSelected: boolean,
color: string,
lineWidth: number,
dash?: number[]
): void;
setFillStyles(fillColor: string): void;
/** 0~1. 도면층·객체 투명도를 그릴 때 반영한다 */
setOpacity(opacity: number): void;
clear(): void;
drawLine(startPoint: Point, endPoint: Point): void;
drawArc(
centerPoint: Point,
radius: number,
startAngle: number,
endAngle: number,
counterClockwise: boolean
): void;
drawText(
label: string,
basePoint: Point,
options: Partial<{
textDirection?: Vector;
textAlign: 'left' | 'center' | 'right';
textColor: string;
fontSize: number;
fontFamily: string;
bold: boolean;
italic: boolean;
}>
): void;
drawImage(
imageElement: HTMLImageElement,
xMin: number,
yMin: number,
width: number,
height: number,
angle: number
): void;
fillPolygon(...points: Point[]): void;
}
export const DEFAULT_TEXT_OPTIONS = {
textDirection: new Vector(1, 0),
textAlign: 'center' as const,
textColor: '#FFF',
fontSize: CANVAS_INPUT_FIELD_FONT_SIZE,
fontFamily: 'sans-serif',
bold: false,
italic: false,
};