output-item: Collapse the inheritance hierarchy into a single struct.
[pspp] / src / output / table.h
index 06427ac32b75bac0d91670840c3a10c4307b8484..add7bf94bee3da0bad444c9b3880682d6587ffda 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997, 1998, 1999, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2009, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 /* Tables.
 
 
 /* Tables.
 
-.  A table is a rectangular grid of cells.  Cells can be joined to form larger
+   A table is a rectangular grid of cells.  Cells can be joined to form larger
    cells.  Rows and columns can be separated by rules of various types.  Rows
    at the top and bottom of a table and columns at the left and right edges of
    a table can be designated as headers, which means that if the table must be
    broken across more than one page, those rows or columns are repeated on each
    page.
 
    cells.  Rows and columns can be separated by rules of various types.  Rows
    at the top and bottom of a table and columns at the left and right edges of
    a table can be designated as headers, which means that if the table must be
    broken across more than one page, those rows or columns are repeated on each
    page.
 
-   Every table is an instance of a particular table class that is responsible
-   for keeping track of cell data.  By far the most common table class is
-   struct tab_table (see output/tab.h).  This header also declares some other
-   kinds of table classes, near the end of the file.
-
-   A table is not itself an output_item, and thus a table cannot by itself be
-   used for output, but they can be embedded inside struct table_item (see
-   table-item.h) for that purpose. */
+   Some drivers use tables as an implementation detail of rendering pivot
+   tables.
+*/
 
 #include <stdbool.h>
 
 #include <stdbool.h>
+#include <stdint.h>
 #include <stddef.h>
 #include <stddef.h>
+#include "libpspp/compiler.h"
 
 struct casereader;
 struct fmt_spec;
 
 struct casereader;
 struct fmt_spec;
+struct pivot_footnote;
+struct pivot_value;
+struct pool;
+struct table_item;
 struct variable;
 
 struct variable;
 
-/* Properties of a table cell. */
-enum
-  {
-    TAB_NONE = 0,
+/* A table axis.
 
 
-    /* Alignment of cell contents. */
-    TAB_RIGHT      = 0 << 0,    /* Right justify. */
-    TAB_LEFT       = 1 << 0,    /* Left justify. */
-    TAB_CENTER     = 2 << 0,    /* Centered. */
-    TAB_ALIGNMENT  = 3 << 0,   /* Alignment mask. */
+   Many table-related declarations use 2-element arrays in place of "x" and "y"
+   variables.  This reduces code duplication significantly, because much table
+   code treats rows and columns the same way.
 
 
-    /* These flags may be combined with any alignment. */
-    TAB_EMPH       = 1 << 2,    /* Emphasize cell contents. */
-    TAB_FIX        = 1 << 3,    /* Use fixed font. */
+   A lot of code that uses these enumerations assumes that the two values are 0
+   and 1, so don't change them to other values. */
+enum table_axis
+  {
+    TABLE_HORZ,
+    TABLE_VERT
+#define TABLE_N_AXES 2
+  };
 
 
-    /* Bits with values (1 << TAB_FIRST_AVAILABLE) and higher are
-       not used, so they are available for subclasses to use as
-       they wish. */
-    TAB_FIRST_AVAILABLE = 4
+struct cell_color
+  {
+    uint8_t alpha, r, g, b;
   };
 
   };
 
-/* Styles for the rules around table cells. */
-enum
+#define CELL_COLOR(r, g, b) { 255, r, g, b }
+#define CELL_COLOR_BLACK CELL_COLOR (0, 0, 0)
+#define CELL_COLOR_WHITE CELL_COLOR (255, 255, 255)
+
+static inline bool
+cell_color_equal (const struct cell_color *a, const struct cell_color *b)
+{
+  return a->alpha == b->alpha && a->r == b->r && a->g == b->g && a->b == b->b;
+}
+
+void cell_color_dump (const struct cell_color *);
+
+enum table_stroke
   {
   {
-    TAL_0,                     /* No line. */
-    TAL_GAP,                    /* Spacing but no line. */
-    TAL_1,                     /* Single line. */
-    TAL_2,                     /* Double line. */
-    N_LINES
+    TABLE_STROKE_NONE,
+    TABLE_STROKE_SOLID,
+    TABLE_STROKE_DASHED,
+    TABLE_STROKE_THICK,
+    TABLE_STROKE_THIN,
+    TABLE_STROKE_DOUBLE,
+    TABLE_N_STROKES,
   };
 
   };
 
