204 lines
8.0 KiB
C#
204 lines
8.0 KiB
C#
using liblogtiny;
|
|
using libpaperang;
|
|
using libpaperang.Main;
|
|
using System;
|
|
using System.Windows;
|
|
using System.Windows.Forms;
|
|
//testing
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
|
|
namespace paperangapp {
|
|
public partial class MainWindow : Window {
|
|
private ILogTiny logger;
|
|
private BaseTypes.Connection mmjcx=BaseTypes.Connection.USB;
|
|
private BaseTypes.Model mmjmd=BaseTypes.Model.T1;
|
|
private Paperang mmj;
|
|
|
|
// TODO: is it out of scope for this library to provide functionality for printing bitmap data?
|
|
public MainWindow() {
|
|
InitializeComponent();
|
|
logger = new LUITextbox();
|
|
gMain.DataContext = (LUITextbox)logger;
|
|
logger.Info("Application started");
|
|
}
|
|
private void BtClearLog_Click(object sender, RoutedEventArgs e) =>
|
|
logger.Raw("!clearlog");
|
|
private void SetP1_Click(object sender, RoutedEventArgs e) {
|
|
mmjmd = BaseTypes.Model.P1;
|
|
logger.Info("Model type set to P1 or P1S");
|
|
}
|
|
private void SetP2_Click(object sender, RoutedEventArgs e) {
|
|
mmjmd = BaseTypes.Model.P2;
|
|
logger.Info("Model type set to P2 or P2S");
|
|
}
|
|
private void SetT1_Click(object sender, RoutedEventArgs e) {
|
|
mmjmd = BaseTypes.Model.T1;
|
|
logger.Info("Model type set to T1");
|
|
}
|
|
private void BtInitUSB_Click(object sender, RoutedEventArgs e) {
|
|
mmj = new Paperang(mmjcx, mmjmd);
|
|
mmj.SetLogContext(logger);
|
|
logger.Verbose("# printers found: " + mmj.Printer.AvailablePrinters.Count);
|
|
if(!mmj.Printer.PrinterAvailable) {
|
|
logger.Error("Couldn't initialise printer as none is connected");
|
|
return;
|
|
}
|
|
logger.Info("USB Initialising");
|
|
mmj.Initialise();
|
|
logger.Debug("PrinterInitialised? " + mmj.Printer.PrinterInitialised);
|
|
logger.Debug("Printer initialised and ready");
|
|
btInitUSB.IsEnabled = false;
|
|
btDeInitUSB.IsEnabled = true;
|
|
gbOtherFunc.IsEnabled = true;
|
|
gbPrinting.IsEnabled = true;
|
|
}
|
|
private void BtDeInitUSB_Click(object sender, RoutedEventArgs e) {
|
|
mmj.Printer.ClosePrinter();
|
|
mmj.Printer.Deinitialise();
|
|
mmj = null;
|
|
gbPrinting.IsEnabled = false;
|
|
gbOtherFunc.IsEnabled = false;
|
|
btInitUSB.IsEnabled = true;
|
|
btDeInitUSB.IsEnabled = false;
|
|
|
|
}
|
|
private void BtFeed_Click(object sender, RoutedEventArgs e) => mmj.Feed((uint)slFeedTime.Value);
|
|
private void BtPrintText_Click(object sender, RoutedEventArgs e) {
|
|
Font fnt=new Font(txFont.Text, int.Parse(txSzF.Text));
|
|
Graphics g=Graphics.FromImage(new Bitmap(mmj.Printer.LineWidth*8, 1));
|
|
SizeF szText=g.MeasureString(txInput.Text, fnt);
|
|
g.Dispose();
|
|
Bitmap b=new Bitmap(mmj.Printer.LineWidth*8, (int)szText.Height);
|
|
g = Graphics.FromImage(b);
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
|
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
|
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
|
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
|
|
g.DrawString(txInput.Text, fnt, Brushes.Black, new PointF(0,0));
|
|
g.Flush();
|
|
PrintBitmap(b);
|
|
g.Dispose();
|
|
b.Dispose();
|
|
}
|
|
private void BtPrintImage_Click(object sender, RoutedEventArgs e) {
|
|
logger.Debug("Loading image for print");
|
|
OpenFileDialog r = new OpenFileDialog {
|
|
Title="Select 1 (one) image file",
|
|
Multiselect=false,
|
|
Filter="PNG files|*.png|JPEG files|*.jpg;*.jpeg|Jraphics Interchange Format files|*.gif|Bitte-Mappe files|*.bmp|All of the above|*.jpg;*.jpeg;*.png;*.gif;*.bmp",
|
|
AutoUpgradeEnabled=true
|
|
};
|
|
if (r.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) {
|
|
logger.Debug("Image load cancelled");
|
|
return;
|
|
}
|
|
Image _=Image.FromFile(r.FileName);
|
|
logger.Debug("Loaded image " + r.FileName);
|
|
r.Dispose();
|
|
logger.Debug("Disposed of dialog");
|
|
Bitmap bimg=new Bitmap(_, (mmj.Printer.LineWidth*8),
|
|
(int)((double)(mmj.Printer.LineWidth*8)*(double)((double)_.Height/(double)_.Width)));
|
|
logger.Debug("Loaded image as Bitmap");
|
|
_.Dispose();
|
|
logger.Debug("Disposed of Image");
|
|
PrintBitmap(bimg);
|
|
}
|
|
private void PrintBitmap(Bitmap bimg) {
|
|
bimg = CopyToBpp(bimg);
|
|
logger.Debug("Converted Bitmap to 1-bit");
|
|
int hSzImg=bimg.Height;
|
|
byte[] iimg = new byte[hSzImg*mmj.Printer.LineWidth];
|
|
byte[] img;
|
|
using(MemoryStream s = new MemoryStream()) {
|
|
bimg.Save(s, ImageFormat.Bmp);
|
|
img = s.ToArray();
|
|
}
|
|
logger.Debug("Got bitmap's bytes");
|
|
bimg.Dispose();
|
|
logger.Debug("Disposed of Bitmap");
|
|
int startoffset=img.Length-(hSzImg*mmj.Printer.LineWidth);
|
|
logger.Debug("Processing bytes with offset " + startoffset);
|
|
for(int h = 0; h < hSzImg; h++) {
|
|
for(int w = 0; w < mmj.Printer.LineWidth; w++) {
|
|
iimg[(mmj.Printer.LineWidth * (hSzImg - 1 - h)) + (mmj.Printer.LineWidth - 1 - w)] = (byte)~
|
|
(img[startoffset + (mmj.Printer.LineWidth * h) + (mmj.Printer.LineWidth - 1 - w)]);
|
|
}
|
|
}
|
|
logger.Debug($"Have {img.Length} bytes of print data ({mmj.Printer.LineWidth*8}x{hSzImg}@1bpp)");
|
|
mmj.PrintBytes(iimg, false);
|
|
mmj.Feed(175);
|
|
}
|
|
static uint BitSwap1(uint x) => ((x & 0x55555555u) << 1) | ((x & (~0x55555555u)) >> 1);
|
|
static uint BitSwap2(uint x) => ((x & 0x33333333u) << 2) | ((x & (~0x33333333u)) >> 2);
|
|
static uint BitSwap4(uint x) => ((x & 0x0f0f0f0fu) << 4) | ((x & (~0x0f0f0f0fu)) >> 4);
|
|
static uint BitSwap(uint x) => BitSwap4(BitSwap2(BitSwap1(x)));
|
|
static Bitmap CopyToBpp(Bitmap b) {
|
|
int w=b.Width, h=b.Height;
|
|
IntPtr hbm = b.GetHbitmap();
|
|
BITMAPINFO bmi = new BITMAPINFO {
|
|
biSize=40,
|
|
biWidth=w,
|
|
biHeight=h,
|
|
biPlanes=1,
|
|
biBitCount=1,
|
|
biCompression=BI_RGB,
|
|
biSizeImage = (uint)(((w+7)&0xFFFFFFF8)*h/8),
|
|
biXPelsPerMeter=1000000,
|
|
biYPelsPerMeter=1000000
|
|
};
|
|
bmi.biClrUsed=2;
|
|
bmi.biClrImportant=2;
|
|
bmi.cols=new uint[256];
|
|
bmi.cols[0]=MAKERGB(0, 0, 0);
|
|
bmi.cols[1]=MAKERGB(255, 255, 255);
|
|
IntPtr hbm0 = CreateDIBSection(IntPtr.Zero,ref bmi,DIB_RGB_COLORS,out _,IntPtr.Zero,0);
|
|
IntPtr sdc = GetDC(IntPtr.Zero);
|
|
IntPtr hdc = CreateCompatibleDC(sdc);
|
|
_ = SelectObject(hdc, hbm);
|
|
IntPtr hdc0 = CreateCompatibleDC(sdc);
|
|
_ = SelectObject(hdc0, hbm0);
|
|
_ = BitBlt(hdc0, 0, 0, w, h, hdc, 0, 0, SRCCOPY);
|
|
Bitmap b0 = Image.FromHbitmap(hbm0);
|
|
_ = DeleteDC(hdc);
|
|
_ = DeleteDC(hdc0);
|
|
_ = ReleaseDC(IntPtr.Zero, sdc);
|
|
_ = DeleteObject(hbm);
|
|
_ = DeleteObject(hbm0);
|
|
return b0;
|
|
}
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
public static extern bool DeleteObject(IntPtr hObject);
|
|
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
|
public static extern IntPtr GetDC(IntPtr hwnd);
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
|
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
|
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
public static extern int DeleteDC(IntPtr hdc);
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
public static extern int BitBlt(IntPtr hdcDst, int xDst, int yDst, int w, int h, IntPtr hdcSrc, int xSrc, int ySrc, int rop);
|
|
static int SRCCOPY = 0x00CC0020;
|
|
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
|
static extern IntPtr CreateDIBSection(IntPtr hdc, ref BITMAPINFO bmi, uint Usage, out IntPtr bits, IntPtr hSection, uint dwOffset);
|
|
static uint BI_RGB = 0;
|
|
static uint DIB_RGB_COLORS=0;
|
|
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
|
public struct BITMAPINFO {
|
|
public uint biSize;
|
|
public int biWidth, biHeight;
|
|
public short biPlanes, biBitCount;
|
|
public uint biCompression, biSizeImage;
|
|
public int biXPelsPerMeter, biYPelsPerMeter;
|
|
public uint biClrUsed, biClrImportant;
|
|
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=256)]
|
|
public uint[] cols;
|
|
}
|
|
static uint MAKERGB(int r, int g, int b) => ((uint)(b&255)) | ((uint)((r&255)<<8)) | ((uint)((g&255)<<16));
|
|
}
|
|
}
|