some changes

This commit is contained in:
Maff 2019-10-04 11:18:17 +01:00
parent 734ebf47e1
commit 471c9e5165
9 changed files with 150 additions and 126 deletions

View File

@ -1,8 +1,4 @@
using System; namespace liblogtiny {
using System.Collections.Generic;
using System.Text;
namespace liblogtiny {
public partial class LogTiny { public partial class LogTiny {
public enum LogLevel { public enum LogLevel {
Trace, Trace,

View File

@ -5,55 +5,57 @@ using System.Linq;
namespace libpaperang.Helpers { namespace libpaperang.Helpers {
public class CRC { public class CRC {
private uint _iv; private uint _iv;
public uint iv { get => ~_iv; private set => _iv=~value; } public uint Iv { get => ~_iv; private set => _iv = ~value; }
public uint mv = 0x35769521; public uint Mv => 0x35769521u;
private uint poly = 0xedb88320; private uint poly = 0xedb88320;
private uint[] crctable; private uint[] crctable;
public bool IsInitialised=false; public bool IsInitialised=false;
public CRC(bool autoinit = true) { public CRC(bool autoinit = true) {
iv = 0; Iv = 0;
if(autoinit) Initialise(); if(autoinit)
Initialise();
} }
public CRC(uint iv, bool autoinit = true) { public CRC(uint iv, bool autoinit = true) {
this.iv = iv; Iv = iv;
if (autoinit) Initialise(); if(autoinit)
Initialise();
} }
public void Initialise() { public void Initialise() {
crctable=Enumerable.Range(0, 256).Select(i => { crctable = Enumerable.Range(0, 256).Select(i => {
uint e=(uint)i; uint e=(uint)i;
for (ushort eb = 0; eb<8; eb++) for(ushort eb = 0; eb < 8; eb++) {
e=((e&1)!=0) e = ((e & 1) != 0)
? (poly^(e>>1)) ? (poly ^ (e >> 1))
: (e>>1); : (e >> 1);
}
return e; return e;
}).ToArray(); }).ToArray();
IsInitialised=true; IsInitialised = true;
} }
public uint Reflect(uint iv) { public uint Reflect(uint iv) {
uint ivr=0; uint ivr=0;
for (int i = 0; i<32; i++) { for(int i = 0; i < 32; i++) {
uint b=(iv>>i)&1; uint b=(iv>>i)&1;
ivr|=(b<<(31-i)); ivr |= b << (31 - i);
} }
return ~ivr; return ~ivr;
} }
public uint GetChecksumUint<T>(IEnumerable<T> data) { public uint GetChecksumUint<T>(IEnumerable<T> data) {
if (!IsInitialised) throw new CrcNotAvailableException(); if(!IsInitialised)
throw new CrcNotAvailableException();
try { try {
return ~data.Aggregate(_iv, return ~data.Aggregate(_iv,
(cti, cb) => crctable[(cti&0xFF)^Convert.ToByte(cb)]^(cti>>8)); (cti, cb) => crctable[(cti & 0xFF) ^ Convert.ToByte(cb)] ^ (cti >> 8));
} catch (FormatException e) { } catch(FormatException e) {
throw new FormatException("Could not read input as a byte stream", e); throw new FormatException("Could not read input as a byte stream", e);
} catch (InvalidCastException e) { } catch(InvalidCastException e) {
throw new InvalidCastException("Could not read input as a byte stream", e); throw new InvalidCastException("Could not read input as a byte stream", e);
} catch (OverflowException e) { } catch(OverflowException e) {
throw new OverflowException("Could not read input as a byte stream", e); throw new OverflowException("Could not read input as a byte stream", e);
} }
} }
public byte[] GetChecksumBytes<T>(IEnumerable<T> data) => BitConverter.GetBytes(GetChecksumUint(data)); public byte[] GetChecksumBytes<T>(IEnumerable<T> data) => BitConverter.GetBytes(GetChecksumUint(data));
public uint GetCrcIv() => iv == mv public uint GetCrcIv() => Iv == Mv ? Iv : Iv ^ Mv;
? iv
: iv ^ mv;
public byte[] GetCrcIvBytes() => BitConverter.GetBytes(GetCrcIv()); public byte[] GetCrcIvBytes() => BitConverter.GetBytes(GetCrcIv());
} }
} }

View File

@ -1,5 +0,0 @@

namespace libpaperang.Helpers {
class Media {
}
}

View File

@ -7,23 +7,29 @@ namespace libpaperang.Helpers {
public BaseTypes.Opcodes Op; public BaseTypes.Opcodes Op;
public short OpLen; public short OpLen;
public Transforms(BaseTypes.Packet FrameConstruction, BaseTypes.Opcodes Operations, short OperLen) { public Transforms(BaseTypes.Packet FrameConstruction, BaseTypes.Opcodes Operations, short OperLen) {
Frame=FrameConstruction; Frame = FrameConstruction;
Op=Operations; Op = Operations;
OpLen=OperLen; OpLen = OperLen;
} }
public byte[] Oper(BaseTypes.Operations Operation) { public byte[] Oper(BaseTypes.Operations Operation) {
switch (Operation) { switch(Operation) {
case BaseTypes.Operations.NoOp: return Op.NoOp; case BaseTypes.Operations.NoOp:
case BaseTypes.Operations.LineFeed: return Op.LineFeed; return Op.NoOp;
case BaseTypes.Operations.CrcTransmit: return Op.TransmitCrc; case BaseTypes.Operations.LineFeed:
case BaseTypes.Operations.Print: return Op.Print; return Op.LineFeed;
default: throw new InvalidOperationException(); case BaseTypes.Operations.CrcTransmit:
return Op.TransmitCrc;
case BaseTypes.Operations.Print:
return Op.Print;
default:
throw new InvalidOperationException();
} }
} }
public byte[] Arg(BaseTypes.Operations Operation, uint Data) { public byte[] Arg(BaseTypes.Operations Operation, uint Data) {
switch(Operation) { switch(Operation) {
case BaseTypes.Operations.LineFeed: return BitConverter.GetBytes(SwapWordEndianness( case BaseTypes.Operations.LineFeed:
0x00000000 | ((((( return BitConverter.GetBytes(SwapWordEndianness(
0x00000000 | (((((
Data & 0xffu) << 16) | Data & 0xffu) << 16) |
Data) & 0xffff00u) >> 8))).Skip(2).ToArray(); Data) & 0xffff00u) >> 8))).Skip(2).ToArray();
case BaseTypes.Operations.Print: case BaseTypes.Operations.Print:
@ -31,17 +37,18 @@ namespace libpaperang.Helpers {
0x00010000 | ((((( 0x00010000 | (((((
Data & 0xffu) << 16) | Data & 0xffu) << 16) |
Data) & 0xffff00u) >> 8))); Data) & 0xffff00u) >> 8)));
default: throw new InvalidOperationException(); default:
throw new InvalidOperationException();
} }
} }
public byte[] Packet(byte[] oper, byte[] data, CRC checksum) { public byte[] Packet(byte[] oper, byte[] data, CRC checksum) {
byte[] packet = new byte[1+oper.Length+data.Length+5]; byte[] packet = new byte[1+oper.Length+data.Length+5];
packet[0] = Frame.Start; packet[0] = Frame.Start;
packet[packet.Length-1] = Frame.End; packet[packet.Length - 1] = Frame.End;
Buffer.BlockCopy(oper, Buffer.BlockCopy(oper,
0, packet, 1, oper.Length); 0, packet, 1, oper.Length);
Buffer.BlockCopy(data, Buffer.BlockCopy(data,
0, packet, oper.Length+1, data.Length); 0, packet, oper.Length + 1, data.Length);
Buffer.BlockCopy(checksum.GetChecksumBytes(data), Buffer.BlockCopy(checksum.GetChecksumBytes(data),
0, packet, packet.Length - 5, 4); 0, packet, packet.Length - 5, 4);
return packet; return packet;
@ -54,7 +61,7 @@ namespace libpaperang.Helpers {
return p; return p;
} }
public uint SwapWordEndianness(uint value) => ( public uint SwapWordEndianness(uint value) => (
(value & 0x000000ffu) << 24)| (value & 0x000000ffu) << 24) |
((value & 0x0000ff00u) << 8) | ((value & 0x0000ff00u) << 8) |
((value & 0x00ff0000u) >> 8) | ((value & 0x00ff0000u) >> 8) |
((value & 0xff000000u) >> 24); ((value & 0xff000000u) >> 24);

View File

@ -55,6 +55,8 @@ namespace libpaperang {
} }
public interface IPrinter { public interface IPrinter {
short LineWidth { get; } short LineWidth { get; }
short BasePrintDelay { get; }
uint MaximumDataSize { get; }
BaseTypes.Connection ConnectionMethod { get; } BaseTypes.Connection ConnectionMethod { get; }
BaseTypes.Model PrinterVariant { get; } BaseTypes.Model PrinterVariant { get; }
BaseTypes.State Status { get; } BaseTypes.State Status { get; }

View File

@ -10,7 +10,7 @@ namespace libpaperang.Interfaces {
// constants // constants
private const ushort iV = 0x4348; private const ushort iV = 0x4348;
private const ushort iP = 0x5584; private const ushort iP = 0x5584;
private const short MaxDataSize = 1008; public uint MaximumDataSize => 1008;
// types // types
private struct UsbComms { private struct UsbComms {
@ -20,21 +20,35 @@ namespace libpaperang.Interfaces {
public UsbEndpointWriter tx; public UsbEndpointWriter tx;
} }
private UsbComms Printer; private UsbComms Printer;
private BaseTypes.Model iModel;
private bool _initialised=false;
public short LineWidth { public short LineWidth {
get { get {
switch (iModel) { switch(PrinterVariant) {
case BaseTypes.Model.P1: return 48; case BaseTypes.Model.P1:
case BaseTypes.Model.P2: return 72; return 48;
case BaseTypes.Model.P2S: return 72; //assumption case BaseTypes.Model.P2:
case BaseTypes.Model.T1: throw new PrinterVariantNotSupportedException(); return 72;
default: throw new InvalidOperationException(); case BaseTypes.Model.T1:
throw new PrinterVariantNotSupportedException();
default:
throw new InvalidOperationException();
}
}
}
public short BasePrintDelay {
get {
switch(PrinterVariant) {
case BaseTypes.Model.P1:
return 80;
case BaseTypes.Model.P2:
return 140;
default:
throw new InvalidOperationException();
} }
} }
} }
public BaseTypes.Connection ConnectionMethod => BaseTypes.Connection.USB; public BaseTypes.Connection ConnectionMethod => BaseTypes.Connection.USB;
public BaseTypes.Model PrinterVariant => iModel; public BaseTypes.Model PrinterVariant { get; private set; }
public BaseTypes.State Status => BaseTypes.State.Offline; public BaseTypes.State Status => BaseTypes.State.Offline;
public List<BaseTypes.Printer> AvailablePrinters { public List<BaseTypes.Printer> AvailablePrinters {
get { get {
@ -52,33 +66,36 @@ namespace libpaperang.Interfaces {
} }
} }
public bool PrinterAvailable => AvailablePrinters.Count > 0; public bool PrinterAvailable => AvailablePrinters.Count > 0;
public bool PrinterInitialised => _initialised; public bool PrinterInitialised { get; private set; } = false;
public bool PrinterOpen => Printer.handle?.IsOpen ?? false; public bool PrinterOpen => Printer.handle?.IsOpen ?? false;
public void OpenPrinter(BaseTypes.Printer printer) {
bool res;
try {
res = ((UsbRegistry)printer.Instance).Open(out Printer.handle);
} catch(Exception) {
throw new PrinterNotAvailableException();
}
if(!res)
throw new PrinterNotAvailableException();
}
public void ClosePrinter() => Printer.handle?.Close(); public void ClosePrinter() => Printer.handle?.Close();
public void Initialise() {
if(!PrinterOpen)
throw new PrinterNotInitialisedException();
//WinUSB-specific
Printer.iface = Printer.handle as IUsbDevice;
_ = Printer.iface?.SetConfiguration(1);
_ = Printer.iface?.ClaimInterface(0);
Printer.rx = Printer.handle.OpenEndpointReader(ReadEndpointID.Ep01);
Printer.tx = Printer.handle.OpenEndpointWriter(WriteEndpointID.Ep02);
PrinterInitialised = true;
}
public void Deinitialise() { public void Deinitialise() {
Printer.rx?.Dispose(); Printer.rx?.Dispose();
Printer.tx?.Dispose(); Printer.tx?.Dispose();
_ = Printer.iface?.ReleaseInterface(0); _ = Printer.iface?.ReleaseInterface(0);
_ = Printer.iface?.Close(); _ = Printer.iface?.Close();
} ClosePrinter();
public void Initialise() {
if (!PrinterOpen) throw new PrinterNotInitialisedException();
//WinUSB-specific
Printer.iface=Printer.handle as IUsbDevice;
_=Printer.iface?.SetConfiguration(1);
_=Printer.iface?.ClaimInterface(0);
Printer.rx=Printer.handle.OpenEndpointReader(ReadEndpointID.Ep01);
Printer.tx=Printer.handle.OpenEndpointWriter(WriteEndpointID.Ep02);
_initialised = true;
}
public void OpenPrinter(BaseTypes.Printer printer) {
bool res;
try {
res=((UsbRegistry)printer.Instance).Open(out Printer.handle);
} catch (Exception) {
throw new PrinterNotAvailableException();
}
if (!res) throw new PrinterNotAvailableException();
} }
public byte[] ReadBytes() { public byte[] ReadBytes() {
byte[] readbuf=new byte[1024]; byte[] readbuf=new byte[1024];
@ -91,6 +108,6 @@ namespace libpaperang.Interfaces {
Thread.Sleep(delay); Thread.Sleep(delay);
return _; return _;
} }
public USB(BaseTypes.Model model) => iModel=model; public USB(BaseTypes.Model model) => PrinterVariant = model;
} }
} }

View File

@ -1,8 +1,8 @@
using libpaperang.Helpers; using System.Collections.Generic;
using libpaperang.Interfaces;
using liblogtiny;
using System.Linq; using System.Linq;
using System.Collections.Generic; using liblogtiny;
using libpaperang.Helpers;
using libpaperang.Interfaces;
namespace libpaperang.Main { namespace libpaperang.Main {
public class Paperang { public class Paperang {
@ -75,7 +75,7 @@ namespace libpaperang.Main {
logger?.Trace($"PrintBytes() invoked with data length of {data.Length}"); logger?.Trace($"PrintBytes() invoked with data length of {data.Length}");
List<byte[]> segments = data List<byte[]> segments = data
.Select((b,i) => new {Index=i,Value=b }) .Select((b,i) => new {Index=i,Value=b })
.GroupBy(b=>b.Index/1008) .GroupBy(b=>b.Index/Printer.MaximumDataSize)
.Select(b=>b.Select(bb=>bb.Value).ToArray()) .Select(b=>b.Select(bb=>bb.Value).ToArray())
.ToList(); .ToList();
logger?.Trace($"data split into {segments.Count} segment(s)"); logger?.Trace($"data split into {segments.Count} segment(s)");
@ -84,7 +84,9 @@ namespace libpaperang.Main {
Transform.Arg(BaseTypes.Operations.Print, (uint)b.Length), Transform.Arg(BaseTypes.Operations.Print, (uint)b.Length),
b, b,
Crc), Crc),
200-(b.Length/Printer.LineWidth))); Printer.BasePrintDelay + (b.Length / Printer.LineWidth)));
if(autofeed)
Feed(185);
} }
} }
} }

