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.
This commit is contained in:
Enrico Forestieri 2021-02-21 00:32:41 +01:00
parent 61657bd610
commit 4e0d7f753b
6 changed files with 75 additions and 60 deletions

View File

@ -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 {}

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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,14 +56,8 @@ 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;
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;
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);
}

View File

@ -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];