--- /dev/null
+#ifndef COLS_HH
+#define COLS_HH
+
+#include "glob.hh"
+#include "boxes.hh"
+#include "plist.hh"
+#include "item.hh"
+
+/// stuff grouped vertically.
+struct PCol {
+ List<const Item*> its;
+ List<const Spanner*> stoppers, starters;
+
+ /// Can this be broken? true eg. for bars.
+ bool breakable()const;
+
+ /// does this column have items, does it have spacings attached?
+ bool used;
+
+ /// prebreak is put before end of line.
+ PCol *prebreak;
+ /**
+ if broken here, then (*this) column is discarded, and prebreak
+ is put at end of line, owned by Col
+ */
+
+ /// postbreak at beginning of the new line
+ PCol *postbreak;
+ /** \See{prebreak}
+ */
+ PCol *daddy;
+ /*
+ if this column is pre or postbreak, then this field points to the parent.
+ */
+ /// if lines are broken then this column is in #line#
+ const Line_of_score *line;
+
+ /// if lines are broken then this column x-coord #hpos#
+ Real hpos;
+
+
+ /****************************************************************/
+
+ void add(Item*i);
+
+ Interval width() const;
+ ~PCol();
+ PCol(PCol * parent);
+
+ /// which col comes first?
+ static int compare(const PCol &c1, const PCol &c2);
+ /**
+ signed compare on columns.
+
+ return < 0 if c1 < c2.
+ */
+
+ void OK() const;
+ void set_breakable();
+ void print()const;
+};
+/**
+ This is a class to address items vertically. It contains the data for:
+ \begin{itemize}
+ \item
+ unbroken score
+ \item
+ broken score
+ \item
+ the linespacing problem
+ \end{itemize}
+ */
+
+#include "compare.hh"
+instantiate_compare(const PCol &, PCol::compare);
+
+
+/// ideal spacing between two columns
+struct Idealspacing {
+
+ /// the ideal distance
+ Real space;
+
+ /// Hooke's constant: how strong are the "springs" attached to columns
+ Real hooke;
+
+ /// the two columns
+ const PCol *left, *right;
+
+ void print()const;
+ void OK() const ;
+ Idealspacing(const PCol *left,const PCol *right);
+};
+
+#endif
--- /dev/null
+#include "pcol.hh"
+#include "pstaff.hh"
+#include "debug.hh"
+
+void
+Idealspacing::print() const
+{
+#ifndef NPRINT
+ mtor << "idealspacing {" ;
+ mtor << "distance "<<space<< " strength " << hooke << "}\n";
+#endif
+}
+
+Idealspacing::Idealspacing(const PCol * l,const PCol * r)
+{
+ space = 0.0;
+ hooke = 0.0;
+ left = l;
+ right = r;
+}
+
+void
+Idealspacing::OK() const
+{
+#ifndef NDEBUG
+ assert(hooke >= 0 && left && right);
+#endif
+}
+
+/****************************************************************/
+
+Interval
+PCol::width() const
+{
+ Interval w;
+
+ for (PCursor<const Item *> ic(its); ic.ok(); ic++)
+ w.unite(ic->width());
+ if (w.empty())
+ w.unite(Interval(0,0));
+ return w;
+}
+
+void
+PCol::print() const
+{
+ #ifndef NPRINT
+ mtor << "PCol {";
+ mtor << "# symbols: " << its.size() ;
+ if (breakable()){
+ mtor << "pre,post: ";
+ prebreak->print();
+ postbreak->print();
+ }
+ mtor << "extent: " << width().min << ", " << width().max << "\n";
+ mtor << "}\n";
+ #endif
+}
+
+int
+PCol::compare(const PCol &, const PCol &)
+{
+ assert(false);
+ return 0 ;
+}
+
+void
+PCol::OK () const
+{
+ if (prebreak || postbreak ) {
+ assert(prebreak&&postbreak);
+ assert(prebreak->daddy == this);
+ assert(postbreak->daddy == this);
+ }
+
+}
+
+void
+PCol::set_breakable()
+{
+ if (breakable())
+ return;
+
+ prebreak = new PCol(this);
+ postbreak = new PCol(this);
+ used = true;
+}
+
+bool
+PCol::breakable() const
+{
+ return prebreak||postbreak;
+}
+
+PCol::PCol(PCol *parent) {
+ daddy = parent;
+ prebreak=0;
+ postbreak=0;
+ line=0;
+ used = false;
+}
+
+PCol::~PCol()
+{
+
+ delete prebreak;
+
+ delete postbreak;
+}
+
+void
+PCol::add( Item *i)
+{
+ its.bottom().add(i);
+ i->pcol_ = this;
+ used = true;
+}
+