This patch implements \phantom, \hphantom and \vphantom in math. They can 
be used already, but will be drawn in red.
The implementation follows the idea given by Jean-Marc in 
http://bugzilla.lyx.org/show_bug.cgi?id=1473: draw the contents in 
LColor::color::special, and draw one or two arrows over that in color 
LColor::color::space.
I use this since some months now, and it works fine.

Opinions?
If I get no objections this will go in trunk. Log:

Implement \phantom, \hphantom and \vphantom in math (bug 1473):
        * src/mathed/math_factory.C
        (createMathInset): handle \phantom, \hphantom and \vphantom
        * src/mathed/Makefile.am: add math_phantominset.[Ch]
        * src/mathed/math_phantominset.[Ch]: new phantom inset


Georg
Index: src/mathed/math_factory.C
===================================================================
--- src/mathed/math_factory.C	(Revision 13676)
+++ src/mathed/math_factory.C	(Arbeitskopie)
@@ -37,6 +37,7 @@
 #include "math_makeboxinset.h"
 #include "math_oversetinset.h"
 #include "math_parser.h"
+#include "math_phantominset.h"
 #include "math_rootinset.h"
 #include "math_sizeinset.h"
 #include "math_spaceinset.h"
@@ -335,6 +336,12 @@ MathAtom createMathInset(string const & 
 		return MathAtom(new MathDfracInset);
 	if (s == "tfrac")
 		return MathAtom(new MathTfracInset);
+	if (s == "hphantom")
+		return MathAtom(new MathPhantomInset(MathPhantomInset::hphantom));
+	if (s == "phantom")
+		return MathAtom(new MathPhantomInset(MathPhantomInset::phantom));
+	if (s == "vphantom")
+		return MathAtom(new MathPhantomInset(MathPhantomInset::vphantom));
 
 	if (MacroTable::globalMacros().has(s))
 		return MathAtom(new MathMacro(s,
Index: src/mathed/Makefile.am
===================================================================
--- src/mathed/Makefile.am	(Revision 13676)
+++ src/mathed/Makefile.am	(Arbeitskopie)
@@ -112,6 +112,8 @@ libmathed_la_SOURCES = \
 	math_parinset.h \
 	math_parser.C \
 	math_parser.h \
+	math_phantominset.C \
+	math_phantominset.h \
 	math_replace.h \
 	math_rootinset.C \
 	math_rootinset.h \
Index: src/mathed/math_phantominset.C
===================================================================
--- src/mathed/math_phantominset.C	(Revision 0)
+++ src/mathed/math_phantominset.C	(Revision 0)
@@ -0,0 +1,168 @@
+/**
+ * \file math_phantominset.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Georg Baum
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "math_phantominset.h"
+#include "math_mathmlstream.h"
+#include "math_streamstr.h"
+
+#include "LColor.h"
+
+#include "frontends/Painter.h"
+
+#include "support/std_ostream.h"
+
+
+MathPhantomInset::MathPhantomInset(Kind k)
+	: MathNestInset(1), kind_(k)
+{}
+
+
+std::auto_ptr<InsetBase> MathPhantomInset::doClone() const
+{
+	return std::auto_ptr<InsetBase>(new MathPhantomInset(*this));
+}
+
+
+void MathPhantomInset::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+	cell(0).metrics(mi, dim);
+	metricsMarkers(dim);
+	dim_ = dim;
+}
+
+
+void MathPhantomInset::draw(PainterInfo & pi, int x, int y) const
+{
+	static int const arrow_size = 4;
+
+	// We first draw the text and then an arrow
+	LColor_color const origcol = pi.base.font.color();
+	pi.base.font.setColor(LColor::special);
+	cell(0).draw(pi, x + 1, y);
+	pi.base.font.setColor(origcol);
+
+	if (kind_ == phantom || kind_ == vphantom) {
+		// y1---------
+		//           / \.
+		// y2-----  / | \.
+		//            |
+		//            |
+		// y3-----  \ | /
+		//           \ /
+		// y4---------
+		//          | | |
+		//         /  |  \.
+		//        x1  x2 x3
+
+		int const x2 = x + dim_.wid / 2;
+		int const x1 = x2 - arrow_size;
+		int const x3 = x2 + arrow_size;
+
+		int const y1 = y - dim_.asc;
+		int const y2 = y1 + arrow_size;
+		int const y4 = y + dim_.des;
+		int const y3 = y4 - arrow_size;
+
+		// top arrow
+		pi.pain.line(x2, y1, x1, y2, LColor::added_space);
+		pi.pain.line(x2, y1, x3, y2, LColor::added_space);
+
+		// bottom arrow
+		pi.pain.line(x2, y4, x1, y3, LColor::added_space);
+		pi.pain.line(x2, y4, x3, y3, LColor::added_space);
+
+		// joining line
+		pi.pain.line(x2, y1, x2, y4, LColor::added_space);
+	}
+
+	if (kind_ == phantom || kind_ == hphantom) {
+		// y1----   /          \.
+		//        /              \.
+		// y2--- <---------------->
+		//        \              /
+		// y3----   \          /
+		//       |   |        |   |
+		//      x1  x2       x3  x4
+
+		int const x1 = x;
+		int const x2 = x + arrow_size;
+		int const x4 = x + dim_.wid;
+		int const x3 = x4 - arrow_size;
+
+		int const y2 = y + (dim_.des - dim_.asc) / 2;
+		int const y1 = y2 - arrow_size;
+		int const y3 = y2 + arrow_size;
+
+		// left arrow
+		pi.pain.line(x1, y2, x2, y3, LColor::added_space);
+		pi.pain.line(x1, y2, x2, y1, LColor::added_space);
+
+		// right arrow
+		pi.pain.line(x4, y2, x3, y3, LColor::added_space);
+		pi.pain.line(x4, y2, x3, y1, LColor::added_space);
+
+		// joining line
+		pi.pain.line(x1, y2, x4, y2, LColor::added_space);
+	}
+
+	drawMarkers(pi, x, y);
+}
+
+
+void MathPhantomInset::write(WriteStream & os) const
+{
+	switch (kind_) {
+	case phantom:
+		os << "\\phantom{";
+		break;
+	case vphantom:
+		os << "\\vphantom{";
+		break;
+	case hphantom:
+		os << "\\hphantom{";
+		break;
+	}
+	os << cell(0) << '}';
+}
+
+
+void MathPhantomInset::normalize(NormalStream & os) const
+{
+	switch (kind_) {
+	case phantom:
+		os << "[phantom ";
+		break;
+	case vphantom:
+		os << "[vphantom ";
+		break;
+	case hphantom:
+		os << "[hphantom ";
+		break;
+	}
+	os << cell(0) << ']';
+}
+
+
+void MathPhantomInset::infoize(std::ostream & os) const
+{
+	switch (kind_) {
+	case phantom:
+		os << "Phantom";
+		break;
+	case vphantom:
+		os << "Vphantom";
+		break;
+	case hphantom:
+		os << "Hphantom";
+		break;
+	}
+}
Index: src/mathed/math_phantominset.h
===================================================================
--- src/mathed/math_phantominset.h	(Revision 0)
+++ src/mathed/math_phantominset.h	(Revision 0)
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+/**
+ * \file math_phantominset.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Georg Baum
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef MATH_PHANTOMINSET_H
+#define MATH_PHANTOMINSET_H
+
+#include "math_nestinset.h"
+
+class MathPhantomInset : public MathNestInset {
+public:
+	///
+	enum Kind {
+		phantom,
+		vphantom,
+		hphantom
+	};
+	///
+	explicit MathPhantomInset(Kind);
+	///
+	void metrics(MetricsInfo & mi, Dimension & dim) const;
+	///
+	void draw(PainterInfo & pi, int x, int y) const;
+	///
+	void write(WriteStream & os) const;
+	/// write normalized content
+	void normalize(NormalStream & ns) const;
+	///
+	void infoize(std::ostream & os) const;
+private:
+	///
+	virtual std::auto_ptr<InsetBase> doClone() const;
+	///
+	Kind kind_;
+};
+
+#endif

Reply via email to