1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        MadPrintout.cpp
3 // Description: Printing functions
4 // Author:      madedit@gmail.com
5 // Licence:     GPL
6 ///////////////////////////////////////////////////////////////////////////////
7 
8 #include <wx/print.h>
9 #include <wx/dc.h>
10 #include <wx/confbase.h>
11 #include <wx/filename.h>
12 #include "MadPrintout.h"
13 #include "MadEdit/MadEdit.h"
14 
15 extern MadEdit *g_ActiveMadEdit;
16 bool GetActiveMadEditPathNameOrTitle(wxString &name);
17 
18 // Global print data, to remember settings during the session
19 //wxPrintData *g_PrintData = (wxPrintData*) NULL ;
20 
21 // Global page setup data
22 wxPageSetupData *g_PageSetupData = (wxPageSetupData*) NULL;
23 
24 
25 int MadPrintout::s_PrintoutCount=0;
26 
MadPrintout(const wxString & title)27 MadPrintout::MadPrintout(const wxString& title)
28     : wxPrintout(title)
29 {
30     ++s_PrintoutCount;
31 }
32 
~MadPrintout()33 MadPrintout::~MadPrintout()
34 {
35     if(--s_PrintoutCount==0)
36     {
37         g_ActiveMadEdit->EndPrint();
38     }
39 }
40 
41 
OnPreparePrinting()42 void MadPrintout::OnPreparePrinting()
43 {
44     double xScale, yScale;
45     wxRect printRect;
46     CalcPrintInfo(g_PageSetupData, xScale, yScale, printRect);
47 
48     // get print info
49     wxConfigBase *cfg=wxConfigBase::Get(false);
50     wxString oldpath=cfg->GetPath();
51     cfg->SetPath(wxT("/MadEdit"));
52 
53     cfg->Read(wxT("PrintPageHeader"), &m_PrintHeader);
54     cfg->Read(wxT("PageHeaderLeft"), &m_HeaderLeft);
55     cfg->Read(wxT("PageHeaderCenter"), &m_HeaderCenter);
56     cfg->Read(wxT("PageHeaderRight"), &m_HeaderRight);
57 
58     cfg->Read(wxT("PrintPageFooter"), &m_PrintFooter);
59     cfg->Read(wxT("PageFooterLeft"), &m_FooterLeft);
60     cfg->Read(wxT("PageFooterCenter"), &m_FooterCenter);
61     cfg->Read(wxT("PageFooterRight"), &m_FooterRight);
62 
63     cfg->SetPath(oldpath);
64 
65     wxFont font=g_ActiveMadEdit->GetFont();
66     font.SetPointSize(12);      // use 12 PointSize to print Header, Footer
67     wxDC *dc=GetDC();
68     dc->SetFont(font);
69     m_CharHeight = dc->GetCharHeight();
70 
71     // subtract header,footer rect
72     m_HeaderHeight=0;
73     if(m_PrintHeader)
74     {
75         m_HeaderHeight = (m_CharHeight*5)/4 ; // 1.25 times
76         printRect.y += m_HeaderHeight;
77         printRect.height -= m_HeaderHeight;
78     }
79     m_FooterHeight=0;
80     if(m_PrintFooter)
81     {
82         m_FooterHeight = (m_CharHeight*5)/4 ; // 1.25 times
83         printRect.height -= m_FooterHeight;
84     }
85 
86     g_ActiveMadEdit->BeginPrint(printRect);
87 }
88 
89 
GetPageInfo(int * minPage,int * maxPage,int * pageFrom,int * pageTo)90 void MadPrintout::GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo)
91 {
92     // get info from g_ActiveMadEdit
93     *maxPage = *pageTo = g_ActiveMadEdit->GetPageCount();
94     if(*maxPage==0)
95     {
96         *minPage=*pageFrom=0;
97     }
98     else
99     {
100         *minPage=*pageFrom=1;
101     }
102 }
103 
HasPage(int page)104 bool MadPrintout::HasPage(int page)
105 {
106     // get info from g_ActiveMadEdit
107     int count=g_ActiveMadEdit->GetPageCount();
108     return (page>=1 && page<=count);
109 }
110 
111 /* Header & Footer Print Marks
112 %f File Name
113 %p Path Name
114 %n Page Number
115 %s Total Pages
116 %d Date
117 %t Time
118 */
TranslatePrintMark(const wxString & text,int pageNum)119 wxString TranslatePrintMark(const wxString &text, int pageNum)
120 {
121     wxString newtext, name;
122     wxDateTime now;
123     size_t count=text.Len();
124     for(size_t i=0;i<count;i++)
125     {
126         if(text[i]==wxT('%') && (i+1)<count)
127         {
128             const wxChar wc=text[++i];
129             switch(wc)
130             {
131             case wxT('f'):
132                 if(GetActiveMadEditPathNameOrTitle(name))
133                 {
134                     wxFileName fn(name);
135                     newtext += fn.GetFullName();
136                 }
137                 else // title
138                 {
139                     newtext += name;
140                 }
141                 break;
142             case wxT('p'):
143                 GetActiveMadEditPathNameOrTitle(name);
144                 newtext += name;
145                 break;
146             case wxT('n'):
147                 newtext << pageNum;
148                 break;
149             case wxT('s'):
150                 newtext << g_ActiveMadEdit->GetPageCount();
151                 break;
152             case wxT('d'):
153                 now = wxDateTime::Now();
154                 newtext += now.FormatDate();
155                 break;
156             case wxT('t'):
157                 now = wxDateTime::Now();
158                 newtext += now.FormatTime();
159                 break;
160             case wxT('%'):
161                 newtext += wxT('%');
162                 break;
163             default:
164                 newtext += wxT('%');
165                 newtext += text[i];
166                 break;
167             }
168         }
169         else
170         {
171             newtext += text[i];
172         }
173     }
174 
175     return newtext;
176 }
177 
178 
OnPrintPage(int page)179 bool MadPrintout::OnPrintPage(int page)
180 {
181     wxDC *dc = GetDC();
182 
183     double xScale, yScale;
184     wxRect rect;
185     // calc and set user scale
186     CalcPrintInfo(g_PageSetupData, xScale, yScale, rect);
187     dc->SetUserScale(xScale, yScale);
188 
189     // paint the contents
190     g_ActiveMadEdit->PrintPage(dc, page);
191 
192     // paint Header, Footer
193     wxFont font=g_ActiveMadEdit->GetFont();
194     font.SetPointSize(12);      // use 12 PointSize to print Header, Footer
195     dc->SetFont(font);
196     dc->SetTextForeground(*wxBLACK);
197 
198     int w, h;
199     wxString str;
200     if(m_PrintHeader)
201     {
202         if(!m_HeaderLeft.IsEmpty())
203         {
204             str=TranslatePrintMark(m_HeaderLeft, page);
205             dc->DrawText(str, rect.x, rect.y);
206         }
207         if(!m_HeaderCenter.IsEmpty())
208         {
209             str=TranslatePrintMark(m_HeaderCenter, page);
210             dc->GetTextExtent(str, &w, &h);
211             dc->DrawText(str, rect.x + (rect.width-w)/2, rect.y);
212         }
213         if(!m_HeaderRight.IsEmpty())
214         {
215             str=TranslatePrintMark(m_HeaderRight, page);
216             dc->GetTextExtent(str, &w, &h);
217             dc->DrawText(str, rect.x+rect.width-w, rect.y);
218         }
219 
220         // draw a line
221         dc->SetPen(*wxBLACK_PEN);
222         int y=rect.y+m_CharHeight+ (m_HeaderHeight-m_CharHeight)/2;
223         dc->DrawLine(rect.x, y, rect.x+rect.width, y);
224     }
225 
226     if(m_PrintFooter)
227     {
228         int y=rect.y+rect.height-m_CharHeight;
229 
230         if(!m_FooterLeft.IsEmpty())
231         {
232             str=TranslatePrintMark(m_FooterLeft, page);
233             dc->DrawText(str, rect.x, y);
234         }
235         if(!m_FooterCenter.IsEmpty())
236         {
237             str=TranslatePrintMark(m_FooterCenter, page);
238             dc->GetTextExtent(str, &w, &h);
239             dc->DrawText(str, rect.x + (rect.width-w)/2, y);
240         }
241         if(!m_FooterRight.IsEmpty())
242         {
243             str=TranslatePrintMark(m_FooterRight, page);
244             dc->GetTextExtent(str, &w, &h);
245             dc->DrawText(str, rect.x+rect.width-w, y);
246         }
247 
248         // draw a line
249         dc->SetPen(*wxBLACK_PEN);
250         y -= (m_HeaderHeight-m_CharHeight)/2;
251         dc->DrawLine(rect.x, y, rect.x+rect.width, y);
252     }
253 
254     /*
255     dc->SetBrush(*wxTRANSPARENT_BRUSH);
256     dc->DrawRectangle(rect);
257     */
258     return true;
259 }
260 
CalcPrintInfo(wxPageSetupData * pPageSetupData,double & xScale,double & yScale,wxRect & paintRect)261 void MadPrintout::CalcPrintInfo(wxPageSetupData *pPageSetupData, double &xScale, double &yScale, wxRect &paintRect)
262 {
263     wxDC *dc = GetDC();
264     int dcw, dch;
265     dc->GetSize(&dcw, &dch);
266 
267     int pagesize_x, pagesize_y;
268     GetPageSizeMM(&pagesize_x, &pagesize_y);
269     wxPoint pttl=pPageSetupData->GetMarginTopLeft();
270     wxPoint ptbr=pPageSetupData->GetMarginBottomRight();
271 
272     int sx, sy;
273     GetPPIScreen(&sx, &sy);
274 
275     // pagesize: convert mm to pixel
276     double px = double(pagesize_x)/25.4 * double(sx);
277     double py = double(pagesize_y)/25.4 * double(sy);
278 
279     // calc paintRect scale
280     double top    = double(pttl.y)/double(pagesize_y);
281     double left   = double(pttl.x)/double(pagesize_x);
282     double bottom = double(ptbr.y)/double(pagesize_y);
283     double right  = double(ptbr.x)/double(pagesize_x);
284 
285     // calc the pixel-size of paintRect
286     paintRect.x = int(left * px);
287     paintRect.y = int(top  * py);
288     paintRect.width  = int(px) - int(right * px) - paintRect.x;
289     paintRect.height = int(py) - int(bottom * py) - paintRect.y;
290 
291     // calc scaling factor
292     xScale = double(dcw) / px;
293     yScale = double(dch) / py;
294 }
295