-/* Given line styles A and B (each one of the TAL_* enumeration constants
-   above), returns a line style that "combines" them, that is, that gives a
-   reasonable line style choice for a rule for different reasons should have
-   both styles A and B.
+const char *table_stroke_to_string (enum table_stroke);
 
 
-   Used especially for pasting tables together (see table_paste()). */
-static inline int table_rule_combine (int a, int b)
+/* Given strokes A and B, returns a stroke that "combines" them, that is, that
+   gives a reasonable stroke choice for a rule for different reasons should
+   have both styles A and B. */
+static inline int
+table_stroke_combine (enum table_stroke a, enum table_stroke b)
 {
   return a > b ? a : b;
 }
 
 {
   return a > b ? a : b;
 }
 
-/* A table axis.
+struct table_border_style
+  {
+    enum table_stroke stroke;
+    struct cell_color color;
+  };
 
 
-   Many table-related declarations use 2-element arrays in place of "x" and "y"
-   variables.  This reduces code duplication significantly, because much table
-   code has treat rows and columns the same way.
+#define TABLE_BORDER_STYLE_INITIALIZER { TABLE_STROKE_SOLID, CELL_COLOR_BLACK }
 
 
-   A lot of code that uses these enumerations assumes that the two values are 0
-   and 1, so don't change them to other values. */
-enum table_axis
+enum table_halign
   {
   {
-    TABLE_HORZ,
-    TABLE_VERT,
-    TABLE_N_AXES
+    TABLE_HALIGN_RIGHT,
+    TABLE_HALIGN_LEFT,
+    TABLE_HALIGN_CENTER,
+    TABLE_HALIGN_MIXED,
+    TABLE_HALIGN_DECIMAL
+  };
+
+const char *table_halign_to_string (enum table_halign);
+
+enum table_valign
+  {
+    TABLE_VALIGN_TOP,
+    TABLE_VALIGN_CENTER,
+    TABLE_VALIGN_BOTTOM,
+  };
+
+const char *table_valign_to_string (enum table_valign);
+
+struct cell_style
+  {
+    enum table_halign halign;
+    enum table_valign valign;
+    double decimal_offset;       /* In 1/96" units. */
+    char decimal_char;           /* Either '.' or ','. */
+    int margin[TABLE_N_AXES][2]; /* In 1/96" units. */
+  };
+
+#define CELL_STYLE_INITIALIZER { CELL_STYLE_INITIALIZER__ }
+#define CELL_STYLE_INITIALIZER__                                \
+        .margin = { [TABLE_HORZ][0] = 8, [TABLE_HORZ][1] = 11,  \
+                    [TABLE_VERT][0] = 1, [TABLE_VERT][1] = 1 }
+
+void cell_style_dump (const struct cell_style *);
+
+struct font_style
+  {
+    bool bold, italic, underline, markup;
+    struct cell_color fg[2], bg[2];
+    char *typeface;
+    int size;                   /* In 1/72" units. */
+  };
+
+#define FONT_STYLE_INITIALIZER { FONT_STYLE_INITIALIZER__ }
+#define FONT_STYLE_INITIALIZER__                                        \
+        .fg = { [0] = CELL_COLOR_BLACK, [1] = CELL_COLOR_BLACK},        \
+        .bg = { [0] = CELL_COLOR_WHITE, [1] = CELL_COLOR_WHITE},
+
+void font_style_copy (struct pool *,
+                      struct font_style *, const struct font_style *);
+void font_style_uninit (struct font_style *);
+void font_style_dump (const struct font_style *);
+bool font_style_equal (const struct font_style *, const struct font_style *);
+
+struct table_area_style
+  {
+    struct cell_style cell_style;
+    struct font_style font_style;
+  };
+
+#define TABLE_AREA_STYLE_INITIALIZER { TABLE_AREA_STYLE_INITIALIZER__ }
+#define TABLE_AREA_STYLE_INITIALIZER__          \
+       .cell_style = CELL_STYLE_INITIALIZER,    \
+       .font_style = FONT_STYLE_INITIALIZER
+
+struct table_area_style *table_area_style_clone (
+  struct pool *, const struct table_area_style *);
+void table_area_style_copy (struct pool *, struct table_area_style *,
+                            const struct table_area_style *);
+void table_area_style_uninit (struct table_area_style *);
+void table_area_style_free (struct table_area_style *);
+
+/* Properties of a table cell. */
+enum
+  {
+    TAB_NONE = 0,
+    TAB_ROTATE     = 1 << 4,    /* Rotate cell contents 90 degrees. */
+
+    TAB_STYLE_SHIFT = 5,
+    TAB_STYLE_MASK = 7 << TAB_STYLE_SHIFT,
+
+    /* Internal use by tab.c only. */
+    TAB_JOIN = 1 << 14,
   };
 
 /* A table. */
 struct table
   {
   };
 
 /* A table. */
 struct table
   {
-    const struct table_class *class;
+    struct pool *container;
 
     /* Table size.
 
 
     /* Table size.
 
@@ -127,64 +219,49 @@ struct table
        indicated by a reference count greater than 1.  When this is the case,
        the table must not be modified. */
     int ref_cnt;
        indicated by a reference count greater than 1.  When this is the case,
        the table must not be modified. */
     int ref_cnt;
+
+    /* Table contents.
+
+       Each array element in cc[] is ordinarily a "struct pivot_value *".
+       If TAB_JOIN (defined in table.c) is set in ct[] for the element,
+       however, it is a joined cell and the corresponding element of cc[]
+       points to a struct table_cell. */
+    void **cc;                  /* Cell contents; void *[nr][nc]. */
+    unsigned short *ct;                /* Cell types; unsigned short[nr][nc]. */
+    struct table_area_style *styles[8];
+
+    /* Rules. */
+    unsigned char *rh;         /* Horiz rules; unsigned char[nr+1][nc]. */
+    unsigned char *rv;         /* Vert rules; unsigned char[nr][nc+1]. */
+    struct cell_color *rule_colors[32];
   };
 
 /* Reference counting. */
 struct table *table_ref (const struct table *);
 void table_unref (struct table *);
 bool table_is_shared (const struct table *);
   };
 
 /* Reference counting. */
 struct table *table_ref (const struct table *);
 void table_unref (struct table *);
 bool table_is_shared (const struct table *);
