SVG: export stippled lines.
Also, factor out styles in the exported file, making it much smaller.
This commit is contained in:
parent
94cba11f2a
commit
d88149e705
|
@ -486,9 +486,14 @@ bool DxfFileWriter::NeedToOutput(Constraint *c) {
|
||||||
// Routines for EPS output
|
// Routines for EPS output
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
std::string MakeStipplePattern(int pattern, double scale, char delimiter) {
|
static std::string MakeStipplePattern(int pattern, double scale, char delimiter,
|
||||||
|
bool inkscapeWorkaround = false) {
|
||||||
scale /= 2.0;
|
scale /= 2.0;
|
||||||
|
|
||||||
|
// Inkscape ignores all elements that are exactly zero instead of drawing
|
||||||
|
// them as dots.
|
||||||
|
double zero = inkscapeWorkaround ? 1e-6 : 0;
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
switch(pattern) {
|
switch(pattern) {
|
||||||
case Style::STIPPLE_CONTINUOUS:
|
case Style::STIPPLE_CONTINUOUS:
|
||||||
|
@ -500,19 +505,21 @@ std::string MakeStipplePattern(int pattern, double scale, char delimiter) {
|
||||||
result = ssprintf("%.3f_%.3f", scale, scale);
|
result = ssprintf("%.3f_%.3f", scale, scale);
|
||||||
break;
|
break;
|
||||||
case Style::STIPPLE_DASH_DOT:
|
case Style::STIPPLE_DASH_DOT:
|
||||||
result = ssprintf("%.3f_%.3f_0_%.3f",
|
result = ssprintf("%.3f_%.3f_%.6f_%.3f",
|
||||||
scale, scale * 0.5, scale * 0.5);
|
scale, scale * 0.5, zero, scale * 0.5);
|
||||||
break;
|
break;
|
||||||
case Style::STIPPLE_DASH_DOT_DOT:
|
case Style::STIPPLE_DASH_DOT_DOT:
|
||||||
result = ssprintf("%.3f_%.3f_0_%.3f_0_%.3f",
|
result = ssprintf("%.3f_%.3f_%.6f_%.3f_%.6f_%.3f",
|
||||||
scale, scale * 0.5, scale * 0.5, scale * 0.5);
|
scale, scale * 0.5, zero,
|
||||||
|
scale * 0.5, scale * 0.5, zero);
|
||||||
break;
|
break;
|
||||||
case Style::STIPPLE_DOT:
|
case Style::STIPPLE_DOT:
|
||||||
result = ssprintf("0_%.3f", scale * 0.5);
|
result = ssprintf("%.6f_%.3f", zero, scale * 0.5);
|
||||||
break;
|
break;
|
||||||
case Style::STIPPLE_LONG_DASH:
|
case Style::STIPPLE_LONG_DASH:
|
||||||
result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5);
|
result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
oops();
|
oops();
|
||||||
}
|
}
|
||||||
|
@ -863,6 +870,37 @@ void SvgFileWriter::StartFile(void) {
|
||||||
"\r\n",
|
"\r\n",
|
||||||
(ptMax.x - ptMin.x), (ptMax.y - ptMin.y),
|
(ptMax.x - ptMin.x), (ptMax.y - ptMin.y),
|
||||||
(ptMax.x - ptMin.x), (ptMax.y - ptMin.y));
|
(ptMax.x - ptMin.x), (ptMax.y - ptMin.y));
|
||||||
|
|
||||||
|
fprintf(f, "<style><![CDATA[\r\n");
|
||||||
|
fprintf(f, "polygon {\r\n");
|
||||||
|
fprintf(f, "shape-rendering:crispEdges;\r\n");
|
||||||
|
// crispEdges turns of anti-aliasing, which tends to cause hairline
|
||||||
|
// cracks between triangles; but there still is some cracking, so
|
||||||
|
// specify a stroke width too, hope for around a pixel
|
||||||
|
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
||||||
|
fprintf(f, "stroke-width:%f;\r\n", sw);
|
||||||
|
fprintf(f, "}\r\n");
|
||||||
|
for(int i = 0; i < SK.style.n; i++) {
|
||||||
|
Style *s = &SK.style.elem[i];
|
||||||
|
RgbaColor strokeRgb = Style::Color(s->h, true);
|
||||||
|
int pattern = Style::PatternType(s->h);
|
||||||
|
double stippleScale = Style::StippleScaleMm(s->h);
|
||||||
|
|
||||||
|
fprintf(f, ".s%x {\r\n", s->h.v);
|
||||||
|
fprintf(f, "stroke:#%02x%02x%02x;\r\n", strokeRgb.red, strokeRgb.green, strokeRgb.blue);
|
||||||
|
// don't know why we have to take a half of the width
|
||||||
|
fprintf(f, "stroke-width:%f;\r\n", Style::WidthMm(s->h.v) / 2.0);
|
||||||
|
fprintf(f, "stroke-linecap:round;\r\n");
|
||||||
|
fprintf(f, "stroke-linejoin:round;\r\n");
|
||||||
|
std::string patternStr = MakeStipplePattern(pattern, stippleScale, ',',
|
||||||
|
/*inkscapeWorkaround=*/true);
|
||||||
|
if(!patternStr.empty()) {
|
||||||
|
fprintf(f, "stroke-dasharray:%s;\r\n", patternStr.c_str());
|
||||||
|
}
|
||||||
|
fprintf(f, "fill:none;\r\n");
|
||||||
|
fprintf(f, "}\r\n");
|
||||||
|
}
|
||||||
|
fprintf(f, "]]></style>\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth,
|
void SvgFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth,
|
||||||
|
@ -876,16 +914,11 @@ void SvgFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth,
|
||||||
{
|
{
|
||||||
std::string fill;
|
std::string fill;
|
||||||
if(filled) {
|
if(filled) {
|
||||||
fill = ssprintf("#%02x%02x%02x",
|
fill = ssprintf("fill='#%02x%02x%02x'",
|
||||||
fillRgb.red, fillRgb.green, fillRgb.blue);
|
fillRgb.red, fillRgb.green, fillRgb.blue);
|
||||||
} else {
|
|
||||||
fill = "none";
|
|
||||||
}
|
}
|
||||||
fprintf(f, "' stroke-width='%.3f' stroke='#%02x%02x%02x' "
|
std::string cls = ssprintf("s%x", style);
|
||||||
"stroke-linecap='round' stroke-linejoin='round' "
|
fprintf(f, "' class='%s' %s/>\r\n", cls.c_str(), fill.c_str());
|
||||||
"fill='%s' />\r\n",
|
|
||||||
lineWidth, strokeRgb.red, strokeRgb.green, strokeRgb.blue,
|
|
||||||
fill.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgFileWriter::MaybeMoveTo(Vector st, Vector fi) {
|
void SvgFileWriter::MaybeMoveTo(Vector st, Vector fi) {
|
||||||
|
@ -897,19 +930,14 @@ void SvgFileWriter::MaybeMoveTo(Vector st, Vector fi) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgFileWriter::Triangle(STriangle *tr) {
|
void SvgFileWriter::Triangle(STriangle *tr) {
|
||||||
// crispEdges turns of anti-aliasing, which tends to cause hairline
|
|
||||||
// cracks between triangles; but there still is some cracking, so
|
|
||||||
// specify a stroke width too, hope for around a pixel
|
|
||||||
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"<polygon points='%.3f,%.3f %.3f,%.3f %.3f,%.3f' "
|
"<polygon points='%.3f,%.3f %.3f,%.3f %.3f,%.3f' "
|
||||||
"stroke='#%02x%02x%02x' stroke-width='%.3f' "
|
"stroke='#%02x%02x%02x' "
|
||||||
"style='fill:#%02x%02x%02x' shape-rendering='crispEdges'/>\r\n",
|
"fill='#%02x%02x%02x'/>\r\n",
|
||||||
(tr->a.x - ptMin.x), (ptMax.y - tr->a.y),
|
(tr->a.x - ptMin.x), (ptMax.y - tr->a.y),
|
||||||
(tr->b.x - ptMin.x), (ptMax.y - tr->b.y),
|
(tr->b.x - ptMin.x), (ptMax.y - tr->b.y),
|
||||||
(tr->c.x - ptMin.x), (ptMax.y - tr->c.y),
|
(tr->c.x - ptMin.x), (ptMax.y - tr->c.y),
|
||||||
tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue,
|
tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue,
|
||||||
sw,
|
|
||||||
tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue);
|
tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user