OpenCPN Partial API docs
ocpn_print.cpp
1 /***************************************************************************
2  *
3  * Project: OpenCPN
4  * Purpose: Implement ocpn_print.h
5  * Author: David Register
6  *
7  ***************************************************************************
8  * Copyright (C) 2010 by David S. Register *
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  * This program is distributed in the hope that it will be useful, *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18  * GNU General Public License for more details. *
19  * *
20  * You should have received a copy of the GNU General Public License *
21  * along with this program; if not, write to the *
22  * Free Software Foundation, Inc., *
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24  **************************************************************************/
25 #include "config.h"
26 
27 #include "chcanv.h"
28 #include "glChartCanvas.h"
29 #include "ocpn_frame.h"
30 #include "ocpn_print.h"
31 
32 extern bool g_bopengl;
33 extern MyFrame* gFrame;
34 
35 class ChartCanvas;
36 ChartCanvas* GetFocusCanvas();
37 
38 
39 bool MyPrintout::OnPrintPage(int page) {
40  wxDC *dc = GetDC();
41  if (dc) {
42  if (page == 1) DrawPageOne(dc);
43 
44  return true;
45  } else
46  return false;
47 }
48 
49 bool MyPrintout::OnBeginDocument(int startPage, int endPage) {
50  if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false;
51 
52  return true;
53 }
54 
55 void MyPrintout::GetPageInfo(int* minPage, int* maxPage, int* selPageFrom,
56  int* selPageTo) {
57  *minPage = 1;
58  *maxPage = 1;
59  *selPageFrom = 1;
60  *selPageTo = 1;
61 }
62 
63 bool MyPrintout::HasPage(int pageNum) { return (pageNum == 1); }
64 
65 void MyPrintout::DrawPageOne(wxDC *dc) {
66  // Get the Size of the Chart Canvas
67  int sx, sy;
68  gFrame->GetFocusCanvas()->GetClientSize(&sx, &sy); // of the canvas
69 
70  float maxX = sx;
71  float maxY = sy;
72 
73  // Let's have at least some device units margin
74  float marginX = 50;
75  float marginY = 50;
76 
77  // Add the margin to the graphic size
78  maxX += (2 * marginX);
79  maxY += (2 * marginY);
80 
81  // Get the size of the DC in pixels
82  int w, h;
83  dc->GetSize(&w, &h);
84 
85  // Calculate a suitable scaling factor
86  float scaleX = (float)(w / maxX);
87  float scaleY = (float)(h / maxY);
88 
89  // Use x or y scaling factor, whichever fits on the DC
90  float actualScale = wxMin(scaleX, scaleY);
91 
92  // Calculate the position on the DC for centring the graphic
93  float posX = (float)((w - (maxX * actualScale)) / 2.0);
94  float posY = (float)((h - (maxY * actualScale)) / 2.0);
95 
96  posX = wxMax(posX, marginX);
97  posY = wxMax(posY, marginY);
98 
99  // Set the scale and origin
100  dc->SetUserScale(actualScale, actualScale);
101  dc->SetDeviceOrigin((long)posX, (long)posY);
102 
103  // Get the latest bitmap as rendered by the ChartCanvas
104 
105  if (g_bopengl) {
106 #ifdef ocpnUSE_GL
107  if (m_GLbmp.IsOk()) {
108  wxMemoryDC mdc;
109  mdc.SelectObject(m_GLbmp);
110  dc->Blit(0, 0, m_GLbmp.GetWidth(), m_GLbmp.GetHeight(), &mdc, 0, 0);
111  mdc.SelectObject(wxNullBitmap);
112  }
113 #endif
114  } else {
115  // And Blit/scale it onto the Printer DC
116  wxMemoryDC mdc;
117  mdc.SelectObject(*(gFrame->GetFocusCanvas()->pscratch_bm));
118 
119  dc->Blit(0, 0, gFrame->GetFocusCanvas()->pscratch_bm->GetWidth(),
120  gFrame->GetFocusCanvas()->pscratch_bm->GetHeight(), &mdc, 0, 0);
121 
122  mdc.SelectObject(wxNullBitmap);
123  }
124 }
125 
126 void MyPrintout::GenerateGLbmp() {
127  if (g_bopengl) {
128 #ifdef ocpnUSE_GL
129  int gsx = gFrame->GetFocusCanvas()->GetglCanvas()->GetSize().x;
130  int gsy = gFrame->GetFocusCanvas()->GetglCanvas()->GetSize().y;
131 
132  unsigned char *buffer = (unsigned char *)malloc(gsx * gsy * 4);
133  glReadPixels(0, 0, gsx, gsy, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
134 
135  unsigned char *e = (unsigned char *)malloc(gsx * gsy * 3);
136 
137  if (buffer && e) {
138  for (int p = 0; p < gsx * gsy; p++) {
139  e[3 * p + 0] = buffer[4 * p + 0];
140  e[3 * p + 1] = buffer[4 * p + 1];
141  e[3 * p + 2] = buffer[4 * p + 2];
142  }
143  }
144  free(buffer);
145 
146  wxImage image(gsx, gsy);
147  image.SetData(e);
148  wxImage mir_imag = image.Mirror(false);
149  m_GLbmp = wxBitmap(mir_imag);
150 #endif
151  }
152 }