moved symbol viewer, because it is not part of the gui

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@69 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2006-10-31 16:18:15 +00:00
parent a5b8efaa78
commit 5b56e8ee11
2 changed files with 0 additions and 0 deletions
-223
View File
@@ -1,223 +0,0 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <gui/symbol/viewer.hpp>
DECLARE_TYPEOF_COLLECTION(SymbolPartP);
// ----------------------------------------------------------------------------- : Constructor
SymbolViewer::SymbolViewer(const SymbolP& symbol, double borderRadius)
: borderRadius(borderRadius)
, rotation(0, RealRect(0,0,500,500))
{
setSymbol(symbol);
}
// ----------------------------------------------------------------------------- : Drawing
typedef shared_ptr<wxMemoryDC> MemoryDCP;
// Return a temporary DC with the same size as the parameter
MemoryDCP getTempDC(DC& dc) {
wxSize s = dc.GetSize();
Bitmap buffer(s.GetWidth(), s.GetHeight(), 1);
MemoryDCP newDC(new wxMemoryDC);
newDC->SelectObject(buffer);
// On windows 9x it seems that bitmaps are not black by default
#if !BITMAPS_DEFAULT_BLACK
newDC->SetPen(*wxTRANSPARENT_PEN);
newDC->SetBrush(*wxBLACK_BRUSH);
newDC->DrawRectangle(0, 0, s.GetWidth(), s.GetHeight());
#endif
return newDC;
}
// Combine the temporary DCs used in the drawing with the main dc
void combineBuffers(DC& dc, DC* borders, DC* interior) {
wxSize s = dc.GetSize();
if (borders) dc.Blit(0, 0, s.GetWidth(), s.GetHeight(), borders, 0, 0, wxOR);
if (interior) dc.Blit(0, 0, s.GetWidth(), s.GetHeight(), interior, 0, 0, wxAND_INVERT);
}
void SymbolViewer::draw(DC& dc) {
bool paintedSomething = false;
bool buffersFilled = false;
// Temporary dcs
MemoryDCP borderDC;
MemoryDCP interiorDC;
// Check if we can paint directly to the dc
// This will fail if there are parts with combine == intersection
FOR_EACH(p, symbol->parts) {
if (p->combine == PART_INTERSECTION) {
paintedSomething = true;
break;
}
}
// Draw all parts, in reverse order (bottom to top)
FOR_EACH_REVERSE(p, symbol->parts) {
const SymbolPart& part = *p;
if (part.combine == PART_OVERLAP && buffersFilled) {
// We will be overlapping some previous parts, write them to the screen
combineBuffers(dc, borderDC.get(), interiorDC.get());
// Clear the buffers
buffersFilled = false;
paintedSomething = true;
wxSize s = dc.GetSize();
if (borderDC) {
borderDC->SetBrush(*wxBLACK_BRUSH);
borderDC->SetPen( *wxTRANSPARENT_PEN);
borderDC->DrawRectangle(0, 0, s.GetWidth(), s.GetHeight());
}
interiorDC->SetBrush(*wxBLACK_BRUSH);
interiorDC->DrawRectangle(0, 0, s.GetWidth(), s.GetHeight());
}
if (!paintedSomething) {
// No need to buffer
if (!interiorDC) interiorDC = getTempDC(dc);
combineSymbolPart(part, dc, *interiorDC, true, false);
buffersFilled = true;
} else {
if (!borderDC) borderDC = getTempDC(dc);
if (!interiorDC) interiorDC = getTempDC(dc);
// Draw this part to the buffer
combineSymbolPart(part, *borderDC, *interiorDC, false, false);
buffersFilled = true;
}
}
// Output the final parts from the buffer
if (buffersFilled) {
combineBuffers(dc, borderDC.get(), interiorDC.get());
}
}
void SymbolViewer::highlightPart(DC& dc, const SymbolPart& part, HighlightStyle style) {
// create point list
vector<wxPoint> points;
size_t size = part.points.size();
for(size_t i = 0 ; i < size ; ++i) {
segment_subdivide(*part.getPoint((int)i), *part.getPoint((int)i+1), rotation, points);
}
// draw
if (style == HIGHLIGHT_BORDER) {
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.SetPen (wxPen(Color(255,0,0), 2));
dc.DrawPolygon((int)points.size(), &points[0]);
} else {
dc.SetLogicalFunction(wxOR);
dc.SetBrush(Color(0,0,64));
dc.SetPen (*wxTRANSPARENT_PEN);
dc.DrawPolygon((int)points.size(), &points[0]);
if (part.combine == PART_SUBTRACT || part.combine == PART_BORDER) {
dc.SetLogicalFunction(wxAND);
dc.SetBrush(Color(192,192,255));
dc.DrawPolygon((int)points.size(), &points[0]);
}
dc.SetLogicalFunction(wxCOPY);
}
}
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;
// how to draw depends on combining mode
switch(part.combine) {
case PART_OVERLAP:
case PART_MERGE: {
drawSymbolPart(part, &border, &interior, 255, interiorCol, directB);
break;
} case PART_SUBTRACT: {
border.SetLogicalFunction(wxAND);
drawSymbolPart(part, &border, &interior, 0, interiorCol ^ 255, directB);
border.SetLogicalFunction(wxCOPY);
break;
} case PART_INTERSECTION: {
MemoryDCP keepBorder = getTempDC(border);
MemoryDCP keepInterior = getTempDC(interior);
drawSymbolPart(part, keepBorder.get(), keepInterior.get(), 255, 255, 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);
interior.Blit(0, 0, s.GetWidth(), s.GetHeight(), &*keepInterior, 0, 0, wxAND);
break;
} case PART_DIFFERENCE: {
// TODO
break;
} case PART_BORDER: {
// draw border as interior
drawSymbolPart(part, nullptr, &border, 0, 255, false);
break;
}
}
}
void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interior, int borderCol, int interiorCol, bool directB) {
// create point list
vector<wxPoint> points;
size_t size = part.points.size();
for(size_t i = 0 ; i < size ; ++i) {
segment_subdivide(*part.getPoint((int)i), *part.getPoint((int)i+1), rotation, points);
}
// 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));
}
border->SetPen(wxPen(*wxWHITE, rotation.trS(borderRadius)));
border->DrawPolygon((int)points.size(), &points[0]);
}
// draw interior
if (interior) {
interior->SetBrush(Color(interiorCol,interiorCol,interiorCol));
interior->SetPen(*wxTRANSPARENT_PEN);
interior->DrawPolygon((int)points.size(), &points[0]);
}
}
/*
void SymbolViewer::calcBezierPoint(const ControlPointP& p0, const ControlPointP& p1, Point*& p_out, UInt count) {
BezierCurve c(*p0, *p1);
// add start point
*p_out = toDisplay(*p0);
++p_out;
// recursively calculate rest of curve
calcBezierOpt(c, *p0, *p1, 0.0f, 1.0f, p_out, count-1);
}
void SymbolViewer::calcBezierOpt(const BezierCurve& c, const Vector2D& p0, const Vector2D& p1, double t0, double t1, Point*& p_out, mutable UInt count) {
if (count <= 0) return;
double midtime = (t0+t1) * 0.5f;
Vector2D midpoint = c.pointAt(midtime);
Vector2D d0 = p0 - midpoint;
Vector2D d1 = midpoint - p1;
// Determine treshold for subdivision, greater angle -> subdivide
// greater size -> subdivide
double treshold = fabs( atan2(d0.x,d0.y) - atan2(d1.x,d1.y)) * (p0-p1).lengthSqr();
bool subdivide = treshold >= .0001;
// subdivide left
calcBezierOpt(c, p0, midpoint, t0, midtime, p_out, count/2);
// add midpoint
if (subdivide) {
*p_out = toDisplay(midpoint);
++p_out;
count -= 1;
}
// subdivide right
calcBezierOpt(c, midpoint, p1, midtime, t1, p_out, count/2);
}
*/
-74
View File
@@ -1,74 +0,0 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_GUI_SYMBOL_VIEWER
#define HEADER_GUI_SYMBOL_VIEWER
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/rotation.hpp>
#include <data/symbol.hpp>
#include <gfx/bezier.hpp>
// ----------------------------------------------------------------------------- : Symbol Viewer
enum HighlightStyle {
HIGHLIGHT_BORDER,
HIGHLIGHT_INTERIOR
};
/// Class that knows how to draw a symbol
class SymbolViewer : public SymbolView {
public:
// --------------------------------------------------- : Data
SymbolViewer(const SymbolP& symbol, double borderRadius = 0.05);
// drawing
double borderRadius;
// --------------------------------------------------- : Point translation
Rotation rotation; ///< Object that handles rotation, scaling and translation
// --------------------------------------------------- : Drawing
public:
/// Draw the symbol to a dc
void draw(DC& dc);
void highlightPart(DC& dc, const SymbolPart& part, HighlightStyle style);
private:
/// Combines a symbol part with what is currently drawn, the border and interior are drawn separatly
/** directB/directI are true if the border/interior is the screen dc, false if it
* is a temporary 1 bit one
*/
void combineSymbolPart(const SymbolPart& part, DC& border, DC& interior, bool directB, bool directI);
/// Draw a symbol part, draws the border and the interior to separate DCs
/** The DCs may be null. directB should be true when drawing the border directly to the screen.
* 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);
/*
// ------------------- Bezier curve calculation
// Calculate the points on a bezier curve between p0 and p1
// Stores the Points in p_out, at most count points are stored
// after this call p_out points to just beyond the last point
void calcBezierPoint(const ControlPointP& p0, const ControlPointP& p1, wxPoint*& p_out, UInt count);
// Subdivide a bezier curve by adding at most count points
// p0 = c(t0), p1 = c(p1)
// subdivides linearly between t0 and t1, and only when necessary
// adds points to p_out and increments the pointer when a point is added
void calcBezierOpt(const BezierCurve& c, const Vector2D& p0, const Vector2D& p1, double t0, double t1, wxPoint*& p_out, UInt count);
*/};
// ----------------------------------------------------------------------------- : EOF
#endif