#include "StdAfx.h"
#include "./printhelper.h"
#include "math.h"
#include <string>
static const unsigned int GRID_WIDTH[] =
{
13,
22,
22,
29,
29,
20,
25,
32,
23,
23,
35,
20,
32,
32,
32
};
static const unsigned int A3_PAPER_WIDTH = 420;
CPrintHelper::CPrintHelper(CDC * pDc, bool bHeader, bool bFooter) : _pDc(pDc)
, _bHeader(bHeader)
, _bFooter(bFooter)
{
_dpi = _pDc->GetDeviceCaps(LOGPIXELSX); // UNDONE: GetDeviceCaps(HORZRES)/GetDeviceCaps(HORZSIZE)/25.4;
// 紙寬(單位:mm)
float pWidth = (float)ceil(25.4 * GetPaperWidth() / _dpi);
_ratio = pWidth/A3_PAPER_WIDTH;
// 要求左留白15mm,右留白16mm
_leftMargin = mm2pixel(15 * _ratio - GetPaperLMargin());
_topMargin = _bottomMargin = mm2pixel(float(15 * _ratio- GetPaperTMargin()) );
_rightMargin = mm2pixel(float(16 * _ratio - GetPaperLMargin()) );
_titleHeight = mm2pixel(20 * _ratio);
_footerHeight = mm2pixel(5 * _ratio);
_fontHeight = mm2pixel((float)3.5 * _ratio);
_LineSpacing = mm2pixel(1.5f * _ratio);
_gridMargin = mm2pixel((float)0.5 * _ratio);
_gridNUmber = sizeof(CSV_ATTRI) / sizeof(char *);
_headerHeight = 3 * GetLinePixelHeight(); //屬性打印的表頭行和表之間空開一行
_pFont = new CFont();
_pFont->CreateFont(_fontHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, "MS ゴシック");
_pDc->SelectObject(_pFont);
_pPen = new CPen;
_pPen->CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
_pDc->SelectObject(_pPen);
TEXTMETRIC TextM;
pDc->GetTextMetrics(&TextM);
_CharWidth = pixel2mm(TextM.tmAveCharWidth);
return;
}
CPrintHelper::~CPrintHelper() {
_pFont->DeleteObject();
_pPen->DeleteObject();
delete _pFont;
delete _pPen;
}
//頁眉的打印
void CPrintHelper::PrintHeader(CString title, CString sYear,
CString sImage, CString eYear, CString eImage)
{
if ( ! _bHeader )
return;
CTime t = CTime::GetCurrentTime();
CString date = "印刷日時: " + t.Format("%Y/%m/%d %H:%M:%S");
//打印表頭標題 如:属性情報の印刷 -秋田地區 平面直角坐標係 第10係
//打印時間,如:2006/01/01/ 10:10:00
_pDc->TextOut(_leftMargin, _topMargin, title + " " + date);
//打印 撮影年和画像
_pDc->TextOut(_leftMargin, _topMargin + GetLinePixelHeight(),
"期首画像の撮影年:" + sYear + " 期首画像:" + sImage + " "
"期末画像の撮影年:" + eYear + " 期末画像:" + eImage);
}
//MsFlexGrid頭
void CPrintHelper::PrintGridHeader()
{
int x = _leftMargin + 1;
int y = _topMargin + GetHeaderHeight();
PrintLineGrid(y);
CRect r;
for(int i = 0; i <= sizeof(CSV_ATTRI) / sizeof(char *); ++i) {
r.SetRect(x, y, x + mm2pixel(float(GRID_WIDTH[i]) * _ratio), y + GetLinePixelHeight());
_pDc->DrawText(CSV_ATTRI[i], &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
x += mm2pixel(float(GRID_WIDTH[i])* _ratio) ;
}
};
//打印頁脚的内容:第 X 頁
void CPrintHelper::PrintFooter(int currentPage) //, int totalPage)
{
if ( ! _bFooter )
return;
CString tmp;
//tmp.Format("第 %d 頁/全 %d 頁", currentPage, totalPage);
tmp.Format("第 %d 頁", currentPage);
int x = int( GetPagePixelWidth() - 0.5 * tmp.GetLength() * GetFontPixelHeight());
int y = GetPagePixelHeight() - _bottomMargin - GetFooterHeight();
_pDc->TextOut(x/2, y, tmp);
};
int CPrintHelper::PrintPage(CMsflexgrid1 &grid, int rowPos)
{
// 打印行位置、一頁的行數量
int printLinePos = 1;
while(rowPos < grid.get_Rows() && printLinePos < LinesPerPage())
{
if ( ! PrintLineText(grid, rowPos, printLinePos) )
break;
rowPos++;
}
return rowPos;
}
// 打印一條row數據需要多少行
int CPrintHelper::GetPrintLineNumber(CMsflexgrid1 &grid, int rowPos)
{
int maxHeight = 1;
CString cell;
for(int i = 1; i < grid.GetCols(); i++)
{
cell = grid.GetTextMatrix(rowPos, i);
float charsInCell = ((GRID_WIDTH[i] * _ratio - pixel2mm(_gridMargin * 2)) / _CharWidth);
int height = (int) ceil( cell.GetLength() / charsInCell);
if ( maxHeight < height )
maxHeight = height;
}
return maxHeight;
}
// 畫一行格子( 格子大小取自GRID_WIDTH[] )
void CPrintHelper::PrintLineGrid(int top, int height) {
int buttom = top + height * GetLinePixelHeight();
// 最左邊的竪綫
_pDc->MoveTo(_leftMargin, top);
_pDc->LineTo(_leftMargin, buttom);
// 畫各個格子的右邊竪綫
int x = 0;
for(int i = 0; i < _gridNUmber; ++i) {
x += GRID_WIDTH[i];
_pDc->MoveTo(_leftMargin + mm2pixel(x * _ratio), top);
_pDc->LineTo(_leftMargin + mm2pixel(x * _ratio), buttom);
}
// 畫兩根橫綫
_pDc->MoveTo(_leftMargin, top);
_pDc->LineTo(_leftMargin + mm2pixel(x * _ratio), top);
_pDc->MoveTo(_leftMargin, buttom);
_pDc->LineTo(_leftMargin + mm2pixel(x * _ratio), buttom);
return;
}
// 打印一行數據
bool CPrintHelper::PrintLineText(CMsflexgrid1 &grid, int row, int& linePosition) {
int x = _leftMargin + 1;
int y = _topMargin + linePosition * GetLinePixelHeight();
y += GetHeaderHeight();
// 當前row需要打印多少行
int rowHeight = GetPrintLineNumber(grid, row);
if ( linePosition + rowHeight > LinesPerPage() )
return false;
PrintLineGrid(y, rowHeight);
CRect r;
CString cellString;
CString currString;
for(int line = 0; line < rowHeight; line++) // 對各行
{
int x = 0;
r.top = y;
r.bottom = y + GetLinePixelHeight();
for(int i = 0; i < _gridNUmber; i++) // 對各個格子
{
r.left = _leftMargin + mm2pixel(x * _ratio) + _gridMargin;
x += GRID_WIDTH[i];
r.right = _leftMargin + mm2pixel(x * _ratio) - _gridMargin;
cellString = grid.GetTextMatrix(row, i); // 獲得文字
int charsInCell = (int) floor((GRID_WIDTH[i] * _ratio - pixel2mm(_gridMargin * 2)) / _CharWidth); // 格子一行幾個字
currString = GetSubString( cellString, line * charsInCell, charsInCell ); // cellString.Mid(line * charsInCell, charsInCell); // 當前打印的文字串
if ( ! currString.IsEmpty() ) {
_pDc->DrawText(currString, &r, (i == 0 ? DT_CENTER : DT_LEFT) | DT_VCENTER | DT_SINGLELINE);
}
}
y += GetLinePixelHeight();
}
linePosition += rowHeight;
return true;
}
CString CPrintHelper::GetSubString( const CString s, int iStartPos, int iLen ) const{
CString sRet = "";
int len = s.GetLength();
int iCutLen = 0;
int i = 0;
char c;
if ( iStartPos < len ){
// get real cutting start pos
int iNextPos = 0;
while( iNextPos < iStartPos ){
c = s[iNextPos];
if ( c < 0 ){
iNextPos += 2;
}
else{
iNextPos ++;
}
}
if ( iNextPos > iStartPos ){
// return to start pos of 2 bytes char
i = iStartPos - 1;
}
else{
i = iStartPos;
}
while( i < len && iCutLen < iLen ){
c = s[i];
if ( c > 0 ){
sRet += CString( c );
i++;
iCutLen ++;
}
else{
// 2Bytes Char
iCutLen +=2;
if ( iCutLen <= iLen ){
sRet += s.Mid( i, 2 );
}
i+= 2;
}
}
}
return( sRet );
}