Allow selecting unit (px/mm) in Canvas::Stroke.
By directly specifying the desired end result to the renderer, we can avoid regeneration of geometry.
This commit is contained in:
parent
a5c7fc6ad9
commit
9f97e9aad4
@ -79,11 +79,9 @@ void Constraint::DoLabel(Canvas *canvas, Canvas::hStroke hcs,
|
||||
}
|
||||
|
||||
void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *r) {
|
||||
const Camera &camera = canvas->GetCamera();
|
||||
|
||||
Canvas::Stroke strokeStippled = *canvas->strokes.FindById(hcs);
|
||||
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
|
||||
strokeStippled.stippleScale = 4.0 / camera.scale;
|
||||
strokeStippled.stippleScale = 4.0;
|
||||
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
|
||||
|
||||
Vector p = r->ProjectInto(workplane);
|
||||
@ -542,7 +540,7 @@ void Constraint::DoLayout(DrawAs how, Canvas *canvas,
|
||||
case Type::PROJ_PT_DISTANCE: {
|
||||
Canvas::Stroke strokeStippled = stroke;
|
||||
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
|
||||
strokeStippled.stippleScale = 4.0 / camera.scale;
|
||||
strokeStippled.stippleScale = 4.0;
|
||||
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
|
||||
|
||||
Vector ap = SK.GetEntity(ptA)->PointGetNum(),
|
||||
|
@ -499,6 +499,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
||||
pointStroke.zIndex = IsPoint() ? zIndex + 1 : 0;
|
||||
pointStroke.color = stroke.color;
|
||||
pointStroke.width = 7.0;
|
||||
pointStroke.unit = Canvas::Unit::PX;
|
||||
Canvas::hStroke hcsPoint = canvas->GetStroke(pointStroke);
|
||||
|
||||
switch(type) {
|
||||
@ -555,7 +556,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
||||
if(!SK.GetGroup(group)->IsVisible() || !SS.GW.showNormals) continue;
|
||||
}
|
||||
|
||||
stroke.layer = (asReference) ? Canvas::Layer::FRONT : Canvas::Layer::NORMAL;
|
||||
stroke.layer = (asReference) ? Canvas::Layer::FRONT : Canvas::Layer::NORMAL;
|
||||
if(how != DrawAs::HOVERED && how != DrawAs::SELECTED) {
|
||||
// Always draw the x, y, and z axes in red, green, and blue;
|
||||
// brighter for the ones at the bottom left of the screen,
|
||||
@ -627,7 +628,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
|
||||
Canvas::Stroke strokeBorder = stroke;
|
||||
strokeBorder.zIndex -= 3;
|
||||
strokeBorder.stipplePattern = StipplePattern::SHORT_DASH;
|
||||
strokeBorder.stippleScale = 8.0 / camera.scale;
|
||||
strokeBorder.stippleScale = 8.0;
|
||||
Canvas::hStroke hcsBorder = canvas->GetStroke(strokeBorder);
|
||||
|
||||
double textHeight = Style::TextHeight(hs) / camera.scale;
|
||||
|
@ -137,6 +137,50 @@ bool Canvas::Stroke::Equals(const Stroke &other) const {
|
||||
stippleScale == other.stippleScale);
|
||||
}
|
||||
|
||||
double Canvas::Stroke::WidthMm(const Camera &camera) const {
|
||||
switch(unit) {
|
||||
case Canvas::Unit::MM:
|
||||
return width;
|
||||
case Canvas::Unit::PX:
|
||||
return width / camera.scale;
|
||||
default:
|
||||
ssassert(false, "Unexpected unit");
|
||||
}
|
||||
}
|
||||
|
||||
double Canvas::Stroke::WidthPx(const Camera &camera) const {
|
||||
switch(unit) {
|
||||
case Canvas::Unit::MM:
|
||||
return width * camera.scale;
|
||||
case Canvas::Unit::PX:
|
||||
return width;
|
||||
default:
|
||||
ssassert(false, "Unexpected unit");
|
||||
}
|
||||
}
|
||||
|
||||
double Canvas::Stroke::StippleScaleMm(const Camera &camera) const {
|
||||
switch(unit) {
|
||||
case Canvas::Unit::MM:
|
||||
return stippleScale;
|
||||
case Canvas::Unit::PX:
|
||||
return stippleScale / camera.scale;
|
||||
default:
|
||||
ssassert(false, "Unexpected unit");
|
||||
}
|
||||
}
|
||||
|
||||
double Canvas::Stroke::StippleScalePx(const Camera &camera) const {
|
||||
switch(unit) {
|
||||
case Canvas::Unit::MM:
|
||||
return stippleScale * camera.scale;
|
||||
case Canvas::Unit::PX:
|
||||
return stippleScale;
|
||||
default:
|
||||
ssassert(false, "Unexpected unit");
|
||||
}
|
||||
}
|
||||
|
||||
bool Canvas::Fill::Equals(const Fill &other) const {
|
||||
return (layer == other.layer &&
|
||||
zIndex == other.zIndex &&
|
||||
|
@ -87,6 +87,12 @@ public:
|
||||
CONTOUR_ONLY // Contour outlines only
|
||||
};
|
||||
|
||||
// Stroke widths, etc, can be scale-invariant (in pixels) or scale-dependent (in millimeters).
|
||||
enum class Unit {
|
||||
MM,
|
||||
PX
|
||||
};
|
||||
|
||||
class Stroke {
|
||||
public:
|
||||
hStroke h;
|
||||
@ -95,11 +101,17 @@ public:
|
||||
int zIndex;
|
||||
RgbaColor color;
|
||||
double width;
|
||||
Unit unit;
|
||||
StipplePattern stipplePattern;
|
||||
double stippleScale;
|
||||
|
||||
void Clear() { *this = {}; }
|
||||
bool Equals(const Stroke &other) const;
|
||||
|
||||
double WidthMm(const Camera &camera) const;
|
||||
double WidthPx(const Camera &camera) const;
|
||||
double StippleScaleMm(const Camera &camera) const;
|
||||
double StippleScalePx(const Camera &camera) const;
|
||||
};
|
||||
|
||||
enum class FillPattern {
|
||||
|
@ -43,8 +43,9 @@ void CairoRenderer::SelectStroke(hStroke hcs) {
|
||||
|
||||
RgbaColor color = stroke->color;
|
||||
std::vector<double> dashes =
|
||||
StipplePatternDashes(stroke->stipplePattern, stroke->stippleScale * camera.scale);
|
||||
cairo_set_line_width(context, stroke->width);
|
||||
StipplePatternDashes(stroke->stipplePattern,
|
||||
stroke->StippleScalePx(camera));
|
||||
cairo_set_line_width(context, stroke->WidthPx(camera));
|
||||
cairo_set_dash(context, dashes.data(), dashes.size(), 0);
|
||||
cairo_set_source_rgba(context, color.redF(), color.greenF(), color.blueF(),
|
||||
color.alphaF());
|
||||
|
@ -191,7 +191,7 @@ Canvas::Stroke *OpenGl1Renderer::SelectStroke(hStroke hcs) {
|
||||
UnSelectPrimitive();
|
||||
ssglColorRGBA(stroke->color);
|
||||
ssglDepthRange(stroke->layer, stroke->zIndex);
|
||||
ssglLineWidth(stroke->width);
|
||||
ssglLineWidth(stroke->WidthPx(camera));
|
||||
// Fat lines and points are quads affected by glPolygonStipple, so make sure
|
||||
// they are displayed correctly.
|
||||
ssglFillPattern(FillPattern::SOLID);
|
||||
@ -329,12 +329,12 @@ void OpenGl1Renderer::DoLine(const Vector &a, const Vector &b, hStroke hcs) {
|
||||
if(a.Equals(b)) return;
|
||||
|
||||
Stroke *stroke = SelectStroke(hcs);
|
||||
if(stroke->width <= 3.0) {
|
||||
if(stroke->WidthPx(camera) <= 3.0) {
|
||||
SelectPrimitive(GL_LINES);
|
||||
ssglVertex3v(a);
|
||||
ssglVertex3v(b);
|
||||
} else {
|
||||
DoFatLine(a, b, stroke->width / camera.scale);
|
||||
DoFatLine(a, b, stroke->WidthPx(camera) / camera.scale);
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ void OpenGl1Renderer::DoStippledLine(const Vector &a, const Vector &b, hStroke h
|
||||
|
||||
const char *si = patternSeq;
|
||||
double end = len;
|
||||
double ss = stroke->stippleScale / 2.0;
|
||||
double ss = stroke->StippleScaleMm(camera) / 2.0;
|
||||
do {
|
||||
double start = end;
|
||||
switch(*si) {
|
||||
@ -400,7 +400,7 @@ void OpenGl1Renderer::DoStippledLine(const Vector &a, const Vector &b, hStroke h
|
||||
case '.':
|
||||
end = max(end - 0.5 * ss, 0.0);
|
||||
if(end == 0.0) break;
|
||||
DoPoint(a.Plus(dir.ScaledBy(end)), stroke->width);
|
||||
DoPoint(a.Plus(dir.ScaledBy(end)), stroke->WidthPx(camera));
|
||||
end = max(end - 0.5 * ss, 0.0);
|
||||
break;
|
||||
|
||||
|
@ -291,6 +291,14 @@ Canvas::Stroke Style::Stroke(hStyle hs) {
|
||||
stroke.stipplePattern = style->stippleType;
|
||||
stroke.stippleScale = Style::StippleScaleMm(hs);
|
||||
stroke.width = Style::Width(hs.v);
|
||||
switch(style->widthAs) {
|
||||
case Style::UnitsAs::PIXELS:
|
||||
stroke.unit = Canvas::Unit::PX;
|
||||
break;
|
||||
case Style::UnitsAs::MM:
|
||||
stroke.unit = Canvas::Unit::MM;
|
||||
break;
|
||||
}
|
||||
return stroke;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user