View File

@ -1,5 +1,5 @@
using liblogtiny; using System.ComponentModel;
using System.ComponentModel; using liblogtiny;
namespace paperangapp { namespace paperangapp {
class LUITextbox : ILogTiny, INotifyPropertyChanged { class LUITextbox : ILogTiny, INotifyPropertyChanged {
@ -11,13 +11,13 @@ namespace paperangapp {
//get { return _LogBuffer; } //get { return _LogBuffer; }
get => _LogBuffer; get => _LogBuffer;
set { set {
if (value == _LogBuffer) return; if(value == _LogBuffer)
if (value == "!clearlog") _LogBuffer = ""; return;
else _LogBuffer = value + "\n" + _LogBuffer; _LogBuffer = value == "!clearlog" ? "" : value + "\n" + _LogBuffer;
OnPropertyChanged("LogBuffer"); OnPropertyChanged("LogBuffer");
} }
} }
public void ClearBuffer() => LogBuffer="!clearlog"; public void ClearBuffer() => LogBuffer = "!clearlog";
public void Trace(string msg) => Log(LogTiny.LogLevel.Trace, msg); public void Trace(string msg) => Log(LogTiny.LogLevel.Trace, msg);
public void Debug(string msg) => Log(LogTiny.LogLevel.Debug, msg); public void Debug(string msg) => Log(LogTiny.LogLevel.Debug, msg);
public void Verbose(string msg) => Log(LogTiny.LogLevel.Verbose, msg); public void Verbose(string msg) => Log(LogTiny.LogLevel.Verbose, msg);
@ -25,7 +25,7 @@ namespace paperangapp {
public void Warn(string msg) => Log(LogTiny.LogLevel.Warn, msg); public void Warn(string msg) => Log(LogTiny.LogLevel.Warn, msg);
public void Error(string msg) => Log(LogTiny.LogLevel.Error, msg); public void Error(string msg) => Log(LogTiny.LogLevel.Error, msg);
public void Critical(string msg) => Log(LogTiny.LogLevel.Critical, msg); public void Critical(string msg) => Log(LogTiny.LogLevel.Critical, msg);
public void Log(LogTiny.LogLevel level, string msg) => LogBuffer=$"{level}: {msg}"; public void Log(LogTiny.LogLevel level, string msg) => LogBuffer = $"{level}: {msg}";
public void Raw(string msg) => LogBuffer=msg; public void Raw(string msg) => LogBuffer = msg;
} }
} }

