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
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());
|
|
}
|
|
}
|
|
}
|
|
|