1 /**
2  * Table support
3  */
4 module harud.table;
5 
6 import harud.page: Page;
7 import harud.types: Rect, HaruTextAlignment, HaruCMYKColor;
8 
9 
10 /**
11  * Describe a table.
12  *
13  * A `Table` is a layout element that represents data in a two-dimensional grid
14  */
15 class Table {
16    private Page page;
17    this(Page page, Rect rect) {
18       assert(page !is null);
19       this.page = page;
20       x0 = x = rect.left;
21       y0 = y = rect.top;
22       width = rect.right - rect.left;
23       height = rect.top - rect.bottom;
24       _divSize = width / 12;
25       currentHeight = 0.;
26    }
27 
28    private float x0;
29    private float y0;
30    private float x;
31    private float y;
32    private float height;
33    private float width;
34    void addCol(Column col) {
35       import harud.extension: addTextRect, addRect, setFillColor, setStrokeColor;
36       import harud.util: createTopLeftRect;
37 
38       drawBorder(col);
39       fillCell(col);
40 
41       page.beginText;
42       float w = col.colSpan * _divSize;
43       Rect r = createTopLeftRect(x + col.paddingLeft, y - col.paddingBottom, w - col.paddingLeft - col.paddingRight, currentHeight - col.paddingTop - col.paddingBottom);
44       page.addTextRect(r, col.text, col.alignment);
45       page.endText;
46 
47       x += col.colSpan * _divSize;
48    }
49 
50    private void fillCell(Column col) {
51       import harud.extension: addRect, setFillColor, setStrokeColor;
52       import harud.util: createTopLeftRect;
53 
54       page.graphicSave();
55 
56       page.setFillColor(col.fillColor);
57       Rect border = createTopLeftRect(x, y, col.colSpan * _divSize, currentHeight);
58       page.addRect(border);
59       page.fill;
60 
61       page.graphicRestore;
62   }
63 
64    private void drawBorder(Column col) {
65       import std.stdio;
66       import harud.extension: addTextRect, addRect, setFillColor, setStrokeColor;
67 
68       page.graphicSave();
69 
70       page.setStrokeColor(col.borderColor);
71       float w = col.colSpan * _divSize;
72       float h = currentHeight;
73       if (col.border & CellBorder.top) {
74          page.moveTo(x, y);
75          page.lineTo(x + w, y);
76       }
77       if (col.border & CellBorder.right) {
78          page.moveTo(x + w, y);
79          page.lineTo(x + w, y - h);
80       }
81       if (col.border & CellBorder.bottom) {
82          page.moveTo(x + w, y - h);
83          page.lineTo(x, y - h);
84       }
85       if (col.border & CellBorder.left) {
86          page.moveTo(x, y - h);
87          page.lineTo(x, y);
88       }
89       page.moveTo(x, y);
90       page.stroke;
91 
92       page.graphicRestore;
93    }
94 
95    private float currentHeight;
96    void addRow(float height) {
97       x = x0;
98       y -= currentHeight;
99       currentHeight = height;
100    }
101 
102    private float _divSize;
103    float divSize() {
104       return _divSize;
105    }
106 }
107 
108 /**
109  * Describes a table colums (cell)
110  */
111 struct Column {
112    int colSpan;
113    string text;
114    HaruTextAlignment alignment = HaruTextAlignment.left;
115    CellBorder border = CellBorder.none;
116 
117    float paddingLeft    = 0;
118    float paddingTop     = 0;
119    float paddingRight   = 0;
120    float paddingBottom  = 0;
121 
122    HaruCMYKColor fillColor = HaruCMYKColor(0, 0, 0, 0); // white
123    HaruCMYKColor borderColor = HaruCMYKColor(0, 0, 0, 1); // black
124 }
125 
126 /**
127  * Cell border
128  */
129 enum CellBorder {
130    none = 0x0,
131    top = 0x01,
132    right = 0x02,
133    bottom = 0x04,
134    left = 0x08,
135    all = 0x0F
136 }