From 94cba11f2a50d5c4f043811154d516a2199e4e8a Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Mon, 4 Apr 2016 17:21:30 +0600 Subject: [PATCH] PDF, EPS: export stippled lines. --- src/export.cpp | 4 +-- src/exportvector.cpp | 79 +++++++++++++++++++++++++++++++++++--------- src/solvespace.h | 32 +++++++++--------- 3 files changed, 81 insertions(+), 34 deletions(-) diff --git a/src/export.cpp b/src/export.cpp index dd269c1..e2993d4 100644 --- a/src/export.cpp +++ b/src/export.cpp @@ -537,13 +537,13 @@ void VectorFileWriter::OutputLinesAndMesh(SBezierLoopSetSet *sblss, SMesh *sm) { RgbaColor strokeRgb = Style::Color(hs, true); RgbaColor fillRgb = Style::FillColor(hs, true); - StartPath(strokeRgb, lineWidth, stl->filled, fillRgb); + StartPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs.v); for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { for(b = sbl->l.First(); b; b = sbl->l.NextAfter(b)) { Bezier(b); } } - FinishPath(strokeRgb, lineWidth, stl->filled, fillRgb); + FinishPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs.v); } } FinishAndCloseFile(); diff --git a/src/exportvector.cpp b/src/exportvector.cpp index d7e7a19..bd4d802 100644 --- a/src/exportvector.cpp +++ b/src/exportvector.cpp @@ -443,7 +443,7 @@ void DxfFileWriter::StartFile(void) { } void DxfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { BezierPath path = {}; path.color = strokeRgb.ToPackedIntBGRA(); @@ -451,7 +451,7 @@ void DxfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, paths.push_back(path); } void DxfFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { } @@ -485,6 +485,41 @@ bool DxfFileWriter::NeedToOutput(Constraint *c) { //----------------------------------------------------------------------------- // Routines for EPS output //----------------------------------------------------------------------------- + +std::string MakeStipplePattern(int pattern, double scale, char delimiter) { + scale /= 2.0; + + std::string result; + switch(pattern) { + case Style::STIPPLE_CONTINUOUS: + case Style::STIPPLE_FREEHAND: + case Style::STIPPLE_ZIGZAG: + return ""; + + case Style::STIPPLE_DASH: + result = ssprintf("%.3f_%.3f", scale, scale); + break; + case Style::STIPPLE_DASH_DOT: + result = ssprintf("%.3f_%.3f_0_%.3f", + scale, scale * 0.5, scale * 0.5); + break; + case Style::STIPPLE_DASH_DOT_DOT: + result = ssprintf("%.3f_%.3f_0_%.3f_0_%.3f", + scale, scale * 0.5, scale * 0.5, scale * 0.5); + break; + case Style::STIPPLE_DOT: + result = ssprintf("0_%.3f", scale * 0.5); + break; + case Style::STIPPLE_LONG_DASH: + result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5); + break; + default: + oops(); + } + std::replace(result.begin(), result.end(), '_', delimiter); + return result; +} + void EpsFileWriter::StartFile(void) { fprintf(f, "%%!PS-Adobe-2.0\r\n" @@ -505,21 +540,28 @@ void EpsFileWriter::StartFile(void) { } void EpsFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { fprintf(f, "newpath\r\n"); prevPt = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); } void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { + hStyle hs = { style }; + int pattern = Style::PatternType(hs); + double stippleScale = MmToPts(Style::StippleScaleMm(hs)); + fprintf(f, " %.3f setlinewidth\r\n" " %.3f %.3f %.3f setrgbcolor\r\n" " 1 setlinejoin\r\n" // rounded " 1 setlinecap\r\n" // rounded + " [%s] 0 setdash\r\n" " gsave stroke grestore\r\n", MmToPts(lineWidth), - strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF()); + strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF(), + MakeStipplePattern(pattern, stippleScale, ' ').c_str() + ); if(filled) { fprintf(f, " %.3f %.3f %.3f setrgbcolor\r\n" " gsave fill grestore\r\n", @@ -730,12 +772,17 @@ void PdfFileWriter::FinishAndCloseFile(void) { } void PdfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { + hStyle hs = { style }; + int pattern = Style::PatternType(hs); + double stippleScale = MmToPts(Style::StippleScaleMm(hs)); + fprintf(f, "1 J 1 j " // round endcaps and joins - "%.3f w " + "%.3f w [%s] 0 d " "%.3f %.3f %.3f RG\r\n", MmToPts(lineWidth), + MakeStipplePattern(pattern, stippleScale, ' ').c_str(), strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF()); if(filled) { fprintf(f, "%.3f %.3f %.3f rg\r\n", @@ -745,7 +792,7 @@ void PdfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, prevPt = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); } void PdfFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { if(filled) { fprintf(f, "b\r\n"); @@ -819,13 +866,13 @@ void SvgFileWriter::StartFile(void) { } void SvgFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, - bool filled, RgbaColor fillRgb) + bool filled, RgbaColor fillRgb, uint32_t style) { fprintf(f, "