OpenCPN Partial API docs
Loading...
Searching...
No Matches
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
32extern bool g_bopengl;
33extern MyFrame* gFrame;
34
35class ChartCanvas;
36ChartCanvas* GetFocusCanvas();
37
38
39bool 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
49bool MyPrintout::OnBeginDocument(int startPage, int endPage) {
50 if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false;
51
52 return true;
53}
54
55void 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
63bool MyPrintout::HasPage(int pageNum) { return (pageNum == 1); }
64
65void 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
126void 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}
153