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