-struct table *table_unshare (struct table *);
-
-/* Returns the number of columns or rows, respectively, in T. */
-static inline int table_nc (const struct table *t)
-        { return t->n[TABLE_HORZ]; }
-static inline int table_nr (const struct table *t)
-        { return t->n[TABLE_VERT]; }
-
-/* Returns the number of left, right, top, or bottom headers, respectively, in
-   T.  */
-static inline int table_hl (const struct table *t)
-        { return t->h[TABLE_HORZ][0]; }
-static inline int table_hr (const struct table *t)
-        { return t->h[TABLE_HORZ][1]; }
-static inline int table_ht (const struct table *t)
-        { return t->h[TABLE_VERT][0]; }
-static inline int table_hb (const struct table *t)
-        { return t->h[TABLE_VERT][1]; }
-
-/* Set headers. */
-void table_set_hl (struct table *, int hl);
-void table_set_hr (struct table *, int hr);
-void table_set_ht (struct table *, int ht);
-void table_set_hb (struct table *, int hb);
-\f
-/* Table classes. */
-
-/* Simple kinds of tables. */
-struct table *table_from_string (unsigned int options, const char *);
-struct table *table_from_variables (unsigned int options,
-                                    struct variable **, size_t);
-struct table *table_from_casereader (const struct casereader *,
-                                     size_t column,
-                                     const char *heading,
-                                     const struct fmt_spec *);
-
-/* Combining tables. */
-struct table *table_paste (struct table *, struct table *,
-                           enum table_axis orientation);
-struct table *table_hpaste (struct table *left, struct table *right);
-struct table *table_vpaste (struct table *top, struct table *bottom);
-
-/* Taking subsets of tables. */
-struct table *table_select (struct table *, int rect[TABLE_N_AXES][2]);
-struct table *table_select_slice (struct table *, enum table_axis,
-                                  int z0, int z1, bool add_headers);
-struct table *table_select_columns (struct table *,
-                                    int x0, int x1, bool add_headers);
-struct table *table_select_rows (struct table *,
-                                 int y0, int y1, bool add_headers);
-
-/* Miscellaneous table operations. */
-struct table *table_transpose (struct table *);
+
+/* Rule masks. */
+#define TAB_RULE_TYPE_MASK   7
+#define TAB_RULE_TYPE_SHIFT  0
+#define TAB_RULE_STYLE_MASK  (31 << TAB_RULE_STYLE_SHIFT)
+#define TAB_RULE_STYLE_SHIFT 3
+
+/* Tables. */
+struct table *table_create (int nc, int nr, int hl, int hr, int ht, int hb);
+
+/* Rules. */
+void table_hline (struct table *, int style, int x1, int x2, int y);
+void table_vline (struct table *, int style, int x, int y1, int y2);
+void table_box (struct table *, int f_h, int f_v, int i_h, int i_v,
+                int x1, int y1, int x2, int y2);
+
+/* Cells. */
+void table_put (struct table *, int x1, int y1, int x2, int y2,
+                unsigned opt, const struct pivot_value *);
+void table_put_owned (struct table *, int x1, int y1, int x2, int y2,
+                      unsigned opt, struct pivot_value *);
+
+bool table_cell_is_empty (const struct table *, int c, int r);
 
 #endif /* output/table.h */
 
 #endif /* output/table.h */