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 #include <config.h>
20 
21 #include "BoxMLAttributeSignatures.hh"
22 #include "BoxMLHVElement.hh"
23 #include "BoxMLHElement.hh"
24 #include "BoxMLVElement.hh"
25 #include "FormattingContext.hh"
26 #include "BoxGraphicDevice.hh"
27 #include "ValueConversion.hh"
28 #include "AreaFactory.hh"
29 
BoxMLHVElement(const SmartPtr<BoxMLNamespaceContext> & context)30 BoxMLHVElement::BoxMLHVElement(const SmartPtr<BoxMLNamespaceContext>& context)
31   : BoxMLLinearContainerElement(context)
32 { }
33 
~BoxMLHVElement()34 BoxMLHVElement::~BoxMLHVElement()
35 { }
36 
37 SmartPtr<BoxMLHVElement>
create(const SmartPtr<BoxMLNamespaceContext> & context)38 BoxMLHVElement::create(const SmartPtr<BoxMLNamespaceContext>& context)
39 { return new BoxMLHVElement(context); }
40 
41 AreaRef
getMaxArea() const42 BoxMLHVElement::getMaxArea() const
43 { return maxArea; }
44 
45 AreaRef
format(FormattingContext & ctxt)46 BoxMLHVElement::format(FormattingContext& ctxt)
47 {
48   if (dirtyLayout())
49     {
50       ctxt.push(this);
51 
52       const scaled spacing = ctxt.BGD()->evaluate(ctxt, ToLength(GET_ATTRIBUTE_VALUE(BoxML, HV, spacing)), 0);
53       const scaled indent = ctxt.BGD()->evaluate(ctxt, ToLength(GET_ATTRIBUTE_VALUE(BoxML, HV, indent)), 0);
54       const scaled minLineSpacing = ctxt.BGD()->evaluate(ctxt, ToLength(GET_ATTRIBUTE_VALUE(BoxML, V, minlinespacing)), 0);
55 
56       const scaled availableWidth = ctxt.getAvailableWidth();
57       std::vector<AreaRef> c;
58       c.reserve(content.getSize());
59       std::vector<AreaRef> cMax;
60       cMax.reserve(content.getSize());
61       std::vector<scaled> sc;
62       sc.reserve(content.getSize());
63 
64       for (std::vector< SmartPtr<BoxMLElement> >::const_iterator p = content.begin();
65 	   p != content.end();
66 	   p++)
67 	if (*p)
68 	  {
69 	    const scaled thisIndent = (p == content.begin()) ? 0 : indent;
70 	    ctxt.setAvailableWidth(availableWidth - thisIndent);
71 	    c.push_back((*p)->format(ctxt));
72 	    cMax.push_back((*p)->getMaxArea());
73 
74 	    if (p + 1 != content.end())
75 	      sc.push_back(spacing);
76 	  }
77 
78       AreaRef res;
79       res = BoxMLHElement::formatHorizontalArray(ctxt, cMax, spacing);
80       res = ctxt.BGD()->wrapper(ctxt, res);
81       setMaxArea(res);
82 
83       if (res->box().width > availableWidth)
84 	{
85 	  res = BoxMLVElement::formatVerticalArray(ctxt, c, minLineSpacing, 1, -1, indent);
86 	  res = ctxt.BGD()->wrapper(ctxt, res);
87 	}
88 
89       setArea(res);
90 
91       ctxt.pop();
92       resetDirtyLayout();
93     }
94 
95   return getArea();
96 }
97