///
/// Copyright (C) 2004-2007 Andrej Vodopivec <andrejv@users.sourceforge.net>
///
/// This program is free software; you can redistribute it and/or modify
/// it under the terms of the GNU General Public License as published by
/// the Free Software Foundation; either version 2 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
///
/// You should have received a copy of the GNU General Public License
/// along with this program; if not, write to the Free Software
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///
#include "MathPrintout.h"
#if WXM_PRINT
#include <wx/config.h>
#define PRINT_MARGIN_HORIZONTAL 5
#define PRINT_MARGIN_VERTICAL 5
MathPrintout::MathPrintout(wxString title) : wxPrintout(title)
{
m_numberOfPages = 0;
m_tree = NULL;
}
MathPrintout::~MathPrintout()
{
DestroyTree();
}
void MathPrintout::SetData(MathCell* tree)
{
m_tree = tree;
if (m_tree != NULL)
m_tree->BreakPage(true);
}
bool MathPrintout::HasPage(int num)
{
if (num > 0 && num <= m_numberOfPages)
return true;
return false;
}
bool MathPrintout::OnPrintPage(int num)
{
double screenScaleX, screenScaleY;
double ppiScale;
MathCell* tmp = m_tree;
wxDC* dc = GetDC();
int marginX, marginY;
GetPageMargins(&marginX, &marginY);
ppiScale = GetPPIScale();
GetScreenScale(&screenScaleX, &screenScaleY);
dc->SetUserScale(screenScaleX, screenScaleY);
// Go to current page
tmp = m_pages[num - 1];
// Print page
if (tmp != NULL)
{
wxPoint point;
point.x = marginX;
point.y = marginY + tmp->GetMaxCenter() + GetHeaderHeight();
wxConfigBase* config = wxConfig::Get();
int fontsize = 12;
int drop = tmp->GetMaxDrop();
config->Read(wxT("fontsize"), &fontsize);
PrintHeader(num, dc, ppiScale);
CellParser parser(*dc, ppiScale);
while (tmp != NULL)
{
if (!tmp->m_isBroken)
{
tmp->Draw(parser, point, fontsize, false);
if (tmp->m_nextToDraw != NULL && tmp->m_nextToDraw->BreakLineHere())
{
point.x = marginX;
point.y += drop + tmp->m_nextToDraw->GetMaxCenter();
if (tmp->m_bigSkip)
point.y += SCALE_PX(5, ppiScale);
drop = tmp->m_nextToDraw->GetMaxDrop();
}
else
point.x += (tmp->GetWidth() + SCALE_PX(2, ppiScale));
}
else
{
if (tmp->m_nextToDraw != NULL && tmp->m_nextToDraw->BreakLineHere())
{
point.x = marginX;
point.y += drop + tmp->m_nextToDraw->GetMaxCenter();
if (tmp->m_bigSkip)
point.y += SCALE_PX(5, ppiScale);
drop = tmp->m_nextToDraw->GetMaxDrop();
}
}
tmp = tmp->m_nextToDraw;
if (tmp == NULL || tmp->BreakPageHere())
break;
}
return true;
}
return false;
}
bool MathPrintout::OnBeginDocument(int startPage, int endPage)
{
if (!wxPrintout::OnBeginDocument(startPage, endPage))
return false;
return true;
}
void MathPrintout::BreakLines()
{
int pageWidth, pageHeight;
int marginX, marginY;
double scale = GetPPIScale();
GetPageSizePixels(&pageWidth, &pageHeight);
GetPageMargins(&marginX, &marginY);
int fullWidth = pageWidth - marginX;
int currentWidth = marginX;
MathCell* tmp = m_tree;
while (tmp != NULL)
{
if (!tmp->m_isBroken)
{
tmp->BreakLine(false);
tmp->ResetData();
if (tmp->BreakLineHere() ||
(currentWidth + tmp->GetWidth() >= fullWidth))
{
currentWidth = marginX + tmp->GetWidth();
tmp->BreakLine(true);
}
else
currentWidth += (tmp->GetWidth() + SCALE_PX(2, scale));
}
tmp = tmp->m_nextToDraw;
}
}
void MathPrintout::BreakPages()
{
if (m_tree == NULL)
return ;
int pageWidth, pageHeight;
int marginX, marginY;
int headerHeight = GetHeaderHeight();
double scale = GetPPIScale();
GetPageMargins(&marginX, &marginY);
GetPageSizePixels(&pageWidth, &pageHeight);
int currentHeight = marginY;
int skip = SCALE_PX(5, scale);
MathCell* tmp = m_tree;
m_pages.push_back(tmp);
m_numberOfPages = 1;
while (tmp != NULL)
{
if (!tmp->m_isBroken)
{
tmp->BreakPage(false);
if (tmp->BreakLineHere())
{
if (currentHeight + tmp->GetMaxHeight() + skip >= pageHeight - marginY)
{
currentHeight = marginY + tmp->GetMaxHeight() + headerHeight;
tmp->BreakPage(true);
m_pages.push_back(tmp);
m_numberOfPages++;
}
else
currentHeight += tmp->GetMaxHeight() + skip;
if (tmp->m_bigSkip)
skip = SCALE_PX(5, scale);
else
skip = 0;
}
}
tmp = tmp->m_nextToDraw;
}
}
void MathPrintout::SetupData()
{
RecalculateWidths();
RecalculateSize();
BreakUpCells();
BreakLines();
BreakPages();
}
void MathPrintout::GetPageInfo(int* minPage, int* maxPage,
int* fromPage, int* toPage)
{
*minPage = 1;
*maxPage = 9999;
*fromPage = 1;
*toPage = 9999;
}
void MathPrintout::OnPreparePrinting()
{
SetupData();
}
void MathPrintout::GetPageMargins(int* horizontal, int* vertical)
{
double scale = GetPPIScale();
*horizontal = (int)(SCALE_PX(PRINT_MARGIN_HORIZONTAL, scale) * 10);
*vertical = (int)(SCALE_PX(PRINT_MARGIN_VERTICAL, scale) * 10);
}
int MathPrintout::GetHeaderHeight()
{
wxDC *dc = GetDC();
double ppiScale = GetPPIScale();
int width, height;
dc->SetFont(wxFont((int)((double)10*ppiScale + 0.5),
wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("Courier")));
dc->GetTextExtent(wxT("wxMaxima session"), &width, &height);
return height + SCALE_PX(12, ppiScale);
}
void MathPrintout::PrintHeader(int pageNum, wxDC* dc, double scale)
{
int marginX, marginY;
int pageWidth, pageHeight;
int width, height;
int pages_width, pages_height;
GetPageMargins(&marginX, &marginY);
GetPageSizePixels(&pageWidth, &pageHeight);
double ppiScale = GetPPIScale();
double screenScaleX, screenScaleY;
GetScreenScale(&screenScaleX, &screenScaleY);
scale = ppiScale * screenScaleX;
dc->SetTextForeground(wxColour(wxT("grey")));
dc->SetPen(wxPen(wxT("light grey"), 1, wxSOLID));
dc->SetFont(wxFont(MAX((int)(10.0*ppiScale + 0.5), 1),
wxMODERN, wxNORMAL, wxNORMAL));
dc->GetTextExtent(wxT("wxMaxima session"), &width, &height);
wxString page = wxString::Format(wxT("%d / %d"), pageNum, m_numberOfPages);
dc->GetTextExtent(page, &pages_width, &pages_height);
dc->SetFont(wxFont(MAX((int)(10.0*scale + 0.5), 1),
wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("Courier")));
dc->DrawText(wxT("wxMaxima session"), marginX, marginY);
dc->DrawText(page, pageWidth - pages_width - marginX, marginY);
dc->DrawLine(marginX, marginY + height + SCALE_PX(3, scale),
pageWidth - marginX, marginY + height + SCALE_PX(3, scale));
dc->SetTextForeground(wxColour(wxT("black")));
dc->SetPen(wxPen(wxT("black"), 1, wxSOLID));
}
void MathPrintout::RecalculateSize()
{
wxConfig *config = (wxConfig *)wxConfig::Get();
int fontsize = 12;
config->Read(wxT("fontSize"), &fontsize);
MathCell* tmp = m_tree;
double scale = GetPPIScale();
wxDC *dc = GetDC();
CellParser parser(*dc, scale);
while (tmp != NULL)
{
tmp->RecalculateSize(parser, fontsize, false);
tmp = tmp->m_nextToDraw;
}
}
void MathPrintout::RecalculateWidths()
{
wxConfig *config = (wxConfig *)wxConfig::Get();
int fontsize = 12;
config->Read(wxT("fontSize"), &fontsize);
MathCell* tmp = m_tree;
double scale = GetPPIScale();
wxDC *dc = GetDC();
CellParser parser(*dc, scale);
while (tmp != NULL)
{
tmp->RecalculateWidths(parser, fontsize, false);
tmp = tmp->m_next;
}
}
double MathPrintout::GetPPIScale()
{
int ppiScreenX, ppiScreenY;
int ppiPrinterX, ppiPrinterY;
GetPPIScreen(&ppiScreenX, &ppiScreenY);
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
return ((double)ppiPrinterX) / ((double)ppiScreenX);
}
void MathPrintout::GetScreenScale(double *scaleX, double *scaleY)
{
int pageSizeX, pageSizeY;
int previewSizeX, previewSizeY;
wxDC *dc = GetDC();
GetPageSizePixels(&pageSizeX, &pageSizeY);
dc->GetSize(&previewSizeX, &previewSizeY);
*scaleX = ((double)previewSizeX) / ((double)pageSizeX);
*scaleY = ((double)previewSizeY) / ((double)pageSizeY);
}
void MathPrintout::DestroyTree()
{
if (m_tree != NULL)
{
DestroyTree(m_tree);
m_tree = NULL;
}
}
void MathPrintout::DestroyTree(MathCell* tmp)
{
MathCell* tmp1;
while (tmp != NULL)
{
tmp1 = tmp;
tmp = tmp->m_next;
tmp1->Destroy();
delete tmp1;
}
}
void MathPrintout::BreakUpCells()
{
MathCell *tmp = m_tree;
int pageWidth, pageHeight, marginX, marginY;
wxConfig *config = (wxConfig *)wxConfig::Get();
int fontsize = 12;
config->Read(wxT("fontSize"), &fontsize);
double scale = GetPPIScale();
wxDC *dc = GetDC();
CellParser parser(*dc, scale);
GetPageSizePixels(&pageWidth, &pageHeight);
GetPageMargins(&marginX, &marginY);
int fullWidth = pageWidth - marginX;
while (tmp != NULL)
{
if (tmp->GetWidth() > fullWidth)
{
if (tmp->BreakUp())
tmp->RecalculateWidths(parser, fontsize, false);
}
tmp = tmp->m_nextToDraw;
}
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1