From 9c67a4fa7885fd443553c9e220c8461db9f92a8d Mon Sep 17 00:00:00 2001 From: coppro Date: Tue, 22 May 2007 02:31:17 +0000 Subject: [PATCH] Implemented difference (XOR) option for symbols. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@410 0fc631ac-6414-0410-93d0-97cfa31319b6 --- data/en.mse-locale/locale | 5 ++++- src/gui/symbol/select_editor.cpp | 13 +++++------ src/render/symbol/viewer.cpp | 37 +++++++++++++++++++------------- src/render/symbol/viewer.hpp | 2 +- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index 20fe7055..7ad092a3 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -1,4 +1,4 @@ -mse version: 0.3.2 +mse version: 0.3.2 full name: English ############################################################## Menu items @@ -194,6 +194,7 @@ help: merge: Merges this shape with those below it subtract: Subtracts this shape from shapes below it, leaves only the area in that shape that is not in this shape intersect: Intersects this shape with shapes below it, leaves only the area in both shapes + difference: Differs this shape from the shapes below it, leaves only the area not in any other shape overlap: Place this shape, and its border above shapes below it border: Draws this shape as a border @@ -251,6 +252,7 @@ tool: merge: Merge subtract: Subtract intersect: Intersect + difference: Difference overlap: Overlap border: Border @@ -317,6 +319,7 @@ tooltip: merge: Merge with shapes below subtract: Subtract from shapes below intersect: Intersect with shapes below + difference: Differ from shapes below overlap: Place above other shapes border: Draw as a border diff --git a/src/gui/symbol/select_editor.cpp b/src/gui/symbol/select_editor.cpp index c07cb672..ed5c42da 100644 --- a/src/gui/symbol/select_editor.cpp +++ b/src/gui/symbol/select_editor.cpp @@ -108,18 +108,19 @@ void SymbolSelectEditor::drawRotationCenter(DC& dc, const Vector2D& pos) { void SymbolSelectEditor::initUI(wxToolBar* tb, wxMenuBar* mb) { tb->AddSeparator(); - tb->AddTool(ID_PART_MERGE, _TOOL_("merge"), load_resource_image(_("combine_or")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("merge"), _HELP_("merge")); - tb->AddTool(ID_PART_SUBTRACT, _TOOL_("subtract"), load_resource_image(_("combine_sub_dark")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("subtract"), _HELP_("subtract")); - tb->AddTool(ID_PART_INTERSECTION, _TOOL_("intersect"),load_resource_image(_("combine_and_dark")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("intersect"), _HELP_("intersect")); - // note: difference doesn't work (yet) - tb->AddTool(ID_PART_OVERLAP, _TOOL_("overlap"), load_resource_image(_("combine_over")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("overlap"), _HELP_("overlap")); - tb->AddTool(ID_PART_BORDER, _TOOL_("border"), load_resource_image(_("combine_border")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("border"), _HELP_("border")); + tb->AddTool(ID_PART_MERGE, _TOOL_("merge"), load_resource_image(_("combine_or")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("merge"), _HELP_("merge")); + tb->AddTool(ID_PART_SUBTRACT, _TOOL_("subtract"), load_resource_image(_("combine_sub_dark")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("subtract"), _HELP_("subtract")); + tb->AddTool(ID_PART_INTERSECTION, _TOOL_("intersect"), load_resource_image(_("combine_and_dark")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("intersect"), _HELP_("intersect")); + tb->AddTool(ID_PART_DIFFERENCE, _TOOL_("difference"),load_resource_image(_("combine_xor")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("difference"), _HELP_("difference")); + tb->AddTool(ID_PART_OVERLAP, _TOOL_("overlap"), load_resource_image(_("combine_over")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("overlap"), _HELP_("overlap")); + tb->AddTool(ID_PART_BORDER, _TOOL_("border"), load_resource_image(_("combine_border")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("border"), _HELP_("border")); tb->Realize(); } void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) { tb->DeleteTool(ID_PART_MERGE); tb->DeleteTool(ID_PART_SUBTRACT); tb->DeleteTool(ID_PART_INTERSECTION); + tb->DeleteTool(ID_PART_DIFFERENCE); tb->DeleteTool(ID_PART_OVERLAP); tb->DeleteTool(ID_PART_BORDER); // HACK: hardcoded size of rest of toolbar diff --git a/src/render/symbol/viewer.cpp b/src/render/symbol/viewer.cpp index e753212b..a4acba0b 100644 --- a/src/render/symbol/viewer.cpp +++ b/src/render/symbol/viewer.cpp @@ -138,39 +138,41 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolPart& part, HighlightStyle void SymbolViewer::combineSymbolPart(const SymbolPart& part, DC& border, DC& interior, bool directB, bool directI) { // what color should the interior be? // use black when drawing to the screen - int interiorCol = directI ? 0 : 255; + unsigned char interiorCol = directI ? 0 : 255; // how to draw depends on combining mode switch(part.combine) { case PART_OVERLAP: case PART_MERGE: { - drawSymbolPart(part, &border, &interior, 255, interiorCol, directB); + drawSymbolPart(part, &border, &interior, 255, interiorCol, directB, false); break; } case PART_SUBTRACT: { border.SetLogicalFunction(wxAND); - drawSymbolPart(part, &border, &interior, 0, interiorCol ^ 255, directB); + drawSymbolPart(part, &border, &interior, 0, ~interiorCol, true, true); border.SetLogicalFunction(wxCOPY); break; } case PART_INTERSECTION: { MemoryDCP keepBorder = getTempDC(border); MemoryDCP keepInterior = getTempDC(interior); - drawSymbolPart(part, keepBorder.get(), keepInterior.get(), 255, 255, false); + drawSymbolPart(part, keepBorder.get(), keepInterior.get(), 255, 255, false, false); // combine the temporary dcs with the result using the AND operator wxSize s = border.GetSize(); - border .Blit(0, 0, s.GetWidth(), s.GetHeight(), &*keepBorder, 0, 0, wxAND); + border .Blit(0, 0, s.GetWidth(), s.GetHeight(), &*keepBorder , 0, 0, wxAND); interior.Blit(0, 0, s.GetWidth(), s.GetHeight(), &*keepInterior, 0, 0, wxAND); break; } case PART_DIFFERENCE: { - // TODO + interior.SetLogicalFunction(wxXOR); + drawSymbolPart(part, &border, &interior, 0, ~interiorCol, directB, true); + interior.SetLogicalFunction(wxCOPY); break; } case PART_BORDER: { // draw border as interior - drawSymbolPart(part, nullptr, &border, 0, 255, false); + drawSymbolPart(part, nullptr, &border, 0, 255, false, false); break; } } } -void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interior, int borderCol, int interiorCol, bool directB) { +void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interior, unsigned char borderCol, unsigned char interiorCol, bool directB, bool clear) { // create point list vector points; size_t size = part.points.size(); @@ -179,15 +181,20 @@ void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interi } // draw border if (border) { - if (directB) { - // white/green - border->SetBrush(Color(borderCol, min(255,borderCol + 128), borderCol)); - } else { - // white/black - border->SetBrush(Color(borderCol, borderCol, borderCol)); - } + // white/black + border->SetBrush(Color(borderCol, borderCol^(directB ? 128 : 0), borderCol)); border->SetPen(wxPen(*wxWHITE, (int) rotation.trS(border_radius))); border->DrawPolygon((int)points.size(), &points[0]); + + if (clear) { + border->SetPen(*wxTRANSPARENT_PEN); + border->SetBrush(Color(0, (directB ? 128 : 0), 0)); + + int func = border->GetLogicalFunction(); + border->SetLogicalFunction(wxCOPY); + border->DrawPolygon((int)points.size(), &points[0]); + border->SetLogicalFunction(func); + } } // draw interior if (interior) { diff --git a/src/render/symbol/viewer.hpp b/src/render/symbol/viewer.hpp index a0091022..80eb187a 100644 --- a/src/render/symbol/viewer.hpp +++ b/src/render/symbol/viewer.hpp @@ -60,7 +60,7 @@ class SymbolViewer : public SymbolView { * The **Col parameters give the color to use for the (interior of) the border and the interior * default should be white (255) border and black (0) interior. */ - void drawSymbolPart(const SymbolPart& part, DC* border, DC* interior, int borderCol, int interiorCol, bool directB); + void drawSymbolPart(const SymbolPart& part, DC* border, DC* interior, unsigned char borderCol, unsigned char interiorCol, bool directB, bool oppB); /* // ------------------- Bezier curve calculation