1 // Copyright (C) 2000-2007, Luca Padovani <padovani@sti.uniurb.it>.
2 //
3 // This file is part of GtkMathView, a flexible, high-quality rendering
4 // engine for MathML documents.
5 //
6 // GtkMathView is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GtkMathView is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef __MathMLTableFormatter_hh__
20 #define __MathMLTableFormatter_hh__
21 
22 #include <vector>
23 
24 #include "token.hh"
25 #include "Object.hh"
26 #include "SmartPtr.hh"
27 #include "BoxedLayoutArea.hh"
28 #include "MathMLTableCellElement.hh"
29 
30 class MathMLTableFormatter : public Object
31 {
32 protected:
33   MathMLTableFormatter(void);
34   virtual ~MathMLTableFormatter();
35 
36 public:
create(void)37   static SmartPtr<MathMLTableFormatter> create(void)
38   { return new MathMLTableFormatter(); }
39 
40   void init(const class FormattingContext&,
41 	    unsigned, unsigned,
42 	    const std::vector<SmartPtr<MathMLTableCellElement> >&,
43 	    const std::vector<SmartPtr<MathMLTableCellElement> >&,
44 	    const SmartPtr<Value>&,
45 	    const SmartPtr<Value>&,
46 	    const SmartPtr<Value>&,
47 	    const SmartPtr<Value>&,
48 	    const SmartPtr<Value>&,
49 	    const SmartPtr<Value>&,
50 	    const SmartPtr<Value>&,
51 	    const SmartPtr<Value>&,
52 	    const SmartPtr<Value>&,
53 	    const SmartPtr<Value>&);
54   AreaRef formatLines(const class FormattingContext&,
55 		      const SmartPtr<Value>&,
56 		      const SmartPtr<Value>&,
57 		      const SmartPtr<Value>&) const;
58   void formatCells(const class FormattingContext&,
59 		   const scaled&,
60 		   const SmartPtr<Value>&) const;
61   BoundingBox format(std::vector<BoxedLayoutArea::XYArea>&);
62 
63 private:
64   class Cell
65   {
66   public:
Cell(void)67     Cell(void) { }
68 
getArea(void) const69     AreaRef getArea(void) const { return content->getArea(); }
getBoundingBox(void) const70     BoundingBox getBoundingBox(void) const { return getArea()->box(); }
getContent(void) const71     SmartPtr<MathMLTableCellElement> getContent(void) const { return content; }
isNull(void) const72     bool isNull(void) const { return content == 0; }
operator bool(void) const73     operator bool(void) const { return !isNull(); }
getColumnSpan(void) const74     unsigned getColumnSpan(void) const { return content ? content->getColumnSpan() * 2 - 1 : 0; }
getRowSpan(void) const75     unsigned getRowSpan(void) const { return content ? content->getRowSpan() * 2 - 1 : 0; }
getRowAlign(void) const76     TokenId getRowAlign(void) const { return content->getRowAlign(); }
getColumnAlign(void) const77     TokenId getColumnAlign(void) const { return content->getColumnAlign(); }
getDisplacement(scaled & x,scaled & y) const78     void getDisplacement(scaled& x, scaled& y) const { content->getDisplacement(x, y); }
setContent(const SmartPtr<MathMLTableCellElement> & c)79     void setContent(const SmartPtr<MathMLTableCellElement>& c) { content = c; }
setDisplacement(const scaled & x,const scaled & y) const80     void setDisplacement(const scaled& x, const scaled& y) const { content->setDisplacement(x, y); }
81 
82   private:
83     SmartPtr<MathMLTableCellElement> content;
84   };
85 
86   class Row
87   {
88   public:
89     enum RowHeightSpec { AUTO, FIX, SCALE };
90 
Row(void)91     Row(void)
92       : contentRow(false), spec(AUTO), fixHeight(), scaleHeight(0.0f),
93 	tempHeight(), tempDepth(), height(), depth(), displacement()
94     { }
95 
getSpec(void) const96     RowHeightSpec getSpec(void) const { return spec; }
isContentRow(void) const97     bool isContentRow(void) const { return contentRow; }
getScaleHeight(void) const98     float getScaleHeight(void) const { return scaleHeight; }
getDepth(void) const99     scaled getDepth(void) const { return depth; }
getFixHeight(void) const100     scaled getFixHeight(void) const { return fixHeight; }
getHeight(void) const101     scaled getHeight(void) const { return height; }
getTempDepth(void) const102     scaled getTempDepth(void) const { return tempDepth; }
getTempHeight(void) const103     scaled getTempHeight(void) const { return tempHeight; }
getVerticalExtent(void) const104     scaled getVerticalExtent(void) const { return getHeight() + getDepth(); }
setContentRow(bool b=true)105     void setContentRow(bool b = true) { contentRow = b; }
setDepth(const scaled & d)106     void setDepth(const scaled& d) { depth = d; }
setHeight(const scaled & h)107     void setHeight(const scaled& h) { height = h; }
setHeightSpec(RowHeightSpec s)108     void setHeightSpec(RowHeightSpec s) { spec = s; }
setHeightSpec(const scaled & w)109     void setHeightSpec(const scaled& w) { spec = FIX; fixHeight = w; }
setHeightSpec(float s)110     void setHeightSpec(float s) { spec = SCALE; scaleHeight = s; }
111     void setHeightSpec(const class FormattingContext&, const class Length&);
setTempDepth(const scaled & d)112     void setTempDepth(const scaled& d) { tempDepth = d; }
setTempHeight(const scaled & h)113     void setTempHeight(const scaled& h) { tempHeight = h; }
setDisplacement(const scaled & d)114     void setDisplacement(const scaled& d) { displacement = d; }
getDisplacement(void) const115     scaled getDisplacement(void) const { return displacement; }
getTopDisplacement(void) const116     scaled getTopDisplacement(void) const { return getDisplacement() + height; }
getBottomDisplacement(void) const117     scaled getBottomDisplacement(void) const { return getDisplacement() - depth; }
getCenterDisplacement(void) const118     scaled getCenterDisplacement(void) const { return getDisplacement() + (height - depth) / 2; }
119 
120   private:
121     bool contentRow;
122     RowHeightSpec spec;
123     scaled fixHeight;
124     float scaleHeight;
125     scaled tempHeight;
126     scaled tempDepth;
127     scaled height;
128     scaled depth;
129     scaled displacement;
130   };
131 
132   class Column
133   {
134   public:
135     enum ColumnWidthSpec { AUTO, FIT, FIX, SCALE };
136 
Column(void)137     Column(void)
138       : contentColumn(false), spec(AUTO), fixWidth(), scaleWidth(0.0f),
139 	tempWidth(), width(), contentWidth(), displacement()
140     { }
141 
getSpec(void) const142     ColumnWidthSpec getSpec(void) const { return spec; }
isContentColumn(void) const143     bool isContentColumn(void) const { return contentColumn; }
getScaleWidth(void) const144     float getScaleWidth(void) const { return scaleWidth; }
getContentWidth(void) const145     scaled getContentWidth(void) const { return contentWidth; }
getFixWidth(void) const146     scaled getFixWidth(void) const { return fixWidth; }
getTempWidth(void) const147     scaled getTempWidth(void) const { return tempWidth; }
getWidth(void) const148     scaled getWidth(void) const { return width; }
setContentColumn(bool b=true)149     void setContentColumn(bool b = true) { contentColumn = b; }
setContentWidth(const scaled & w)150     void setContentWidth(const scaled& w) { contentWidth = w; }
setTempWidth(const scaled & w)151     void setTempWidth(const scaled& w) { tempWidth = w; }
setWidth(const scaled & w)152     void setWidth(const scaled& w) { width = w; }
setWidthSpec(ColumnWidthSpec s)153     void setWidthSpec(ColumnWidthSpec s) { spec = s; }
setWidthSpec(const scaled & w)154     void setWidthSpec(const scaled& w) { spec = FIX; fixWidth = w; }
setWidthSpec(float s)155     void setWidthSpec(float s) { spec = SCALE; scaleWidth = s; }
156     void setWidthSpec(const class FormattingContext&, const class Length&);
setDisplacement(const scaled & d)157     void setDisplacement(const scaled& d) { displacement = d; }
getDisplacement(void) const158     scaled getDisplacement(void) const { return displacement; }
getLeftDisplacement(void) const159     scaled getLeftDisplacement(void) const { return getDisplacement(); }
getRightDisplacement(void) const160     scaled getRightDisplacement(void) const { return getDisplacement() + getWidth(); }
getCenterDisplacement(void) const161     scaled getCenterDisplacement(void) const { return getDisplacement() + getWidth() / 2; }
162 
163   private:
164     bool contentColumn;
165     ColumnWidthSpec spec;
166     scaled fixWidth;
167     float scaleWidth;
168     scaled tempWidth;
169     scaled width;
170     scaled contentWidth;
171     scaled displacement;
172   };
173 
174 protected:
175   const Cell& getCell(unsigned, unsigned) const;
getBoundingBox(void) const176   BoundingBox getBoundingBox(void) const { return BoundingBox(getWidth(), getHeight(), getDepth()); }
177   BoundingBox getCellBoundingBox(unsigned, unsigned, unsigned, unsigned) const;
178   scaled computeTableHeightDepthF(void);
179   scaled computeTableHeightDepthT(void);
180   scaled computeMinimumTableWidthF(void);
181   scaled computeMinimumTableWidthT(void);
182   scaled computeMinimumTableWidth(void);
183   scaled computeTableWidth(const scaled&);
184   BoundingBox assignTableWidth(const scaled&);
185   void assignTableWidthT(const scaled&);
186   void assignTableWidthF(const scaled&);
187   scaled getColumnContentWidth(unsigned) const;
getWidth(void) const188   scaled getWidth(void) const { return width; }
getHeight(void) const189   scaled getHeight(void) const { return height; }
getDepth(void) const190   scaled getDepth(void) const { return depth; }
191   void alignTable(const scaled&, const scaled&, TokenId);
192   void alignTable(const scaled&, const scaled&, TokenId, unsigned);
193   void initTempHeightDepth();
194   void initTempWidths(void);
195   void setDisplacements(void);
196   void setCellPosition(void);
setWidth(const scaled & w)197   void setWidth(const scaled& w) { width = w; }
setHeight(const scaled & h)198   void setHeight(const scaled& h) { height = h; }
setDepth(const scaled & d)199   void setDepth(const scaled& d) { depth = d; }
200 
201   scaled axis;
202 
203   unsigned nRows;
204   unsigned nColumns;
205   int numCol; // nContentColumns
206   scaled sumFix;
207   scaled sumCont;
208   float sumScale;
209   bool equalRows;
210   bool equalColumns;
211   TokenId tableAlign;
212   int tableAlignRow;
213 
214   scaled width;
215   scaled height;
216   scaled depth;
217   std::vector<Row> rows;
218   std::vector<Column> columns;
219   std::vector<Cell> cells;
220 };
221 
222 #endif // __MathMLTableFormatter_hh__
223