[LyX/master] Draw real dots

Enrico Forestieri forenr at lyx.org
Sat Feb 20 23:35:13 UTC 2021


commit 4e0d7f753b35c6fdc7bc6233484b4a11a96bd317
Author: Enrico Forestieri <forenr at lyx.org>
Date:   Sun Feb 21 00:32:41 2021 +0100

    Draw real dots
    
    A new method for drawing ellipses has been added to the painter
    and used for drawing real dots for math decorations and the various
    \cdots, \ddots, \vdots, etc., latex commands.
---
 src/frontends/NullPainter.h     |    5 ++
 src/frontends/Painter.h         |    5 ++
 src/frontends/qt/GuiPainter.cpp |   19 +++++++++
 src/frontends/qt/GuiPainter.h   |    9 ++++
 src/mathed/InsetMathDots.cpp    |   19 ++-------
 src/mathed/MathSupport.cpp      |   78 ++++++++++++++++-----------------------
 6 files changed, 75 insertions(+), 60 deletions(-)

diff --git a/src/frontends/NullPainter.h b/src/frontends/NullPainter.h
index 8f7efff..c8e2145 100644
--- a/src/frontends/NullPainter.h
+++ b/src/frontends/NullPainter.h
@@ -53,6 +53,11 @@ public:
 	/// draw an arc
 	void arc(int, int, unsigned int, unsigned int, int, int, Color) override {}
 
+	/// draw an ellipse
+	void ellipse(double, double, double, double, Color,
+		fill_style = fill_none, line_style = line_solid,
+		int = thin_line) override {}
+
 	/// draw a pixel
 	void point(int, int, Color) override {}
 
diff --git a/src/frontends/Painter.h b/src/frontends/Painter.h
index 51d4b7d..94ee460 100644
--- a/src/frontends/Painter.h
+++ b/src/frontends/Painter.h
@@ -122,6 +122,11 @@ public:
 	virtual void arc(int x, int y, unsigned int w, unsigned int h,
 		int a1, int a2, Color) = 0;
 
+	/// draw an ellipse
+	virtual void ellipse(double x, double y, double rx, double ry, Color,
+		fill_style = fill_none, line_style = line_solid,
+		int line_width = thin_line) = 0;
+
 	/// draw a pixel
 	virtual void point(int x, int y, Color) = 0;
 
diff --git a/src/frontends/qt/GuiPainter.cpp b/src/frontends/qt/GuiPainter.cpp
index 1de3d14..30d7fe3 100644
--- a/src/frontends/qt/GuiPainter.cpp
+++ b/src/frontends/qt/GuiPainter.cpp
@@ -233,6 +233,25 @@ void GuiPainter::arc(int x, int y, unsigned int w, unsigned int h,
 }
 
 
+void GuiPainter::ellipse(double x, double y, double rx, double ry,
+	Color col, fill_style fs, line_style ls, int lw)
+{
+	QColor const color = computeColor(col);
+	setQPainterPen(color, ls, lw);
+	bool const do_antialiasing = renderHints() & TextAntialiasing;
+	setRenderHint(Antialiasing, do_antialiasing);
+	if (fs == fill_none) {
+		drawEllipse(QPointF(x, y), rx, ry);
+	} else {
+		QBrush const oldbrush = brush();
+		setBrush(QBrush(color));
+		drawEllipse(QPointF(x, y), rx, ry);
+		setBrush(oldbrush);
+	}
+	setRenderHint(Antialiasing, false);
+}
+
+
 void GuiPainter::image(int x, int y, int w, int h, graphics::Image const & i,
 		       bool const revert_in_darkmode)
 {
diff --git a/src/frontends/qt/GuiPainter.h b/src/frontends/qt/GuiPainter.h
index bdf3e46..b5f61c1 100644
--- a/src/frontends/qt/GuiPainter.h
+++ b/src/frontends/qt/GuiPainter.h
@@ -99,6 +99,15 @@ public:
 		int a1, int a2,
 		Color) override;
 
