1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
import Ratio from "../../math/Ratio";
import Rect from "../../math/Rect";
import { Cell, CellRef, Grid, Row, RowRef } from "./types";
export interface RenderedCell extends Cell {
cellRef: CellRef;
renderedRowIndex: number;
rect: Rect;
}
export interface RenderedRow {
rowRef: RowRef;
rect: Rect;
renderedCells: RenderedCell[];
}
export interface RenderedGrid extends Grid {
rect: Rect;
renderedRows: RenderedRow[];
}
function renderCell(
grid: Grid,
cell: Cell,
cellRef: CellRef,
renderedRowIndex: number,
topLeftX: number,
topLeftY: number,
): RenderedCell {
const width = cell.widthRatio
.divideRatio(grid.baseCellWidthRatio)
.multiplyRatio(Ratio.fromInteger(grid.baseCellSize))
.toNumber();
const rect = new Rect(topLeftX, topLeftY, width, grid.baseCellSize);
return { ...cell, cellRef, rect, renderedRowIndex };
}
function renderRow(
grid: Grid,
row: Row,
rowRef: RowRef,
renderedRowIndex: number,
topLeftY: number,
): RenderedRow {
if (row.cells.length === 0) {
return {
...row,
rowRef,
rect: new Rect(0, topLeftY, 0, 0),
renderedCells: [],
};
}
let topLeftX = 0;
const renderedCells = row.cells.map((cell, cellIndex) => {
const cellRef = { ...rowRef, cellIndex };
const renderedCell = renderCell(
grid,
cell,
cellRef,
renderedRowIndex,
topLeftX,
topLeftY,
);
topLeftX = renderedCell.rect.bottomRight.x;
return renderedCell;
});
const { topLeft } = renderedCells[0].rect;
const { bottomRight } = renderedCells.at(-1)!.rect;
const rect = new Rect(
topLeft.x,
topLeft.y,
bottomRight.x - topLeft.x,
bottomRight.y - topLeft.y,
);
return { ...row, renderedCells, rect, rowRef };
}
function renderRows(grid: Grid): RenderedRow[] {
const renderedRows: RenderedRow[] = [];
let partIndex = 0;
let rowIndex = 0;
let topLeftY = 0;
let renderedRowIndex = 0;
while (true) {
if (!grid.parts[partIndex]?.rows[rowIndex]) break;
const row = grid.parts[partIndex].rows[rowIndex];
const rowRef = { partIndex, rowIndex };
const renderedRow = renderRow(
grid,
row,
rowRef,
renderedRowIndex,
topLeftY,
);
topLeftY = renderedRow.rect.bottomRight.y;
renderedRows.push(renderedRow);
if (!grid.parts[++partIndex]) {
partIndex = 0;
rowIndex++;
}
renderedRowIndex++;
}
return renderedRows;
}
export default function renderGrid(grid: Grid) {
const renderedRows = renderRows(grid);
const rect = renderedRows[0].rect.extend(renderedRows.at(-1)!.rect);
return { ...grid, rect, renderedRows };
}
|