dfl.printing and dfl.drawing is updated

- In dfl.printing, default printing scale is now GraphicsUnit.DISPLAY (BREAKING CHANGE)
- In drawing, multiple monitor is now suport
- Changed common dialog example code about printing
This commit is contained in:
haru-s 2024-05-15 21:02:39 +09:00
parent 000ba4ea27
commit 95c263c566
4 changed files with 695 additions and 579 deletions

View file

@ -12,7 +12,10 @@
"problemMatcher": [ "problemMatcher": [
"$dmd" "$dmd"
], ],
"group": "build", "group":{
"kind": "build",
"isDefault": true
},
"label": "dub: Build commondialog_sample", "label": "dub: Build commondialog_sample",
"detail": "dub build --compiler=dmd.EXE -a=x86_64 -b=debug -c=application" "detail": "dub build --compiler=dmd.EXE -a=x86_64 -b=debug -c=application"
} }

View file

@ -345,15 +345,16 @@ class MainForm : Form
_document.printPage ~= (PrintDocument doc, PrintPageEventArgs e) { _document.printPage ~= (PrintDocument doc, PrintPageEventArgs e) {
Graphics g = e.graphics; Graphics g = e.graphics;
int dpiX = e.pageSettings.printerResolution.x; // dpi unit.
int dpiY = e.pageSettings.printerResolution.y; // dpi unit. // NOTE: BREAKING CHANGE: Changed default scale unit of Graphics is now 1/100 inches from pixels.
assert(g.pageUnit == GraphicsUnit.DISPLAY);
// Draw margin border to all pages. // Draw margin border to all pages.
Rect marginRect = Rect( Rect marginRect = Rect(
e.marginBounds.x * dpiX / 100, // e.marginBounds is 1/100 dpi unit. e.marginBounds.x, // e.marginBounds is 1/100 dpi unit.
e.marginBounds.y * dpiY / 100, e.marginBounds.y,
e.marginBounds.width * dpiX / 100, e.marginBounds.width,
e.marginBounds.height * dpiY / 100); e.marginBounds.height);
g.drawRectangle(new Pen(Color.green, 10), marginRect); g.drawRectangle(new Pen(Color.green, 10), marginRect);
if (e.currentPage == 1) // Draw page 1. if (e.currentPage == 1) // Draw page 1.
@ -366,38 +367,38 @@ class MainForm : Form
"PrintPageEventArgs.pageBounds: " ~ to!string(e.pageBounds) ~ "\n\n" ~ "PrintPageEventArgs.pageBounds: " ~ to!string(e.pageBounds) ~ "\n\n" ~
"PrintPageEventArgs.marginBounds: " ~ to!string(e.marginBounds); "PrintPageEventArgs.marginBounds: " ~ to!string(e.marginBounds);
Rect paramPrintRect = Rect( Rect paramPrintRect = Rect(
e.marginBounds.x * dpiX / 100, // e.marginBounds is 1/100 dpi unit. e.marginBounds.x, // e.marginBounds is 1/100 dpi unit.
e.marginBounds.y * dpiY / 100, e.marginBounds.y,
e.marginBounds.width * dpiX / 100, e.marginBounds.width,
e.marginBounds.height * dpiY / 100 e.marginBounds.height
); );
g.drawText( g.drawText(
str, str,
new Font("MS Gothic", 8/+pt+/ * dpiX / 72), new Font("MS Gothic", 8/+pt+/ * 100 / 72),
Color.black, Color.black,
paramPrintRect paramPrintRect
); );
} }
else if (e.currentPage == 2) // Draw page 2. else if (e.currentPage == 2) // Draw page 2.
{ {
Rect redRect = Rect(1 * dpiX, 1 * dpiY, 1 * dpiX, 1 * dpiY); // 1 x 1 inch. Rect redRect = Rect(1 * 100, 1 * 100, 1 * 100, 1 * 100); // 1 x 1 inch.
redRect.offset(marginRect.x, marginRect.y); redRect.offset(marginRect.x, marginRect.y);
g.fillRectangle(new SolidBrush(Color.red), redRect); g.fillRectangle(new SolidBrush(Color.red), redRect);
Rect blueRect = Rect(dpiX, dpiY, 3 * dpiX, 3 * dpiY); // 3 x 3 inch. Rect blueRect = Rect(100, 100, 3 * 100, 3 * 100); // 3 x 3 inch.
blueRect.offset(marginRect.x, marginRect.y); blueRect.offset(marginRect.x, marginRect.y);
g.drawRectangle(new Pen(Color.blue, 10), blueRect); g.drawRectangle(new Pen(Color.blue, 10), blueRect);
Rect textRect = Rect(1 * dpiX, 1 * dpiY, 1 * dpiX, 1 * dpiY); // 1 x 1 inch. Rect textRect = Rect(1 * 100, 1 * 100, 1 * 100, 1 * 100); // 1 x 1 inch.
textRect.offset(marginRect.x, marginRect.y); textRect.offset(marginRect.x, marginRect.y);
g.drawText( g.drawText(
"ABCDEあいうえお", "ABCDEあいうえお",
new Font("MS Gothic", 12/+pt+/ * dpiX / 72), new Font("MS Gothic", 12/+pt+/ * 100 / 72),
Color.black, Color.black,
textRect textRect
); );
Rect purpleRect = Rect(3 * dpiX, 3 * dpiY, 1 * dpiX, 1 * dpiY); // 1 x 1 inch. Rect purpleRect = Rect(3 * 100, 3 * 100, 1 * 100, 1 * 100); // 1 x 1 inch.
purpleRect.offset(marginRect.x, marginRect.y); purpleRect.offset(marginRect.x, marginRect.y);
g.drawEllipse(new Pen(Color.purple, 10), purpleRect); g.drawEllipse(new Pen(Color.purple, 10), purpleRect);
@ -407,10 +408,10 @@ class MainForm : Form
{ {
g.drawLine( g.drawLine(
pen, pen,
marginRect.x + cast(int)(x / 4.0 * dpiX), marginRect.x + cast(int)(x / 4.0 * 100),
e.marginBounds.y * dpiY / 100, e.marginBounds.y,
marginRect.x + cast(int)((lineNum - x - 1)/4.0 * dpiX), marginRect.x + cast(int)((lineNum - x - 1)/4.0 * 100),
e.marginBounds.bottom * dpiY / 100); e.marginBounds.bottom);
} }
} }
}; };

File diff suppressed because it is too large Load diff

View file

@ -57,7 +57,7 @@ final static class PrinterUnitConvert
return value * to / from; return value * to / from;
} }
/// /// ditto
static int convert(int value, PrinterUnit fromUnit, PrinterUnit toUnit) static int convert(int value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
double from = unitsPerDisplay(fromUnit); double from = unitsPerDisplay(fromUnit);
@ -65,7 +65,7 @@ final static class PrinterUnitConvert
return cast(int)(value * to / from); return cast(int)(value * to / from);
} }
/// /// ditto
static Margins convert(Margins value, PrinterUnit fromUnit, PrinterUnit toUnit) static Margins convert(Margins value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return new Margins( return new Margins(
@ -76,7 +76,7 @@ final static class PrinterUnitConvert
); );
} }
/// /// ditto
static Point convert(Point value, PrinterUnit fromUnit, PrinterUnit toUnit) static Point convert(Point value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return Point( return Point(
@ -85,7 +85,7 @@ final static class PrinterUnitConvert
); );
} }
/// /// ditto
static POINT convert(POINT value, PrinterUnit fromUnit, PrinterUnit toUnit) static POINT convert(POINT value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return POINT( return POINT(
@ -94,7 +94,7 @@ final static class PrinterUnitConvert
); );
} }
/// /// ditto
static Rect convert(Rect value, PrinterUnit fromUnit, PrinterUnit toUnit) static Rect convert(Rect value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return Rect( return Rect(
@ -105,7 +105,7 @@ final static class PrinterUnitConvert
); );
} }
/// /// ditto
static RECT convert(RECT value, PrinterUnit fromUnit, PrinterUnit toUnit) static RECT convert(RECT value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return RECT( return RECT(
@ -116,7 +116,7 @@ final static class PrinterUnitConvert
); );
} }
/// /// ditto
static Size convert(Size value, PrinterUnit fromUnit, PrinterUnit toUnit) static Size convert(Size value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return Size( return Size(
@ -125,7 +125,7 @@ final static class PrinterUnitConvert
); );
} }
/// /// ditto
static SIZE convert(SIZE value, PrinterUnit fromUnit, PrinterUnit toUnit) static SIZE convert(SIZE value, PrinterUnit fromUnit, PrinterUnit toUnit)
{ {
return SIZE( return SIZE(
@ -866,6 +866,12 @@ private PrinterResolution[] _createPrinterResolutionArray(HGLOBAL hDevMode)
} }
} }
private
{
enum DEFAULT_PRINTER_RESOLUTION_X = 200;
enum DEFAULT_PRINTER_RESOLUTION_Y = 200;
}
/// ///
class PrinterSettings class PrinterSettings
{ {
@ -919,7 +925,7 @@ class PrinterSettings
false, // true is landscape (w > h). false, // true is landscape (w > h).
new PaperSize(PaperKind.A4, "A4", 827, 1169), // 1/100 inch unit. (210 x 297 mm) new PaperSize(PaperKind.A4, "A4", 827, 1169), // 1/100 inch unit. (210 x 297 mm)
new PaperSource(PaperSourceKind.FORM_SOURCE, "Tray"), new PaperSource(PaperSourceKind.FORM_SOURCE, "Tray"),
new PrinterResolution(PrinterResolutionKind.CUSTOM, 200, 200)); // dpi unit. new PrinterResolution(PrinterResolutionKind.CUSTOM, DEFAULT_PRINTER_RESOLUTION_X, DEFAULT_PRINTER_RESOLUTION_Y)); // dpi unit.
} }
return _defaultPageSettings; return _defaultPageSettings;
} }
@ -2124,8 +2130,8 @@ class PrintPreviewControl : Control
DEVMODE* pDevMode = cast(DEVMODE*)GlobalLock(pd.hDevMode); DEVMODE* pDevMode = cast(DEVMODE*)GlobalLock(pd.hDevMode);
scope(exit) scope(exit)
GlobalUnlock(pDevMode); GlobalUnlock(pDevMode);
pDevMode.dmPrintQuality = 200; // dpi pDevMode.dmPrintQuality = DEFAULT_PRINTER_RESOLUTION_X; // dpi
pDevMode.dmYResolution = 200; // dpi pDevMode.dmYResolution = DEFAULT_PRINTER_RESOLUTION_Y; // dpi
pDevMode.dmOrientation = { pDevMode.dmOrientation = {
if (document.printerSettings.defaultPageSettings.landscape) if (document.printerSettings.defaultPageSettings.landscape)
return DMORIENT_LANDSCAPE; return DMORIENT_LANDSCAPE;
@ -2187,12 +2193,12 @@ class PrintPreviewControl : Control
mouseDown(this, e); mouseDown(this, e);
} }
static const uint LEFT_MARIGIN = 20; // Dots enum LEFT_MARIGIN = 20; // Dots
static const uint RIGHT_MARGIN = 20; // Dots enum RIGHT_MARGIN = 20; // Dots
static const uint TOP_MARGIN = 20; // Dots enum TOP_MARGIN = 20; // Dots
static const uint BOTTOM_MARGIN = 20; // Dots enum BOTTOM_MARGIN = 20; // Dots
static const uint HORIZONTAL_SPAN = 20; // Dots enum HORIZONTAL_SPAN = 20; // Dots
static const uint VERTICAL_SPAN = 20; // Dots enum VERTICAL_SPAN = 20; // Dots
/// ///
protected override void onPaint(PaintEventArgs e) protected override void onPaint(PaintEventArgs e)
@ -2203,8 +2209,6 @@ class PrintPreviewControl : Control
if (this.autoZoom) if (this.autoZoom)
{ {
const Rect screenRect = Rect(0, 0, _background.width, _background.height); const Rect screenRect = Rect(0, 0, _background.width, _background.height);
const Rect paperRect = _toRect(document.printerSettings.defaultPageSettings);
uint h0 = height; uint h0 = height;
uint w0 = screenRect.width * height / screenRect.height; uint w0 = screenRect.width * height / screenRect.height;
if (w0 >= width) if (w0 >= width)
@ -2495,31 +2499,6 @@ class PrintPreviewDialog : Form
} }
} }
///
// final class PreviewPageInfo
// {
// private Image _image;
// private Size _size; // 1/100 inch unit.
// ///
// this(Image image, Size size)
// {
// _image = image;
// _size = size;
// }
// ///
// Image image() // getter
// {
// return _image;
// }
// /// Gets the size of the printed page, in 1/100 inch unit.
// Size physicalSize() const // getter
// {
// return _size;
// }
// }
/// ///
class PreviewPrintController : PrintController class PreviewPrintController : PrintController
@ -2538,12 +2517,6 @@ class PreviewPrintController : PrintController
_previewControl = previewControl; _previewControl = previewControl;
} }
///
// PreviewPageInfo[] getPreviewPageInfo()
// {
// assert(0);
// }
/// ///
override void onStartPrint(PrintDocument document, PrintEventArgs e) override void onStartPrint(PrintDocument document, PrintEventArgs e)
{ {
@ -2556,12 +2529,12 @@ class PreviewPrintController : PrintController
// Do nothing. // Do nothing.
} }
/// /// Create and draw the back screen.
override Graphics onStartPage(PrintDocument document, PrintPageEventArgs e) override Graphics onStartPage(PrintDocument document, PrintPageEventArgs e)
{ {
Rect paperRect = _toRect(document.printerSettings.defaultPageSettings); Rect paperRect = _toRect(document.printerSettings.defaultPageSettings);
_pageGraphics = { _pageGraphics = {
// Be dispose() called in onEntPage(). // Be dispose() called in onEntPage().
if (e.pageBounds.width <= e.pageBounds.height) if (e.pageBounds.width <= e.pageBounds.height)
return new MemoryGraphics(paperRect.width, paperRect.height, e.graphics.handle); return new MemoryGraphics(paperRect.width, paperRect.height, e.graphics.handle);
else else
@ -2574,9 +2547,12 @@ class PreviewPrintController : PrintController
return _pageGraphics; return _pageGraphics;
} }
/// /// Transfer from the back screen to the front screen.
override void onEndPage(PrintDocument document, PrintPageEventArgs e) 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. // Draw the current page number.
const string currentPageString = to!string(e.currentPage); const string currentPageString = to!string(e.currentPage);
Font font = new Font("MS Gothic", 100/+pt+/ * e.pageSettings.printerResolution.y / 72); Font font = new Font("MS Gothic", 100/+pt+/ * e.pageSettings.printerResolution.y / 72);
@ -2584,7 +2560,9 @@ class PreviewPrintController : PrintController
_pageGraphics.drawText(currentPageString, font, Color.black, Rect(0, 0, 1000, 1000)); _pageGraphics.drawText(currentPageString, font, Color.black, Rect(0, 0, 1000, 1000));
// Draw the main image. // Draw the main image.
const Rect screenRect = Rect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); // NOTE: Gets MemoryGraphics size as the background DC. 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 Rect paperRect = _toRect(document.printerSettings.defaultPageSettings);
const uint row = (e.currentPage - _previewControl.startPage - 1) % _previewControl.rows; const uint row = (e.currentPage - _previewControl.startPage - 1) % _previewControl.rows;
const uint col = (e.currentPage - _previewControl.startPage - 1) / _previewControl.rows; const uint col = (e.currentPage - _previewControl.startPage - 1) / _previewControl.rows;
@ -2607,7 +2585,7 @@ class PreviewPrintController : PrintController
} }
else else
{ {
// Bottom side is over size. // The bottom side protruded.
w0 = w2; w0 = w2;
h0 = h2; h0 = h2;
} }
@ -2621,7 +2599,7 @@ class PreviewPrintController : PrintController
} }
else else
{ {
// Right side is over size. // The right side protruded.
w0 = w1; w0 = w1;
h0 = h1; h0 = h1;
} }
@ -2637,8 +2615,8 @@ class PreviewPrintController : PrintController
_pageGraphics.handle, // SRC _pageGraphics.handle, // SRC
0, 0,
0, 0,
paperRect.width, paperRect.width * 100 / DEFAULT_PRINTER_RESOLUTION_X,
paperRect.height, paperRect.height * 100 / DEFAULT_PRINTER_RESOLUTION_Y,
SRCCOPY SRCCOPY
); );
_pageGraphics.dispose(); // Created in onStartPage(). _pageGraphics.dispose(); // Created in onStartPage().
@ -2652,10 +2630,9 @@ class PreviewPrintController : PrintController
/// ///
private Rect _toRect(PageSettings page) private Rect _toRect(PageSettings page)
{ {
return Rect( const int paperLeft = (page.bounds.x - page.margins.left) * page.printerResolution.x / 100;
(page.bounds.x - page.margins.left) * page.printerResolution.x / 100, const int paperTop = (page.bounds.y - page.margins.top) * page.printerResolution.y / 100;
(page.bounds.y - page.margins.top) * page.printerResolution.y / 100, const int paperWidth = (page.bounds.x + page.bounds.width + page.margins.right) * page.printerResolution.x / 100;
(page.bounds.x + page.bounds.width + page.margins.right) * page.printerResolution.x / 100, const int paperHeight = (page.bounds.y + page.bounds.height + page.margins.bottom) * page.printerResolution.y / 100;
(page.bounds.y + page.bounds.height + page.margins.bottom) * page.printerResolution.y / 100 return Rect(paperLeft, paperTop, paperWidth, paperHeight);
);
} }