mirror of
https://github.com/Rayerd/dfl.git
synced 2025-04-26 04:59:55 +03:00
std.printing supports now different paper orientations for each page
This commit is contained in:
parent
abc727449b
commit
f3db485ee6
1 changed files with 221 additions and 144 deletions
|
@ -29,10 +29,12 @@ private import core.sys.windows.commdlg;
|
||||||
private import core.sys.windows.windows;
|
private import core.sys.windows.windows;
|
||||||
|
|
||||||
private import std.conv;
|
private import std.conv;
|
||||||
|
private import std.range;
|
||||||
|
private import std.algorithm;
|
||||||
|
|
||||||
debug
|
debug
|
||||||
{
|
{
|
||||||
private import std.stdio;
|
private import std.stdio : writeln, stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -521,27 +523,34 @@ class PrintDocument
|
||||||
if (printArgs.cancel)
|
if (printArgs.cancel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Graphics deviceScreen = new Graphics(hDC, false);
|
||||||
|
|
||||||
PrintPageEventArgs printPageArgs;
|
PrintPageEventArgs printPageArgs;
|
||||||
auto walker = new PrintRangeWalker(this.printerSettings.printRange.ranges);
|
auto walker = new PrintRangeWalker(this.printerSettings.printRange.ranges);
|
||||||
foreach (int pageCounter; walker)
|
foreach (int pageCounter; walker)
|
||||||
{
|
{
|
||||||
Graphics originGraphics = new Graphics(printArgs.hDC, false);
|
|
||||||
|
|
||||||
PageSettings newPageSettings = this.printerSettings.defaultPageSettings.clone();
|
PageSettings newPageSettings = this.printerSettings.defaultPageSettings.clone();
|
||||||
QueryPageSettingsEventArgs queryPageSettingsArgs = new QueryPageSettingsEventArgs(printArgs.hDC, newPageSettings, pageCounter);
|
QueryPageSettingsEventArgs queryPageSettingsArgs = new QueryPageSettingsEventArgs(hDC, newPageSettings, pageCounter);
|
||||||
onQueryPageSettings(queryPageSettingsArgs); // Be modified pageSettings of current page by user.
|
onQueryPageSettings(queryPageSettingsArgs); // Be modified pageSettings of current page by user.
|
||||||
|
|
||||||
PageSettings ps = queryPageSettingsArgs.pageSettings;
|
PageSettings ps = queryPageSettingsArgs.pageSettings; // Short name.
|
||||||
|
|
||||||
|
// Change page orientation.
|
||||||
|
DEVMODE devMode;
|
||||||
|
devMode.dmSize = DEVMODE.sizeof;
|
||||||
|
devMode.dmFields |= DM_ORIENTATION;
|
||||||
|
devMode.dmOrientation |= ps.landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
|
||||||
|
ResetDC(hDC, &devMode);
|
||||||
|
|
||||||
Rect marginBounds = ps.bounds; // 1/100 inch unit.
|
Rect marginBounds = ps.bounds; // 1/100 inch unit.
|
||||||
Rect pageBounds = Rect(0, 0, ps.paperSize.width, ps.paperSize.height); // 1/100 inch unit.
|
Rect pageBounds = Rect(0, 0, ps.paperSize.width, ps.paperSize.height); // 1/100 inch unit.
|
||||||
printPageArgs = new PrintPageEventArgs(originGraphics, marginBounds, pageBounds, ps, pageCounter);
|
printPageArgs = new PrintPageEventArgs(deviceScreen, marginBounds, pageBounds, ps, pageCounter);
|
||||||
|
|
||||||
printPageArgs.graphics = printController.onStartPage(this, printPageArgs); // Call StartPage() API
|
printPageArgs.graphics = printController.onStartPage(this, printPageArgs); // Call StartPage() API
|
||||||
|
|
||||||
if(!printPageArgs.cancel)
|
if(!printPageArgs.cancel)
|
||||||
this.onPrintPage(printPageArgs);
|
this.onPrintPage(printPageArgs);
|
||||||
|
|
||||||
printPageArgs.graphics = originGraphics;
|
printPageArgs.graphics = deviceScreen;
|
||||||
|
|
||||||
printController.onEndPage(this, printPageArgs); // Call EndPage() API
|
printController.onEndPage(this, printPageArgs); // Call EndPage() API
|
||||||
if (printPageArgs.cancel)
|
if (printPageArgs.cancel)
|
||||||
|
@ -2031,7 +2040,7 @@ class PrintPreviewControl : Control
|
||||||
private int _rows; ///
|
private int _rows; ///
|
||||||
private int _startPage; ///
|
private int _startPage; ///
|
||||||
private bool _autoZoom; ///
|
private bool _autoZoom; ///
|
||||||
private MemoryGraphics _background; ///
|
private MemoryGraphics _offscreen; ///
|
||||||
|
|
||||||
///
|
///
|
||||||
this(PrintDocument doc)
|
this(PrintDocument doc)
|
||||||
|
@ -2049,7 +2058,7 @@ class PrintPreviewControl : Control
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void document(PrintDocument doc)
|
void document(PrintDocument doc) // setter
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(doc);
|
assert(doc);
|
||||||
|
@ -2059,51 +2068,51 @@ class PrintPreviewControl : Control
|
||||||
_document = doc;
|
_document = doc;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
PrintDocument document()
|
PrintDocument document() // getter
|
||||||
{
|
{
|
||||||
return _document;
|
return _document;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void autoZoom(bool b)
|
void autoZoom(bool b) // setter
|
||||||
{
|
{
|
||||||
_autoZoom = b;
|
_autoZoom = b;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
bool autoZoom() const
|
bool autoZoom() const // getter
|
||||||
{
|
{
|
||||||
return _autoZoom;
|
return _autoZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void columns(int col)
|
void columns(int col) // setter
|
||||||
{
|
{
|
||||||
_columns = col;
|
_columns = col;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
int columns() const
|
int columns() const // getter
|
||||||
{
|
{
|
||||||
return _columns;
|
return _columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void rows(int row)
|
void rows(int row) // setter
|
||||||
{
|
{
|
||||||
_rows = row;
|
_rows = row;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
int rows() const
|
int rows() const // getter
|
||||||
{
|
{
|
||||||
return _rows;
|
return _rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void startPage(int page)
|
void startPage(int page) // setter
|
||||||
{
|
{
|
||||||
_startPage = page;
|
_startPage = page;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
int startPage() const
|
int startPage() const // getter
|
||||||
{
|
{
|
||||||
return _startPage;
|
return _startPage;
|
||||||
}
|
}
|
||||||
|
@ -2145,18 +2154,19 @@ class PrintPreviewControl : Control
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect screenRect = Rect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
Rect screenRect = Rect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
||||||
_background = new MemoryGraphics(screenRect.width, screenRect.height);
|
_offscreen = new MemoryGraphics(screenRect.width, screenRect.height);
|
||||||
_background.fillRectangle(new SolidBrush(Color.gray), screenRect);
|
_offscreen.fillRectangle(new SolidBrush(Color.gray), screenRect);
|
||||||
|
|
||||||
// Reset here, because print range is always all pages on preview print.
|
// Reset here, because print range is always all pages on preview print.
|
||||||
_document.printerSettings.printRange.reset();
|
_document.printerSettings.printRange.reset();
|
||||||
|
|
||||||
PrintController oldPrintController = _document.printController;
|
PrintController oldPrintController = _document.printController;
|
||||||
_document.printController = new PreviewPrintController(this); // TODO: Cross reference.
|
_document.printController = new PreviewPrintController(this); // TODO: Cross reference.
|
||||||
_document.print(_background.handle);
|
_document.print(_offscreen.handle);
|
||||||
_document.printController = oldPrintController;
|
_document.printController = oldPrintController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
protected override void onHandleCreated(EventArgs e)
|
protected override void onHandleCreated(EventArgs e)
|
||||||
{
|
{
|
||||||
super.onHandleCreated(e);
|
super.onHandleCreated(e);
|
||||||
|
@ -2193,48 +2203,48 @@ class PrintPreviewControl : Control
|
||||||
mouseDown(this, e);
|
mouseDown(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LEFT_MARIGIN = 20; // Dots
|
enum LEFT_MARIGIN = 20; // pixels
|
||||||
enum RIGHT_MARGIN = 20; // Dots
|
enum RIGHT_MARGIN = 20; // pixels
|
||||||
enum TOP_MARGIN = 20; // Dots
|
enum TOP_MARGIN = 20; // pixels
|
||||||
enum BOTTOM_MARGIN = 20; // Dots
|
enum BOTTOM_MARGIN = 20; // pixels
|
||||||
enum HORIZONTAL_SPAN = 20; // Dots
|
enum HORIZONTAL_SPAN = 20; // pixels
|
||||||
enum VERTICAL_SPAN = 20; // Dots
|
enum VERTICAL_SPAN = 20; // pixels
|
||||||
|
|
||||||
///
|
///
|
||||||
protected override void onPaint(PaintEventArgs e)
|
protected override void onPaint(PaintEventArgs e)
|
||||||
{
|
{
|
||||||
super.onPaint(e);
|
super.onPaint(e);
|
||||||
if (_background)
|
if (_offscreen)
|
||||||
{
|
{
|
||||||
if (this.autoZoom)
|
if (this.autoZoom)
|
||||||
{
|
{
|
||||||
const Rect screenRect = Rect(0, 0, _background.width, _background.height);
|
const Rect offscreenRect = Rect(0, 0, _offscreen.width, _offscreen.height);
|
||||||
uint h0 = height;
|
uint onScreenHeight = this.height;
|
||||||
uint w0 = screenRect.width * height / screenRect.height;
|
uint onscreenWidth = offscreenRect.width * this.height / offscreenRect.height;
|
||||||
if (w0 >= width)
|
if (onscreenWidth >= this.width)
|
||||||
{
|
{
|
||||||
w0 = width;
|
onscreenWidth = this.width;
|
||||||
h0 = screenRect.height * width / screenRect.width;
|
onScreenHeight = offscreenRect.height * this.width / offscreenRect.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetStretchBltMode(_background.handle, STRETCH_DELETESCANS); // SRC
|
SetStretchBltMode(_offscreen.handle, STRETCH_DELETESCANS); // SRC
|
||||||
StretchBlt(
|
StretchBlt(
|
||||||
e.graphics.handle, // DST
|
e.graphics.handle, // DST
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
w0,
|
onscreenWidth,
|
||||||
h0,
|
onScreenHeight,
|
||||||
_background.handle, // SRC
|
_offscreen.handle, // SRC
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
screenRect.width,
|
offscreenRect.width,
|
||||||
screenRect.height,
|
offscreenRect.height,
|
||||||
SRCCOPY
|
SRCCOPY
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_background.copyTo(e.graphics.handle, 0, 0, _background.width, _background.height, 0, 0, SRCCOPY);
|
_offscreen.copyTo(e.graphics, 0, 0, _offscreen.width, _offscreen.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2345,8 +2355,8 @@ class PrintPreviewDialog : Form
|
||||||
}
|
}
|
||||||
else if (e.button is _button3)
|
else if (e.button is _button3)
|
||||||
{
|
{
|
||||||
_previewControl.rows = 2;
|
_previewControl.rows = 1;
|
||||||
_previewControl.columns = 1;
|
_previewControl.columns = 2;
|
||||||
_previewControl.invalidatePreview();
|
_previewControl.invalidatePreview();
|
||||||
_previewControl.invalidate();
|
_previewControl.invalidate();
|
||||||
}
|
}
|
||||||
|
@ -2447,6 +2457,11 @@ class PrintPreviewDialog : Form
|
||||||
{
|
{
|
||||||
int oldPage = _previewControl.startPage;
|
int oldPage = _previewControl.startPage;
|
||||||
int newPage = _previewControl.startPage + _previewControl.rows * _previewControl.columns;
|
int newPage = _previewControl.startPage + _previewControl.rows * _previewControl.columns;
|
||||||
|
int lastPage = cast(int)((new PrintRangeWalker(_previewControl.document.printerSettings.printRange.ranges)).count) - 1;
|
||||||
|
if (newPage > lastPage)
|
||||||
|
newPage = lastPage;
|
||||||
|
if (newPage < 0)
|
||||||
|
newPage = 0;
|
||||||
_previewControl.startPage = newPage;
|
_previewControl.startPage = newPage;
|
||||||
_fromPage.text = to!string(_previewControl.startPage + 1);
|
_fromPage.text = to!string(_previewControl.startPage + 1);
|
||||||
if (oldPage != newPage)
|
if (oldPage != newPage)
|
||||||
|
@ -2471,7 +2486,7 @@ class PrintPreviewDialog : Form
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void document(PrintDocument doc)
|
void document(PrintDocument doc) // setter
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(doc);
|
assert(doc);
|
||||||
|
@ -2482,7 +2497,7 @@ class PrintPreviewDialog : Form
|
||||||
_previewControl.document = doc;
|
_previewControl.document = doc;
|
||||||
}
|
}
|
||||||
/// ditto
|
/// ditto
|
||||||
PrintDocument document()
|
PrintDocument document() // getter
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(_previewControl);
|
assert(_previewControl);
|
||||||
|
@ -2503,8 +2518,20 @@ class PrintPreviewDialog : Form
|
||||||
///
|
///
|
||||||
class PreviewPrintController : PrintController
|
class PreviewPrintController : PrintController
|
||||||
{
|
{
|
||||||
|
///
|
||||||
|
private class Page
|
||||||
|
{
|
||||||
|
this(MemoryGraphics g, PageSettings s)
|
||||||
|
{
|
||||||
|
graphics = g;
|
||||||
|
settings = s;
|
||||||
|
}
|
||||||
|
MemoryGraphics graphics;
|
||||||
|
PageSettings settings;
|
||||||
|
}
|
||||||
|
|
||||||
private PrintPreviewControl _previewControl; ///
|
private PrintPreviewControl _previewControl; ///
|
||||||
private MemoryGraphics _pageGraphics; ///
|
private Page[] _pages; ///
|
||||||
|
|
||||||
///
|
///
|
||||||
this(PrintPreviewControl previewControl)
|
this(PrintPreviewControl previewControl)
|
||||||
|
@ -2520,115 +2547,165 @@ class PreviewPrintController : PrintController
|
||||||
///
|
///
|
||||||
override void onStartPrint(PrintDocument document, PrintEventArgs e)
|
override void onStartPrint(PrintDocument document, PrintEventArgs e)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
_pages.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create screen for single page and draw the paper looks form.
|
||||||
|
override Graphics onStartPage(PrintDocument document, PrintPageEventArgs e)
|
||||||
|
{
|
||||||
|
Rect paperRect = _paperRectFrom(e.pageSettings);
|
||||||
|
auto pageGraphcis = new MemoryGraphics(paperRect.width, paperRect.height, e.graphics);
|
||||||
|
pageGraphcis.fillRectangle(Color.white, paperRect); // Draw the form of paper.
|
||||||
|
pageGraphcis.drawRectangle(new Pen(Color.black), paperRect); // Draw the border of paper.
|
||||||
|
_pages ~= new Page(pageGraphcis, e.pageSettings);
|
||||||
|
return pageGraphcis;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
override void onEndPage(PrintDocument document, PrintPageEventArgs e)
|
||||||
|
{
|
||||||
|
Graphics pageGraphics = _pages[e.currentPage - 1].graphics;
|
||||||
|
pageGraphics.pageUnit = GraphicsUnit.DISPLAY; // Initialize graphics unit that is changed in user side.
|
||||||
|
Font font = new Font("MS Gothic", 100/+pt+/ * e.pageSettings.printerResolution.y / 72); // 1 point == 1/72 inches
|
||||||
|
_drawPageNumber(pageGraphics, e.currentPage, font); // Draw the current page number.
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
override void onEndPrint(PrintDocument document, PrintEventArgs e)
|
override void onEndPrint(PrintDocument document, PrintEventArgs e)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
auto layoutHelper = new PageLayoutHelper(_previewControl.columns, _previewControl.rows);
|
||||||
|
|
||||||
|
const Rect screenRect = {
|
||||||
|
const int deviceWidth = GetSystemMetrics(SM_CXSCREEN); // pixel unit.
|
||||||
|
const int deviceHeight = GetSystemMetrics(SM_CYSCREEN); // pixel unit.
|
||||||
|
return Rect(0, 0, deviceWidth, deviceHeight); // TODO: Gets MemoryGraphics size as the background DC.
|
||||||
|
}();
|
||||||
|
|
||||||
|
enum LEFT_AND_RIGHT_MARGIN = PrintPreviewControl.LEFT_MARIGIN + PrintPreviewControl.RIGHT_MARGIN;
|
||||||
|
enum TOP_AND_BOTTOM_MARGIN = PrintPreviewControl.TOP_MARGIN + PrintPreviewControl.BOTTOM_MARGIN;
|
||||||
|
enum HORIZONTAL_SPAN = PrintPreviewControl.HORIZONTAL_SPAN;
|
||||||
|
enum VERTICAL_SPAN = PrintPreviewControl.VERTICAL_SPAN;
|
||||||
|
|
||||||
|
Page[] targetPageList = _pages;
|
||||||
|
if (_previewControl.startPage > 0)
|
||||||
|
targetPageList = targetPageList.drop(_previewControl.startPage);
|
||||||
|
targetPageList = targetPageList.take(_previewControl.rows * _previewControl.columns);
|
||||||
|
assert(targetPageList.length > 0, "targetPageList is empty.");
|
||||||
|
|
||||||
|
int totalPageWidth = targetPageList
|
||||||
|
.map!(p => _paperRectFrom(p.settings).width) // [w1,w2,w3,w4]
|
||||||
|
.chunks(_previewControl.columns) // [w1,w2],[w3,w4]
|
||||||
|
.map!(elem => elem.sum) // [w1+w2],[w3+w4]
|
||||||
|
.maxElement; // w1+w2 if w1+w2 > w3+w4
|
||||||
|
|
||||||
|
int totalPageHeight = targetPageList
|
||||||
|
.map!(p => _paperRectFrom(p.settings).height) // [h1,h2,h3,h4]
|
||||||
|
.chunks(_previewControl.columns) // [h1,h2],[h3,h4]
|
||||||
|
.map!(elem => elem.maxElement) // [h1,h4] if h1 > h2 and h3 < h4
|
||||||
|
.sum; // h1+h4
|
||||||
|
|
||||||
|
// NOTE: TOP_AND_BOTTOM_MARGIN and the others are scales on video screen world.
|
||||||
|
double ratio = cast(double)(screenRect.height - TOP_AND_BOTTOM_MARGIN - VERTICAL_SPAN * (_previewControl.rows - 1)) / totalPageHeight;
|
||||||
|
if (screenRect.width < totalPageWidth * ratio)
|
||||||
|
{
|
||||||
|
ratio = cast(double)(screenRect.width - LEFT_AND_RIGHT_MARGIN - HORIZONTAL_SPAN * (_previewControl.columns - 1)) / totalPageWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Page page; targetPageList)
|
||||||
|
{
|
||||||
|
const Point pos = layoutHelper.position();
|
||||||
|
const Rect paperRect = _paperRectFrom(page.settings);
|
||||||
|
const uint offScreenWidth = cast(uint)(paperRect.width * ratio);
|
||||||
|
const uint offScreenHeight = cast(uint)(paperRect.height * ratio);
|
||||||
|
Graphics pageGraphics = page.graphics;
|
||||||
|
SetStretchBltMode(pageGraphics.handle, STRETCH_DELETESCANS); // SRC
|
||||||
|
StretchBlt(
|
||||||
|
e.hDC, // DST
|
||||||
|
pos.x,
|
||||||
|
pos.y,
|
||||||
|
offScreenWidth,
|
||||||
|
offScreenHeight,
|
||||||
|
pageGraphics.handle, // SRC
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
paperRect.width * 100 / DEFAULT_PRINTER_RESOLUTION_X,
|
||||||
|
paperRect.height * 100 / DEFAULT_PRINTER_RESOLUTION_Y,
|
||||||
|
SRCCOPY
|
||||||
|
);
|
||||||
|
pageGraphics.dispose(); // Created in onStartPage().
|
||||||
|
|
||||||
|
layoutHelper.appendPageSize(offScreenWidth, offScreenHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create and draw the back screen.
|
///
|
||||||
override Graphics onStartPage(PrintDocument document, PrintPageEventArgs e)
|
private static void _drawPageNumber(Graphics graphics, int currentPage, Font font)
|
||||||
{
|
{
|
||||||
Rect paperRect = _toRect(document.printerSettings.defaultPageSettings);
|
const string currentPageString = to!string(currentPage);
|
||||||
_pageGraphics = {
|
graphics.drawText(currentPageString, font, Color.white, Rect(20, 20, 1000, 1000));
|
||||||
// Be dispose() called in onEntPage().
|
graphics.drawText(currentPageString, font, Color.black, Rect(0, 0, 1000, 1000));
|
||||||
if (e.pageBounds.width <= e.pageBounds.height)
|
|
||||||
return new MemoryGraphics(paperRect.width, paperRect.height, e.graphics.handle);
|
|
||||||
else
|
|
||||||
return new MemoryGraphics(paperRect.height, paperRect.width, e.graphics.handle); // TODO: Implement correctly.
|
|
||||||
}();
|
|
||||||
// Draw the form of paper.
|
|
||||||
_pageGraphics.fillRectangle(Color.white, paperRect);
|
|
||||||
// Draw the border of paper.
|
|
||||||
_pageGraphics.drawRectangle(new Pen(Color.black), paperRect);
|
|
||||||
return _pageGraphics;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transfer from the back screen to the front screen.
|
|
||||||
override void onEndPage(PrintDocument document, PrintPageEventArgs e)
|
|
||||||
{
|
|
||||||
// Initialize graphics unit that is changed in user side.
|
|
||||||
_pageGraphics.pageUnit = GraphicsUnit.DISPLAY;
|
|
||||||
|
|
||||||
// Draw the current page number.
|
|
||||||
const string currentPageString = to!string(e.currentPage);
|
|
||||||
Font font = new Font("MS Gothic", 100/+pt+/ * e.pageSettings.printerResolution.y / 72);
|
|
||||||
_pageGraphics.drawText(currentPageString, font, Color.white, Rect(20, 20, 1000, 1000));
|
|
||||||
_pageGraphics.drawText(currentPageString, font, Color.black, Rect(0, 0, 1000, 1000));
|
|
||||||
|
|
||||||
// Draw the main image.
|
|
||||||
const int deviceWidth = GetSystemMetrics(SM_CXSCREEN); // pixel unit.
|
|
||||||
const int deviceHeight = GetSystemMetrics(SM_CYSCREEN); // pixel unit.
|
|
||||||
const Rect screenRect = Rect(0, 0, deviceWidth, deviceHeight); // NOTE: Gets MemoryGraphics size as the background DC.
|
|
||||||
const Rect paperRect = _toRect(document.printerSettings.defaultPageSettings);
|
|
||||||
const uint row = (e.currentPage - _previewControl.startPage - 1) % _previewControl.rows;
|
|
||||||
const uint col = (e.currentPage - _previewControl.startPage - 1) / _previewControl.rows;
|
|
||||||
|
|
||||||
// Size that fit Right side.
|
|
||||||
const uint w1 = (screenRect.width - PrintPreviewControl.LEFT_MARIGIN - PrintPreviewControl.RIGHT_MARGIN - (_previewControl.rows - 1) * PrintPreviewControl.HORIZONTAL_SPAN) / _previewControl.rows;
|
|
||||||
const uint h1 = paperRect.height * w1 / paperRect.width;
|
|
||||||
// Size that fit Bottom side.
|
|
||||||
const uint h2 = (screenRect.height - PrintPreviewControl.TOP_MARGIN - PrintPreviewControl.BOTTOM_MARGIN - (_previewControl.columns - 1) * PrintPreviewControl.VERTICAL_SPAN) / _previewControl.columns;
|
|
||||||
const uint w2 = paperRect.width * h2 / paperRect.height;
|
|
||||||
|
|
||||||
uint w0;
|
|
||||||
uint h0;
|
|
||||||
if (PrintPreviewControl.LEFT_MARIGIN + PrintPreviewControl.RIGHT_MARGIN + _previewControl.rows * w1 + (_previewControl.rows - 1) * PrintPreviewControl.HORIZONTAL_SPAN <= screenRect.width)
|
|
||||||
{
|
|
||||||
if (PrintPreviewControl.TOP_MARGIN + PrintPreviewControl.BOTTOM_MARGIN + _previewControl.columns * h1 + (_previewControl.columns - 1) * PrintPreviewControl.VERTICAL_SPAN <= screenRect.height)
|
|
||||||
{
|
|
||||||
w0 = w1;
|
|
||||||
h0 = h1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The bottom side protruded.
|
|
||||||
w0 = w2;
|
|
||||||
h0 = h2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (PrintPreviewControl.TOP_MARGIN + PrintPreviewControl.BOTTOM_MARGIN + _previewControl.columns * h2 + (_previewControl.columns - 1) * PrintPreviewControl.VERTICAL_SPAN <= screenRect.height)
|
|
||||||
{
|
|
||||||
if (PrintPreviewControl.LEFT_MARIGIN + PrintPreviewControl.RIGHT_MARGIN + _previewControl.rows * w2 + (_previewControl.rows - 1) * PrintPreviewControl.HORIZONTAL_SPAN <= screenRect.width)
|
|
||||||
{
|
|
||||||
w0 = w2;
|
|
||||||
h0 = h2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The right side protruded.
|
|
||||||
w0 = w1;
|
|
||||||
h0 = h1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetStretchBltMode(_pageGraphics.handle, STRETCH_DELETESCANS); // SRC
|
|
||||||
StretchBlt(
|
|
||||||
e.graphics.handle, // DST
|
|
||||||
PrintPreviewControl.LEFT_MARIGIN + row * (w0 + PrintPreviewControl.HORIZONTAL_SPAN),
|
|
||||||
PrintPreviewControl.TOP_MARGIN + col * (h0 + PrintPreviewControl.VERTICAL_SPAN),
|
|
||||||
w0,
|
|
||||||
h0,
|
|
||||||
_pageGraphics.handle, // SRC
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
paperRect.width * 100 / DEFAULT_PRINTER_RESOLUTION_X,
|
|
||||||
paperRect.height * 100 / DEFAULT_PRINTER_RESOLUTION_Y,
|
|
||||||
SRCCOPY
|
|
||||||
);
|
|
||||||
_pageGraphics.dispose(); // Created in onStartPage().
|
|
||||||
|
|
||||||
// Preview-print is end.
|
|
||||||
if (row == _previewControl.rows - 1 && col == _previewControl.columns - 1)
|
|
||||||
e.cancel = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
private Rect _toRect(PageSettings page)
|
private final class PageLayoutHelper
|
||||||
|
{
|
||||||
|
private Point _nextPosition; ///
|
||||||
|
private const uint _columns; ///
|
||||||
|
private const uint _rows; ///
|
||||||
|
private uint _col; ///
|
||||||
|
private uint _row; ///
|
||||||
|
private uint _maxHeightInCurrentLine; ///
|
||||||
|
|
||||||
|
///
|
||||||
|
this(uint columns, uint rows)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
_rows = rows;
|
||||||
|
_columns = columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
_nextPosition = Point(PrintPreviewControl.LEFT_MARIGIN, PrintPreviewControl.TOP_MARGIN);
|
||||||
|
_row = 0;
|
||||||
|
_col = 0;
|
||||||
|
_maxHeightInCurrentLine = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
Point position() const
|
||||||
|
{
|
||||||
|
return _nextPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void appendPageSize(int width, int height)
|
||||||
|
{
|
||||||
|
if (_maxHeightInCurrentLine < height)
|
||||||
|
{
|
||||||
|
_maxHeightInCurrentLine = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_col + 1 >= _columns)
|
||||||
|
{
|
||||||
|
_col = 0;
|
||||||
|
_row++;
|
||||||
|
_nextPosition.x = PrintPreviewControl.LEFT_MARIGIN;
|
||||||
|
_nextPosition.y += _maxHeightInCurrentLine + PrintPreviewControl.VERTICAL_SPAN;
|
||||||
|
_maxHeightInCurrentLine = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_col++;
|
||||||
|
_nextPosition.x += width + PrintPreviewControl.HORIZONTAL_SPAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
private Rect _paperRectFrom(PageSettings page)
|
||||||
{
|
{
|
||||||
const int paperLeft = (page.bounds.x - page.margins.left) * page.printerResolution.x / 100;
|
const int paperLeft = (page.bounds.x - page.margins.left) * page.printerResolution.x / 100;
|
||||||
const int paperTop = (page.bounds.y - page.margins.top) * page.printerResolution.y / 100;
|
const int paperTop = (page.bounds.y - page.margins.top) * page.printerResolution.y / 100;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue