You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
13 KiB

using Grpc.Core;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using UltraCombos.Utility;
using grpc = global::Grpc.Core;
using Newtonsoft.Json;
namespace TestPrinter
{
public partial class Form1 : Form
{
private PrintDocument pdDocument = new PrintDocument();
private PageSetupDialog setupDlg = new PageSetupDialog();
private PrintPreviewDialog previewDlg = new PrintPreviewDialog();
private PageSettings pageSettings;
private bool is_preview = false;
private bool is_pressed_ok = false;
private bool is_loaded_ok = false;
private string path = @"printer_settings.json";
//private System.Drawing.Image testing_image;
PrinterService service;
public enum ScaleMode
{
ScaleFit = 0,
ScaleFill,
ScaleFullFit,
ScaleFullFill,
ScaleFullPageFit,
ScaleFullPageFill,
MaxNum,
}
public Form1()
{
InitializeComponent();
for (int i = 0; i < (int)ScaleMode.MaxNum; ++i)
{
comboBox1.Items.Add((ScaleMode)(i));
}
comboBox1.SelectedIndex = 0;
pdDocument.DefaultPageSettings.Landscape = true;
pdDocument.PrinterSettings.DefaultPageSettings.Landscape = true;
pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);
PaperSize papersize = null;
foreach (PaperSize size in pdDocument.PrinterSettings.PaperSizes)
{
if(size.PaperName.StartsWith("A4"))
{
papersize = size;
break;
}
}
if (papersize != null)
{
pdDocument.DefaultPageSettings.PaperSize = papersize;
pdDocument.PrinterSettings.DefaultPageSettings.PaperSize = papersize;
var hard_area = pdDocument.PrinterSettings.DefaultPageSettings.PrintableArea;
Margins margins = new Margins(
(int)Math.Round(hard_area.X),
(int)Math.Round(hard_area.Y),
(int)Math.Round(papersize.Width - (hard_area.X + hard_area.Width)),
(int)Math.Round(papersize.Height - (hard_area.Y + hard_area.Height))
);
pdDocument.DefaultPageSettings.Margins = margins;
}
pageSettings = pdDocument.DefaultPageSettings.Clone() as PageSettings;
PrintSettings s = Utils.LoadPrintSettings(path, pageSettings);
is_loaded_ok = s != null;
if (is_loaded_ok)
{
pdDocument.DefaultPageSettings = pageSettings.Clone() as PageSettings;
comboBox1.SelectedItem = s.ScaleMode;
}
var options = new List<Grpc.Core.ChannelOption> { new Grpc.Core.ChannelOption(ChannelOptions.MaxReceiveMessageLength, int.MaxValue) };
var services = new ServerServiceDefinition[] { Printer.BindService(new PrinterImpl(print_impl)) };
service = new PrinterService();
service.StartServer(options, services, 54578);
}
RectangleF getPrintableArea()
{
var rect = pdDocument.DefaultPageSettings.PrintableArea;
if (pdDocument.DefaultPageSettings.Landscape)
{
float tmp = rect.X;
rect.X = rect.Y;
rect.Y = tmp;
tmp = rect.Width;
rect.Width = rect.Height;
rect.Height = tmp;
}
return rect;
}
RectangleF getFullPageArea()
{
var rect = new RectangleF(0, 0, pdDocument.DefaultPageSettings.PaperSize.Width, pdDocument.DefaultPageSettings.PaperSize.Height);
if (pdDocument.DefaultPageSettings.Landscape)
{
float tmp = rect.Width;
rect.Width = rect.Height;
rect.Height = tmp;
}
return rect;
}
private void OnPrintPage(object sender, PrintPageEventArgs e)
{
Console.WriteLine("OnPrintPage()");
float dpiX = (float)e.PageSettings.PrinterSettings.DefaultPageSettings.PrinterResolution.X;
float dpiY = (float)e.PageSettings.PrinterSettings.DefaultPageSettings.PrinterResolution.Y;
e.Graphics.PageUnit = GraphicsUnit.Pixel;
e.Graphics.ScaleTransform(dpiX*0.01f, dpiY*0.01f);
var printable_area = getPrintableArea();
RectangleF hot_area;
switch (comboBox1.SelectedItem)
{
default:
case ScaleMode.ScaleFit:
case ScaleMode.ScaleFill:
hot_area = RectangleF.Intersect(e.MarginBounds, printable_area);
break;
case ScaleMode.ScaleFullFit:
case ScaleMode.ScaleFullFill:
hot_area = printable_area;
break;
case ScaleMode.ScaleFullPageFit:
case ScaleMode.ScaleFullPageFill:
hot_area = getFullPageArea();
break;
}
{
var state = e.Graphics.Save();
e.Graphics.TranslateTransform(hot_area.X, hot_area.Y);
if(is_preview == false)
e.Graphics.TranslateTransform(-printable_area.X, -printable_area.Y);
var image = pictureBox.Image;
float area_aspect = hot_area.Width / hot_area.Height;
float img_aspect = (float)image.Width / image.Height;
float x, y, w, h;
switch (comboBox1.SelectedItem)
{
default:
case ScaleMode.ScaleFit:
case ScaleMode.ScaleFullFit:
case ScaleMode.ScaleFullPageFit:
if (img_aspect > area_aspect)
{
w = hot_area.Width;
h = w / img_aspect;
}
else
{
h = hot_area.Height;
w = h * img_aspect;
}
break;
case ScaleMode.ScaleFill:
case ScaleMode.ScaleFullFill:
case ScaleMode.ScaleFullPageFill:
w = hot_area.Width;
h = hot_area.Height;
break;
}
x = 0.5f * (hot_area.Width - w);
y = 0.5f * (hot_area.Height - h);
Rectangle myRect = new Rectangle(
(int)Math.Round(x),
(int)Math.Round(y),
(int)Math.Round(w),
(int)Math.Round(h)
);
e.Graphics.DrawImage(
image,
myRect,
0,
0,
image.Width,
image.Height,
GraphicsUnit.Pixel);
e.Graphics.Restore(state);
}
if (is_preview)
{
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), printable_area.X, printable_area.Y, printable_area.Width, printable_area.Height);
e.Graphics.DrawRectangle(new Pen(Color.Blue, 1), e.MarginBounds);
is_preview = false;
}
}
private void printer_preview_Click(object sender, EventArgs e)
{
previewDlg.Document = pdDocument;
is_preview = true;
previewDlg.ShowDialog();
}
private void printer_setup_Click(object sender, EventArgs e)
{
setupDlg.Document = pdDocument;
setupDlg.AllowMargins = true;
setupDlg.AllowOrientation = true;
setupDlg.AllowPaper = true;
setupDlg.AllowPrinter = true;
setupDlg.PageSettings = pageSettings;
PrintSettings s = Utils.LoadPrintSettings(path, setupDlg.PageSettings);
if (is_pressed_ok || s != null)
{
Utils.FixMarginsBug(setupDlg.PageSettings);
}
DialogResult ret = setupDlg.ShowDialog();
is_pressed_ok = ret == DialogResult.OK;
if (is_pressed_ok)
{
pdDocument.DefaultPageSettings = setupDlg.PageSettings.Clone() as PageSettings;
Utils.SavePrintSettings(path, setupDlg.PageSettings, (ScaleMode)comboBox1.SelectedItem);
}
}
private void print_impl(UltraCombos.Utility.Image request)
{
var data = request.Content.ToByteArray();
MemoryStream ms = new MemoryStream(data);
pictureBox.Image = System.Drawing.Image.FromStream(ms);
pdDocument.Print();
Console.WriteLine("print_impl");
}
private void printer_scale_mode_Changed(object sender, EventArgs e)
{
if (pageSettings == null)
{
return;
}
Utils.SavePrintSettings(path, pageSettings, (ScaleMode)comboBox1.SelectedItem);
}
}
sealed class Utils
{
//WTF Bug...
static public void FixMarginsBug(PageSettings s)
{
double left = s.Margins.Left;
double right = s.Margins.Right;
double top = s.Margins.Top;
double Bottom = s.Margins.Bottom;
s.Margins.Left = Convert.ToInt32(left * 2.54);
s.Margins.Right = Convert.ToInt32(right * 2.54);
s.Margins.Top = Convert.ToInt32(top * 2.54);
s.Margins.Bottom = Convert.ToInt32(Bottom * 2.54);
}
static public PrintSettings LoadPrintSettings(string path, PageSettings s)
{
if (!File.Exists(path))
{
return null;
}
string json = File.ReadAllText(path);
var obj = JsonConvert.DeserializeObject<PrintSettings>(json);
if (obj == null)
{
return null;
}
obj.To(s);
return obj;
}
static public bool SavePrintSettings(string path, PageSettings s, Form1.ScaleMode scale_mode)
{
var obj = new PrintSettings();
obj.From(s);
obj.ScaleMode = scale_mode;
string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
File.WriteAllText(path, json);
return true;
}
}
public class PrintSettings
{
public PaperSize PaperSize;
public PaperSource PaperSource;
public Margins Margins;
public bool Landscape;
public Form1.ScaleMode ScaleMode;
public void To(PageSettings s)
{
s.PaperSize = PaperSize;
s.PaperSource = PaperSource;
s.Margins = Margins;
s.Landscape = Landscape;
}
public void From(PageSettings s)
{
PaperSize = s.PaperSize;
PaperSource = s.PaperSource;
Margins = s.Margins;
Landscape = s.Landscape;
}
}
public class PrinterService
{
//public int port = 54578;
protected Server server;
public void StartServer(IEnumerable<ChannelOption> options, IEnumerable<ServerServiceDefinition> services, int port)
{
try
{
server = new Server(options)
{
Ports = { new ServerPort("0.0.0.0", port, ServerCredentials.Insecure) }
};
foreach (var def in services)
server.Services.Add(def);
server.Start();
//Log("Start Grpc Server");
Console.WriteLine("Start Grpc Server");
}
catch (System.Exception e)
{
//Log(e.Message, LogType.Error);
Console.WriteLine(e.Message);
}
}
~PrinterService()
{
Shutdown();
}
protected void Shutdown()
{
if (server != null)
{
try
{
server.ShutdownAsync().Wait();
server = null;
}
catch { }
}
}
/*
protected void Log(object msg, LogType type = LogType.Log)
{
Debug.unityLogger.Log(type, $"<b>[Grpc Server]</b> {msg}");
}
*/
}
public class PrinterImpl : Printer.PrinterBase
{
public delegate void PrintDelegate(UltraCombos.Utility.Image request);
public event PrintDelegate onPrint;
public PrinterImpl(PrintDelegate func)
{
onPrint += func;
}
public override Task<Empty> Print(UltraCombos.Utility.Image request, grpc::ServerCallContext context)
{
//throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
onPrint.Invoke(request);
return Task.FromResult(new Empty());
}
}
}