///////////////////////////////////////////////////////////////////////////// // Name: common/pseudodc.cpp // Purpose: Implementation of the wxPseudoDC Class // Author: Paul Lanier // Modified by: // Created: 05/25/06 // RCS-ID: $Id:$ // Copyright: (c) wxWidgets team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #include "wx/pseudodc.h" #include // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- // Destructor // ---------------------------------------------------------------------------- wxPseudoDC::~wxPseudoDC() { // delete all the nodes in the list ClearAll(); } // ---------------------------------------------------------------------------- // ClearAll - remove all nodes from list // ---------------------------------------------------------------------------- void wxPseudoDC::ClearAll(void) { while (m_list.Next() != &m_list) delete m_list.Next(); } // ---------------------------------------------------------------------------- // GetLen - return the number of operations in the current op list // ---------------------------------------------------------------------------- int wxPseudoDC::GetLen(void) { pdcNode *pt = m_list.Next(); int len=0; while (pt != &m_list) { len++; pt = pt->Next(); } return len; } // ---------------------------------------------------------------------------- // AddToList - Add a node to the list at the end (preserve draw order) // ---------------------------------------------------------------------------- void wxPseudoDC::AddToList(pdcNode *newNode) { // Add to end of list m_list.Insert(newNode); } // ---------------------------------------------------------------------------- // ClearID - remove all the operations associated with a single ID // ---------------------------------------------------------------------------- void wxPseudoDC::ClearId(int id) { pdcNode *pt = m_list.Next(); pdcNode *next; while (pt != &m_list) { next = pt->Next(); if (pt->GetId() == id) delete pt; pt = next; } } // ---------------------------------------------------------------------------- // DrawToDCClipped - play back the op list to the DC but clip any operations // known to be not in rect. This is a coarse level of // clipping to speed things up when lots of objects are off // screen and doesn't affect the dc level clipping // ---------------------------------------------------------------------------- void wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect) { pdcNode *pt = m_list.Next(); pdcDrawLabelNode *ptdl; pdc4CoordNode *pt4c; wxCoord x1,y1,x2,y2; x1 = rect.x; y1 = rect.y; x2 = x1+rect.width; y2 = y1+rect.height; while (pt != &m_list) { switch (pt->GetOp()) { case pdcOP_SET_FONT: dc->SetFont(((pdcFontNode*)pt)->m_font); break; case pdcOP_SET_PEN: dc->SetPen(((pdcPenNode*)pt)->m_pen); break; case pdcOP_SET_BRUSH: dc->SetBrush(((pdcBrushNode*)pt)->m_brush); break; case pdcOP_SET_BACKGROUND: dc->SetBackground(((pdcBrushNode*)pt)->m_brush); break; case pdcOP_SET_BACKGROUND_MODE: dc->SetBackgroundMode(((pdcIntNode*)pt)->m_i); break; case pdcOP_SET_TEXT_BACKGROUND: dc->SetTextBackground(((pdcColourNode*)pt)->m_colour); break; case pdcOP_SET_TEXT_FOREGROUND: dc->SetTextForeground(((pdcColourNode*)pt)->m_colour); break; case pdcOP_DRAW_LABEL: { ptdl = (pdcDrawLabelNode*)pt; if ((ptdl->m_rect.x < x2) && (ptdl->m_rect.x+ptdl->m_rect.width >= x1) && (ptdl->m_rect.y < y2) && (ptdl->m_rect.y+ptdl->m_rect.height >= y1)) dc->DrawLabel(ptdl->m_text, ptdl->m_rect, ptdl->m_align, ptdl->m_iAccel); break; } case pdcOP_DRAW_TEXT: { dc->DrawText(((pdcDrawTextNode*)pt)->m_text, ((pdcDrawTextNode*)pt)->m_x, ((pdcDrawTextNode*)pt)->m_y); break; } case pdcOP_DRAW_RECTANGLE: { pt4c = (pdc4CoordNode*)pt; if ((pt4c->m_c0 < x2) && (pt4c->m_c0+pt4c->m_c2 >= x1) && (pt4c->m_c1 < y2) && (pt4c->m_c1+pt4c->m_c3 >= y1)) dc->DrawRectangle(pt4c->m_c0, pt4c->m_c1, pt4c->m_c2, pt4c->m_c3); break; } case pdcOP_DRAW_LINE: { pt4c = (pdc4CoordNode*)pt; if ((pt4c->m_c0 < x2) && (pt4c->m_c0+pt4c->m_c2 >= x1) && (pt4c->m_c1 < y2) && (pt4c->m_c1+pt4c->m_c3 >= y1)) dc->DrawLine(pt4c->m_c0, pt4c->m_c1, pt4c->m_c2, pt4c->m_c3); break; } case pdcOP_CLEAR: dc->Clear(); break; case pdcOP_NOP: break; } pt = pt->Next(); } } // ---------------------------------------------------------------------------- // DrawToDC- play back the op list to the DC // ---------------------------------------------------------------------------- void wxPseudoDC::DrawToDC(wxDC *dc) { pdcNode *pt = m_list.Next(); pdcDrawLabelNode *ptdl; pdc4CoordNode *pt4c; while (pt != &m_list) { switch (pt->GetOp()) { case pdcOP_SET_FONT: dc->SetFont(((pdcFontNode*)pt)->m_font); break; case pdcOP_SET_PEN: dc->SetPen(((pdcPenNode*)pt)->m_pen); break; case pdcOP_SET_BRUSH: dc->SetBrush(((pdcBrushNode*)pt)->m_brush); break; case pdcOP_SET_BACKGROUND: dc->SetBackground(((pdcBrushNode*)pt)->m_brush); break; case pdcOP_SET_BACKGROUND_MODE: dc->SetBackgroundMode(((pdcIntNode*)pt)->m_i); break; case pdcOP_SET_TEXT_BACKGROUND: dc->SetTextBackground(((pdcColourNode*)pt)->m_colour); break; case pdcOP_SET_TEXT_FOREGROUND: dc->SetTextForeground(((pdcColourNode*)pt)->m_colour); break; case pdcOP_DRAW_LABEL: { ptdl = (pdcDrawLabelNode*)pt; dc->DrawLabel(ptdl->m_text, ptdl->m_rect, ptdl->m_align, ptdl->m_iAccel); break; } case pdcOP_DRAW_TEXT: { dc->DrawText(((pdcDrawTextNode*)pt)->m_text, ((pdcDrawTextNode*)pt)->m_x, ((pdcDrawTextNode*)pt)->m_y); break; } case pdcOP_DRAW_RECTANGLE: { pt4c = (pdc4CoordNode*)pt; dc->DrawRectangle(pt4c->m_c0, pt4c->m_c1, pt4c->m_c2, pt4c->m_c3); break; } case pdcOP_DRAW_LINE: { pt4c = (pdc4CoordNode*)pt; dc->DrawLine(pt4c->m_c0, pt4c->m_c1, pt4c->m_c2, pt4c->m_c3); break; } case pdcOP_CLEAR: dc->Clear(); break; case pdcOP_NOP: break; } pt = pt->Next(); } }