+	/// draw an ellipse
+	void ellipse(
+		double x, double y,
+		double rx, double ry,
+		Color,
+		fill_style fs = fill_none,
+		line_style ls = line_solid,
+		int lw = thin_line) override;
+
 	/// draw a pixel
 	void point(int x, int y, Color) override;
 
diff --git a/src/mathed/InsetMathDots.cpp b/src/mathed/InsetMathDots.cpp
index 44490cb..a89da08 100644
--- a/src/mathed/InsetMathDots.cpp
+++ b/src/mathed/InsetMathDots.cpp
@@ -38,18 +38,15 @@ Inset * InsetMathDots::clone() const
 
 void InsetMathDots::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-	dim = theFontMetrics(mi.base.font).dimension('M');
+	dim = theFontMetrics(mi.base.font).dimension('X');
 	dh_ = 0;
 	if (key_->name == "cdots" || key_->name == "dotsb"
 			|| key_->name == "dotsm" || key_->name == "dotsi")
 		dh_ = dim.asc / 2;
 	else if (key_->name == "dotsc")
 		dh_ = dim.asc / 4;
-	else if (key_->name == "vdots") {
-		dim.wid = (dim.wid / 2) + 1;
-		dh_ = dim.asc;
-	}
-	else if (key_->name == "ddots" || key_->name == "adots" || key_->name == "iddots")
+	else if (key_->name == "ddots" || key_->name == "adots"
+			|| key_->name == "iddots" || key_->name == "vdots")
 		dh_ = dim.asc;
 }
 
@@ -59,16 +56,10 @@ void InsetMathDots::draw(PainterInfo & pi, int x, int y) const
 	Dimension const dim = dimension(*pi.base.bv);
 	if (key_->name == "adots" || key_->name == "iddots")
 		--y;
+	else if (key_->name == "vdots")
+		x += (dim.width() - 2) / 2;
 	mathed_draw_deco(pi, x + 2, y - dh_, dim.width() - 2, dim.ascent(),
 			key_->name);
-	if (key_->name == "vdots" || key_->name == "ddots" || key_->name == "adots" || key_->name == "iddots")
-		++x;
-	if (key_->name == "adots" || key_->name == "iddots")
-		++y;
-	else if (key_->name != "vdots")
-		--y;
-	mathed_draw_deco(pi, x + 2, y - dh_, dim.width() - 2, dim.ascent(),
-		key_->name);
 }
 
 
diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp
index 39a58b2..8f30bca 100644
--- a/src/mathed/MathSupport.cpp
+++ b/src/mathed/MathSupport.cpp
@@ -83,8 +83,8 @@ namespace {
 
 /*
  * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
- * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
- * 5 = rounded thick line (i.e. dot for short line),
+ * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline,
+ * 5 = ellipse with given center and horizontal and vertical radii,
  * 6 = shifted square polyline drawn at the other end
  */
 
@@ -333,50 +333,47 @@ double const hline[] = {
 
 
 double const dot[] = {
-//	1, 0.5, 0.2, 0.5, 0.2,
-//	1, 0.4, 0.4, 0.6, 0.4,
-//	1, 0.5, 0.5, 0.5, 0.5,
-	5, 0.4, 0.5, 0.6, 0.5,
+	5, 0.5, 0.5, 0.1, 0.1,
 	0
 };
 
 
 double const ddot[] = {
-	5, 0.1, 0.5, 0.3, 0.5,
-	5, 0.6, 0.5, 0.8, 0.5,
+	5, 0.2, 0.5, 0.1, 0.1,
+	5, 0.7, 0.5, 0.1, 0.1,
 	0
 };
 
 
 double const dddot[] = {
-	5, 0.0, 0.5, 0.2, 0.5,
-	5, 0.4, 0.5, 0.6, 0.5,
-	5, 0.8, 0.5, 1.0, 0.5,
+	5, 0.1, 0.5, 0.1, 0.1,
+	5, 0.5, 0.5, 0.1, 0.1,
+	5, 0.9, 0.5, 0.1, 0.1,
 	0
 };
 
 
 double const ddddot[] = {
-	5, -0.2, 0.5, 0.0, 0.5,
-	5,  0.2, 0.5, 0.4, 0.5,
-	5,  0.6, 0.5, 0.8, 0.5,
-	5,  1.0, 0.5, 1.2, 0.5,
+	5, -0.1, 0.5, 0.1, 0.1,
+	5,  0.3, 0.5, 0.1, 0.1,
+	5,  0.7, 0.5, 0.1, 0.1,
+	5,  1.1, 0.5, 0.1, 0.1,
 	0
 };
 
 
 double const hline3[] = {
-	1, 0.1,   0,  0.15,  0,
-	1, 0.475, 0,  0.525, 0,
-	1, 0.85,  0,  0.9,   0,
+	5, 0.15, 0.05, 0.0625, 0.0625,
+	5, 0.50, 0.05, 0.0625, 0.0625,
+	5, 0.85, 0.05, 0.0625, 0.0625,
 	0
 };
 
 
 double const dline3[] = {
-	1, 0.1,   0.1,   0.15,  0.15,
-	1, 0.475, 0.475, 0.525, 0.525,
-	1, 0.85,  0.85,  0.9,   0.9,
+	5, 0.25, 0.225, 0.0625, 0.0625,
+	5, 0.50, 0.475, 0.0625, 0.0625,
+	5, 0.75, 0.725, 0.0625, 0.0625,
 	0
 };
 
@@ -678,7 +675,7 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
 
 	for (int i = 0; d[i]; ) {
 		int code = int(d[i++]);
-		if (code & 1) {  // code == 1 || code == 3 || code == 5
+		if (code == 1 || code == 3) {
 			double xx = d[i++];
 			double yy = d[i++];
 			double x2 = d[i++];
@@ -692,30 +689,19 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
 				int(x + xx + 0.5), int(y + yy + 0.5),
 				int(x + x2 + 0.5), int(y + y2 + 0.5),
 				pi.base.font.color(), Painter::line_solid, lw);
-			if (code == 5) {  // thicker, but rounded
-				double const xa = x + xx + 0.5;
-				double const xb = x + x2 + 0.5;
-				double const ya = y + yy + 0.5;
-				double const yb = y + y2 + 0.5;
-				pi.pain.line(int(xa + 1), int(ya - 1),
-				             int(xb - 1), int(yb - 1),
-				             pi.base.font.color(),
-				             Painter::line_solid, lw);
-				pi.pain.line(int(xa + 1), int(ya + 1),
-				             int(xb - 1), int(yb + 1),
-				             pi.base.font.color(),
-				             Painter::line_solid, lw);
-				for (int k = 2; xa + k <= xb - k; k++) {
-					pi.pain.line(int(xa + k), int(ya - k),
-						     int(xb - k), int(yb - k),
-						     pi.base.font.color(),
-						     Painter::line_solid, lw);
-					pi.pain.line(int(xa + k), int(ya + k),
-						     int(xb - k), int(yb + k),
-						     pi.base.font.color(),
-						     Painter::line_solid, lw);
-				}
-			}
+		} else if (code == 5) {
+			double xx = d[i++];
+			double yy = d[i++];
+			double x2 = xx + d[i++];
+			double y2 = yy + d[i++];
+			mt.transform(xx, yy);
+			mt.transform(x2, y2);
+			double const xc = x + xx;
+			double const yc = y + yy;
+			double const rx = x2 - xx;
+			double const ry = y2 - yy;
+			pi.pain.ellipse(xc, yc, rx, ry,
+				pi.base.font.color(), Painter::fill_winding);
 		} else {
 			int xp[32];
 			int yp[32];


More information about the lyx-cvs mailing list