View File

@ -1,15 +1,14 @@
using liblogtiny; using System;
using libpaperang;
using libpaperang.Interfaces;
using libpaperang.Main;
using System;
using System.Timers;
using System.Windows;
using System.Windows.Forms;
//testing
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Timers;
using System.Windows;
using System.Windows.Forms;
using liblogtiny;
using libpaperang;
using libpaperang.Interfaces;
using libpaperang.Main;
namespace paperangapp { namespace paperangapp {
public partial class MainWindow : Window { public partial class MainWindow : Window {
@ -25,7 +24,7 @@ namespace paperangapp {
UnInitDev, UnInitDev,
InitDev InitDev
}; };
private AppState state=AppState.UnInitNoDev; private AppState state=AppState.UnInitDev;
// TODO: is it out of scope for this library to provide functionality for printing bitmap data? // TODO: is it out of scope for this library to provide functionality for printing bitmap data?
public MainWindow() { public MainWindow() {
InitializeComponent(); InitializeComponent();
@ -35,14 +34,14 @@ namespace paperangapp {
usbpoll = new System.Timers.Timer(200) { usbpoll = new System.Timers.Timer(200) {
AutoReset = true AutoReset = true
}; };
usbpoll.Elapsed += evtUsbPoll; usbpoll.Elapsed += EvtUsbPoll;
usbpoll.Start(); usbpoll.Start();
logger.Verbose("USB presence interval event started"); logger.Verbose("USB presence interval event started");
} }
private void evtUsbPoll(object sender, ElapsedEventArgs e) =>_ = Dispatcher.BeginInvoke(new invDgtUsbPoll(dgtUsbPoll)); private void EvtUsbPoll(object sender, ElapsedEventArgs e) => _ = Dispatcher.BeginInvoke(new invDgtUsbPoll(DgtUsbPoll));
private delegate void invDgtUsbPoll(); private delegate void invDgtUsbPoll();
private void dgtUsbPoll() { private void DgtUsbPoll() {
try { try {
if(state == AppState.UnInitNoDev && prtr.PrinterAvailable) { if(state == AppState.UnInitNoDev && prtr.PrinterAvailable) {
btInitUSB.IsEnabled = true; btInitUSB.IsEnabled = true;
@ -63,7 +62,8 @@ namespace paperangapp {
~MainWindow() { ~MainWindow() {
logger.Warn("Application closing"); logger.Warn("Application closing");
if(mmj!=null) USBDeInit(); if(mmj != null)
USBDeInit();
} }
private void BtClearLog_Click(object sender, RoutedEventArgs e) => private void BtClearLog_Click(object sender, RoutedEventArgs e) =>
logger.Raw("!clearlog"); logger.Raw("!clearlog");
@ -115,9 +115,14 @@ namespace paperangapp {
} }
private void BtFeed_Click(object sender, RoutedEventArgs e) => mmj.Feed((uint)slFeedTime.Value); private void BtFeed_Click(object sender, RoutedEventArgs e) => mmj.Feed((uint)slFeedTime.Value);
private void BtPrintText_Click(object sender, RoutedEventArgs e) { private void BtPrintText_Click(object sender, RoutedEventArgs e) {
if(!(txInput.Text.Length > 0)) {
logger.Warn("PrintText event but nothing to print.");
return;
}
Font fnt=new Font(txFont.Text, int.Parse(txSzF.Text)); Font fnt=new Font(txFont.Text, int.Parse(txSzF.Text));
Graphics g=Graphics.FromImage(new Bitmap(mmj.Printer.LineWidth*8, 1)); Graphics g=Graphics.FromImage(new Bitmap(mmj.Printer.LineWidth*8, 1));
SizeF szText=g.MeasureString(txInput.Text, fnt); System.Drawing.Size szText = TextRenderer.MeasureText(g, txInput.Text, fnt);
//SizeF szText=g.MeasureString(txInput.Text, fnt);
g.Dispose(); g.Dispose();
Bitmap b=new Bitmap(mmj.Printer.LineWidth*8, (int)szText.Height); Bitmap b=new Bitmap(mmj.Printer.LineWidth*8, (int)szText.Height);
g = Graphics.FromImage(b); g = Graphics.FromImage(b);
@ -125,34 +130,37 @@ namespace paperangapp {
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.DrawString(txInput.Text, fnt, Brushes.Black, new PointF(0,0)); TextRenderer.DrawText(g, txInput.Text, fnt, new System.Drawing.Point(0, 0), Color.Black);
g.Flush(); g.Flush();
PrintBitmap(b); PrintBitmap(b);
g.Dispose(); g.Dispose();
b.Dispose(); b.Dispose();
} }
private void BtPrintImage_Click(object sender, RoutedEventArgs e) { private void BtPrintImage_Click(object sender, RoutedEventArgs e) {
logger.Debug("Loading image for print"); logger.Debug("Invoking file selection dialogue.");
OpenFileDialog r = new OpenFileDialog { OpenFileDialog r = new OpenFileDialog {
Title="Select 1 (one) image file", Title="Select 1 (one) image file",
Multiselect=false, 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", 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 AutoUpgradeEnabled=true
}; };
if (r.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) { if(r.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) {
logger.Debug("Image load cancelled"); logger.Warn("PrintImage event but no file was selected.");
r.Dispose();
return; return;
} }
logger.Debug("Loading image for print");
Image _=Image.FromFile(r.FileName); Image _=Image.FromFile(r.FileName);
logger.Debug("Loaded image " + r.FileName); logger.Debug("Loaded image " + r.FileName);
r.Dispose(); r.Dispose();
logger.Debug("Disposed of dialog"); logger.Debug("Disposed of dialog");
Bitmap bimg=new Bitmap(_, (mmj.Printer.LineWidth*8), Bitmap bimg=new Bitmap(_, mmj.Printer.LineWidth*8,
(int)((double)(mmj.Printer.LineWidth*8)*(double)((double)_.Height/(double)_.Width))); (int)(mmj.Printer.LineWidth*8*(double)((double)_.Height/(double)_.Width)));
logger.Debug("Loaded image as Bitmap"); logger.Debug("Loaded image as Bitmap");
_.Dispose(); _.Dispose();
logger.Debug("Disposed of Image"); logger.Debug("Disposed of Image");
PrintBitmap(bimg); PrintBitmap(bimg);
bimg.Dispose();
} }
private void PrintBitmap(Bitmap bimg) { private void PrintBitmap(Bitmap bimg) {
bimg = CopyToBpp(bimg); bimg = CopyToBpp(bimg);
@ -172,17 +180,12 @@ namespace paperangapp {
for(int h = 0; h < hSzImg; h++) { for(int h = 0; h < hSzImg; h++) {
for(int w = 0; w < mmj.Printer.LineWidth; w++) { for(int w = 0; w < mmj.Printer.LineWidth; w++) {
iimg[(mmj.Printer.LineWidth * (hSzImg - 1 - h)) + (mmj.Printer.LineWidth - 1 - w)] = (byte)~ iimg[(mmj.Printer.LineWidth * (hSzImg - 1 - h)) + (mmj.Printer.LineWidth - 1 - w)] = (byte)~
(img[startoffset + (mmj.Printer.LineWidth * h) + (mmj.Printer.LineWidth - 1 - w)]); 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)"); logger.Debug($"Have {img.Length} bytes of print data ({mmj.Printer.LineWidth * 8}x{hSzImg}@1bpp)");
mmj.PrintBytes(iimg, false); 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)));
#region GDIBitmap1bpp #region GDIBitmap1bpp
static Bitmap CopyToBpp(Bitmap b) { static Bitmap CopyToBpp(Bitmap b) {
int w=b.Width, h=b.Height; int w=b.Width, h=b.Height;
@ -198,11 +201,11 @@ namespace paperangapp {
biXPelsPerMeter=1000000, biXPelsPerMeter=1000000,
biYPelsPerMeter=1000000 biYPelsPerMeter=1000000
}; };
bmi.biClrUsed=2; bmi.biClrUsed = 2;
bmi.biClrImportant=2; bmi.biClrImportant = 2;
bmi.cols=new uint[256]; bmi.cols = new uint[256];
bmi.cols[0]=MAKERGB(0, 0, 0); bmi.cols[0] = MAKERGB(0, 0, 0);
bmi.cols[1]=MAKERGB(255, 255, 255); bmi.cols[1] = MAKERGB(255, 255, 255);
IntPtr hbm0 = CreateDIBSection(IntPtr.Zero,ref bmi,DIB_RGB_COLORS,out _,IntPtr.Zero,0); IntPtr hbm0 = CreateDIBSection(IntPtr.Zero,ref bmi,DIB_RGB_COLORS,out _,IntPtr.Zero,0);
IntPtr sdc = GetDC(IntPtr.Zero); IntPtr sdc = GetDC(IntPtr.Zero);
IntPtr hdc = CreateCompatibleDC(sdc); IntPtr hdc = CreateCompatibleDC(sdc);
@ -248,7 +251,7 @@ namespace paperangapp {
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=256)] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=256)]
public uint[] cols; public uint[] cols;
} }
static uint MAKERGB(int r, int g, int b) => ((uint)(b&255)) | ((uint)((r&255)<<8)) | ((uint)((g&255)<<16)); static uint MAKERGB(int r, int g, int b) => ((uint)(b & 255)) | ((uint)((r & 255) << 8)) | ((uint)((g & 255) << 16));
#endregion #endregion
} }
} }