- Add missing styles support to wxWindow XRC hanlder (Steffen Olszewski).
- Allow specifying all wxFlexGridSizer parameters in XRC (Steffen Olszewski).
- Close wxLogWindow automatically if it's the last remaining top level window.
+- Implement clipping for wxSVGFileDC (Steve Benbow).
wxGTK:
wxFAIL_MSG(wxT("wxSVGFILEDC::Clear() Call not implemented \nNot sensible for an output file?"));
}
- virtual void DestroyClippingRegion()
- {
- wxFAIL_MSG(wxT("wxSVGFILEDC::void Call not yet implemented"));
- }
+ virtual void DestroyClippingRegion();
virtual wxCoord GetCharHeight() const;
virtual wxCoord GetCharWidth() const;
wxFAIL_MSG(wxT("wxSVGFILEDC::DoSetDeviceClippingRegion not yet implemented"));
}
- virtual void DoSetClippingRegion( int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
- {
- wxFAIL_MSG(wxT("wxSVGFILEDC::DoSetClippingRegion not yet implemented"));
- }
+ virtual void DoSetClippingRegion(int x, int y, int width, int height);
virtual void DoGetSizeMM( int *width, int *height ) const;
// new one for the last pen/brush change.
void NewGraphicsIfNeeded();
+ // Open a new graphics group setting up all the attributes according to
+ // their current values in wxDC.
+ void DoStartNewGraphics();
+
wxFileOutputStream *m_outfile;
wxString m_filename;
int m_sub_images; // number of png format images we have
int m_width, m_height;
double m_dpi;
-private:
+ // The clipping nesting level is incremented by every call to
+ // SetClippingRegion() and reset when DestroyClippingRegion() is called.
+ size_t m_clipNestingLevel;
+
+ // Unique ID for every clipping graphics group: this is simply always
+ // incremented in each SetClippingRegion() call.
+ size_t m_clipUniqueId;
+
DECLARE_ABSTRACT_CLASS(wxSVGFileDCImpl)
};
*/
void SetLogicalFunction(wxRasterOperationMode function);
+ /**
+ Sets the clipping region for this device context to the intersection of
+ the given region described by the parameters of this method and the previously
+ set clipping region.
+ Clipping is implemented in the SVG output using SVG group elements (<g>), with
+ nested group elements being used to represent clipping region intersections when
+ two or more calls are made to SetClippingRegion().
+ */
+ void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width,
+ wxCoord height);
+
+ /**
+ This is an overloaded member function, provided for convenience. It differs from the
+ above function only in what argument(s) it accepts.
+ */
+ void SetClippingRegion(const wxPoint& pt, const wxSize& sz);
+
+ /**
+ This is an overloaded member function, provided for convenience. It differs from the
+ above function only in what argument(s) it accepts.
+ */
+ void SetClippingRegion(const wxRect& rect);
+
+ /**
+ This function is not implemented in this DC class.
+ It could be implemented in future if a GetPoints() function were made available on wxRegion.
+ */
+ void SetClippingRegion(const wxRegion& region);
+
+ /**
+ Destroys the current clipping region so that none of the DC is clipped.
+ Since intersections arising from sequential calls to SetClippingRegion are represented
+ with nested SVG group elements (<g>), all such groups are closed when
+ DestroyClippingRegion is called.
+ */
+ void DestroyClippingRegion();
+
//@{
/**
Functions not implemented in this DC class.
*/
void CrossHair(wxCoord x, wxCoord y);
- void DestroyClippingRegion();
bool FloodFill(wxCoord x, wxCoord y, const wxColour& colour,
wxFloodFillStyle style = wxFLOOD_SURFACE);
void GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *width, wxCoord *height) const;
bool GetPixel(wxCoord x, wxCoord y, wxColour* colour) const;
- void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width,
- wxCoord height);
- void SetClippingRegion(const wxPoint& pt, const wxSize& sz);
- void SetClippingRegion(const wxRect& rect);
- void SetClippingRegion(const wxRegion& region);
void SetPalette(const wxPalette& palette);
bool StartDoc(const wxString& message);
//@}
SetBackgroundColour(wxColour(wxT("WHITE")));
m_child = parent;
- m_index = m_child->GetFrame()->GetCountOfChildren() % 8;
+ m_index = m_child->GetFrame()->GetCountOfChildren() % 9;
}
// Define the repainting behaviour
break;
case 7:
+ dc.SetTextForeground(wxT("RED"));
+ dc.DrawText(wxT("Red = Clipping Off"), 30, 5);
+ dc.SetTextForeground(wxT("GREEN"));
+ dc.DrawText(wxT("Green = Clipping On"), 30, 25);
+
+ dc.SetTextForeground(wxT("BLACK"));
+
+ dc.SetPen(*wxRED_PEN);
+ dc.SetBrush (wxBrush (wxT("SALMON"),wxBRUSHSTYLE_TRANSPARENT));
+ dc.DrawCheckMark ( 80,50,75,75);
+ dc.DrawRectangle ( 80,50,75,75);
+
+ dc.SetPen(*wxGREEN_PEN);
+
+ // Clipped checkmarks
+ dc.DrawRectangle(180,50,75,75);
+ dc.SetClippingRegion(180,50,75,75); // x,y,width,height version
+ dc.DrawCheckMark ( 180,50,75,75);
+ dc.DestroyClippingRegion();
+
+ dc.DrawRectangle(wxRect(80,150,75,75));
+ dc.SetClippingRegion(wxPoint(80,150),wxSize(75,75)); // pt,size version
+ dc.DrawCheckMark ( 80,150,75,75);
+ dc.DestroyClippingRegion();
+
+ dc.DrawRectangle(wxRect(180,150,75,75));
+ dc.SetClippingRegion(wxRect(180,150,75,75)); // rect version
+ dc.DrawCheckMark ( 180,150,75,75);
+ dc.DestroyClippingRegion();
+
+ dc.DrawRectangle(wxRect( 80,250,50,65));
+ dc.DrawRectangle(wxRect(105,260,50,65));
+ dc.SetClippingRegion(wxRect( 80,250,50,65)); // second call to SetClippingRegion
+ dc.SetClippingRegion(wxRect(105,260,50,65)); // forms intersection with previous
+ dc.DrawCheckMark(80,250,75,75);
+ dc.DestroyClippingRegion(); // only one call to destroy (there's no stack)
+
+ /*
+ ** Clipping by wxRegion not implemented for SVG. Should be
+ ** possible, but need to access points that define the wxRegion
+ ** from inside DoSetDeviceClippingRegion() and wxRegion does not
+ ** implement anything like getPoints().
+ points[0].x = 180; points[0].y = 250;
+ points[1].x = 255; points[1].y = 250;
+ points[2].x = 180; points[2].y = 325;
+ points[3].x = 255; points[3].y = 325;
+ points[4].x = 180; points[4].y = 250;
+
+ dc.DrawLines (5, points);
+ wxRegion reg = wxRegion(5,points);
+
+ dc.SetClippingRegion(reg);
+ dc.DrawCheckMark ( 180,250,75,75);
+ dc.DestroyClippingRegion();
+ */
+
+#if wxUSE_STATUSBAR
+ s = wxT("Clipping region");
+#endif // wxUSE_STATUSBAR
+ break;
+
+ case 8:
wxString txtStr;
wxCoord txtX, txtY, txtW, txtH, txtDescent, txtEL;
wxCoord txtPad = 0;
s = wxT("Text position test page");
#endif // wxUSE_STATUSBAR
break;
-
}
#if wxUSE_STATUSBAR
m_child->SetStatusText(s);
m_OK = true;
+ m_clipUniqueId = 0;
+ m_clipNestingLevel = 0;
+
m_mm_to_pix_x = dpi/25.4;
m_mm_to_pix_y = dpi/25.4;
}
}
+void wxSVGFileDCImpl::DoSetClippingRegion( int x, int y, int width, int height )
+{
+ wxString svg;
+
+ // End current graphics group to ensure proper xml nesting (e.g. so that
+ // graphics can be subsequently changed inside the clipping region)
+ svg << "</g>\n"
+ "<defs>\n"
+ "<clipPath id=\"clip" << m_clipNestingLevel << "\">\n"
+ "<rect id=\"cliprect" << m_clipNestingLevel << "\" "
+ "x=\"" << x << "\" "
+ "y=\"" << y << "\" "
+ "width=\"" << width << "\" "
+ "height=\"" << height << "\" "
+ "style=\"stroke: gray; fill: none;\"/>\n"
+ "</clipPath>\n"
+ "</defs>\n"
+ "<g style=\"clip-path: url(#clip" << m_clipNestingLevel << ");\">\n";
+
+ write(svg);
+
+ // Re-apply current graphics to ensure proper xml nesting
+ DoStartNewGraphics();
+
+ m_clipUniqueId++;
+ m_clipNestingLevel++;
+}
+
+void wxSVGFileDCImpl::DestroyClippingRegion()
+{
+ wxString svg;
+
+ // End current graphics element to ensure proper xml nesting (e.g. graphics
+ // might have been changed inside the clipping region)
+ svg << "</g>\n";
+
+ // Close clipping group elements
+ for ( size_t i = 0; i < m_clipUniqueId; i++ )
+ {
+ svg << "</g>";
+ }
+ svg << "\n";
+
+ write(svg);
+
+ // Re-apply current graphics (e.g. brush may have been changed inside one
+ // of the clipped regions - that change will have been lost after xml
+ // elements for the clipped region have been closed).
+ DoStartNewGraphics();
+
+ m_clipUniqueId = 0;
+}
+
void wxSVGFileDCImpl::DoGetTextExtent(const wxString& string, wxCoord *w, wxCoord *h, wxCoord *descent , wxCoord *externalLeading , const wxFont *font) const
{
m_graphics_changed = false;
+ write(wxS("</g>\n"));
+
+ DoStartNewGraphics();
+}
+
+void wxSVGFileDCImpl::DoStartNewGraphics()
+{
wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast;
- sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour(), m_brush.GetStyle() )
+ sBrush = wxS("<g style=\"") + wxBrushString ( m_brush.GetColour(), m_brush.GetStyle() )
+ wxPenString(m_pen.GetColour(), m_pen.GetStyle());
switch ( m_pen.GetCap() )