Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2016 Anton Krotov
  3.  
  4.     This file is part of fb2read.
  5.  
  6.     fb2read is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation, either version 3 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     fb2read is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with fb2read. If not, see <http://www.gnu.org/licenses/>.
  18. *)
  19.  
  20. MODULE tables;
  21.  
  22. IMPORT V := Vector;
  23.  
  24.  
  25. TYPE
  26.  
  27.  
  28.   Int  = POINTER TO RECORD (V.ANYREC) value: INTEGER END;
  29.  
  30.   Cell = POINTER TO RECORD (V.ANYREC) top, bottom, left, right, colspan, rowspan: INTEGER END;
  31.  
  32.   Tab  = POINTER TO RECORD (V.ANYREC) col, row: INTEGER END;
  33.  
  34.   Table* = POINTER TO RECORD
  35.  
  36.     tab     :  V.VECTOR;
  37.     h_lines :  V.VECTOR;
  38.     v_lines :  V.VECTOR;
  39.     cells*  :  V.VECTOR;
  40.  
  41.     tab_x, tab_y, max_length: INTEGER
  42.  
  43.   END;
  44.  
  45.  
  46. PROCEDURE GetCell (t: Table; cell: INTEGER): Cell;
  47. VAR any: V.ANYPTR;
  48. BEGIN
  49.   any := V.get(t.cells, cell)
  50.   RETURN any(Cell)
  51. END GetCell;
  52.  
  53.  
  54. PROCEDURE GetInt (v: V.VECTOR; idx: INTEGER): INTEGER;
  55. VAR any: V.ANYPTR;
  56. BEGIN
  57.   any := V.get(v, idx)
  58.   RETURN any(Int).value
  59. END GetInt;
  60.  
  61.  
  62. PROCEDURE PutInt (v: V.VECTOR; idx, value: INTEGER);
  63. VAR any: V.ANYPTR;
  64. BEGIN
  65.   any := V.get(v, idx);
  66.   any(Int).value := value
  67. END PutInt;
  68.  
  69.  
  70. PROCEDURE PushInt (v: V.VECTOR; value: INTEGER);
  71. VAR int: Int;
  72. BEGIN
  73.   NEW(int);
  74.   int.value := value;
  75.   V.push(v, int)
  76. END PushInt;
  77.  
  78.  
  79. PROCEDURE get_tab_xy (t: Table; x, y: INTEGER): BOOLEAN;
  80. VAR i: INTEGER;
  81.     tab: Tab; any: V.ANYPTR;
  82.     res: BOOLEAN;
  83. BEGIN
  84.   res := FALSE;
  85.   i := 0;
  86.   WHILE (i < t.tab.count) & ~res DO
  87.     any := V.get(t.tab, i);
  88.     tab := any(Tab);
  89.     res := (tab.col = x) & (tab.row = y);
  90.     INC(i)
  91.   END
  92.   RETURN res
  93. END get_tab_xy;
  94.  
  95.  
  96. PROCEDURE set_tab_xy (t: Table; x, y: INTEGER);
  97. VAR tab: Tab;
  98. BEGIN
  99.   NEW(tab);
  100.   tab.col := x;
  101.   tab.row := y;
  102.   V.push(t.tab, tab)
  103. END set_tab_xy;
  104.  
  105.  
  106. PROCEDURE tr* (t: Table);
  107. BEGIN
  108.   INC(t.tab_y);
  109.   WHILE t.h_lines.count < t.tab_y + 10 DO
  110.     PushInt(t.h_lines, 0)
  111.   END;
  112.   t.tab_x := 0;
  113.   WHILE get_tab_xy(t, t.tab_x, t.tab_y) DO
  114.     INC(t.tab_x);
  115.     WHILE t.v_lines.count < t.tab_x + 10 DO
  116.       PushInt(t.v_lines, 0)
  117.     END
  118.   END
  119. END tr;
  120.  
  121.  
  122. PROCEDURE td* (t: Table; colspan, rowspan: INTEGER);
  123. VAR i, j: INTEGER; _cell: Cell;
  124. BEGIN
  125.   FOR i := t.tab_x TO t.tab_x + colspan - 1 DO
  126.     FOR j := t.tab_y TO t.tab_y + rowspan - 1 DO
  127.       set_tab_xy(t, i, j);
  128.       IF i > t.max_length THEN
  129.         t.max_length := i
  130.       END
  131.     END
  132.   END;
  133.   NEW(_cell);
  134.   _cell.left    := t.tab_x;
  135.   _cell.top     := t.tab_y;
  136.   _cell.right   := t.tab_x + colspan;
  137.   WHILE t.v_lines.count < _cell.right + 10 DO
  138.     PushInt(t.v_lines, 0)
  139.   END;
  140.   _cell.bottom  := t.tab_y + rowspan;
  141.   WHILE t.h_lines.count < _cell.bottom + 10 DO
  142.     PushInt(t.h_lines, 0)
  143.   END;
  144.   _cell.colspan := colspan;
  145.   _cell.rowspan := rowspan;
  146.   V.push(t.cells, _cell);
  147.   WHILE get_tab_xy(t, t.tab_x, t.tab_y) DO
  148.     INC(t.tab_x);
  149.     WHILE t.v_lines.count < t.tab_x + 10 DO
  150.       PushInt(t.v_lines, 0)
  151.     END
  152.   END
  153. END td;
  154.  
  155.  
  156. PROCEDURE set_width* (t: Table; cell, width: INTEGER);
  157. VAR left, right, old_width, d_width, i: INTEGER; _cell: Cell;
  158. BEGIN
  159.   _cell := GetCell(t, cell);
  160.   right := GetInt(t.v_lines, _cell.right);
  161.   left  := GetInt(t.v_lines, _cell.left);
  162.   old_width := right - left;
  163.   d_width := width - old_width;
  164.   PutInt(t.v_lines, _cell.right, left + width);
  165.   FOR i := _cell.right + 1 TO t.v_lines.count - 1 DO
  166.     PutInt(t.v_lines, i, GetInt(t.v_lines, i) + d_width)
  167.   END
  168. END set_width;
  169.  
  170.  
  171. PROCEDURE set_height* (t: Table; cell, height: INTEGER);
  172. VAR top, bottom, old_height, d_height, i: INTEGER; _cell: Cell;
  173. BEGIN
  174.   _cell := GetCell(t, cell);
  175.   top := GetInt(t.h_lines, _cell.top);
  176.   bottom  := GetInt(t.h_lines, _cell.bottom);
  177.   old_height := bottom - top;
  178.   d_height := height - old_height;
  179.   PutInt(t.h_lines, _cell.bottom, top + height);
  180.   FOR i := _cell.bottom + 1 TO t.h_lines.count - 1 DO
  181.     PutInt(t.h_lines, i, GetInt(t.h_lines, i) + d_height)
  182.   END
  183. END set_height;
  184.  
  185.  
  186. PROCEDURE get_height* (t: Table; cell: INTEGER): INTEGER;
  187. VAR _cell: Cell;
  188. BEGIN
  189.   _cell := GetCell(t, cell)
  190.   RETURN GetInt(t.h_lines, _cell.bottom) - GetInt(t.h_lines, _cell.top)
  191. END get_height;
  192.  
  193.  
  194. PROCEDURE get_width* (t: Table; cell: INTEGER): INTEGER;
  195. VAR _cell: Cell;
  196. BEGIN
  197.   _cell := GetCell(t, cell)
  198.   RETURN GetInt(t.v_lines, _cell.right) - GetInt(t.v_lines, _cell.left)
  199. END get_width;
  200.  
  201.  
  202. PROCEDURE get_x* (t: Table; cell: INTEGER): INTEGER;
  203. VAR _cell: Cell;
  204. BEGIN
  205.   _cell := GetCell(t, cell)
  206.   RETURN GetInt(t.v_lines, _cell.left)
  207. END get_x;
  208.  
  209.  
  210. PROCEDURE get_y* (t: Table; cell: INTEGER): INTEGER;
  211. VAR _cell: Cell;
  212. BEGIN
  213.   _cell := GetCell(t, cell)
  214.   RETURN GetInt(t.h_lines, _cell.top)
  215. END get_y;
  216.  
  217.  
  218. PROCEDURE get_table_height* (t: Table): INTEGER;
  219.   RETURN GetInt(t.h_lines, t.tab_y + 1)
  220. END get_table_height;
  221.  
  222.  
  223. PROCEDURE table* (t: Table; tab_width: INTEGER; open: BOOLEAN);
  224. VAR i, width: INTEGER; _cell: Cell;
  225. BEGIN
  226.   IF open THEN
  227.     t.cells   := V.create(1024);
  228.     t.v_lines := V.create(1024);
  229.     t.h_lines := V.create(1024);
  230.     t.tab     := V.create(1024);
  231.     t.tab_x := 0;
  232.     t.tab_y := -1;
  233.     t.max_length := 0;
  234.   ELSE
  235.     width := tab_width DIV (t.max_length + 1);
  236.     FOR i := 0 TO t.cells.count - 1 DO
  237.       _cell := GetCell(t, i);
  238.       set_width(t, i, width * _cell.colspan)
  239.     END
  240.   END
  241. END table;
  242.  
  243.  
  244. PROCEDURE destroy* (t: Table);
  245. BEGIN
  246.   IF t # NIL THEN
  247.     V.destroy(t.tab,     NIL);
  248.     V.destroy(t.h_lines, NIL);
  249.     V.destroy(t.v_lines, NIL);
  250.     V.destroy(t.cells,   NIL);
  251.     DISPOSE(t)
  252.   END
  253. END destroy;
  254.  
  255.  
  256. END tables.
  257.