some changes
This commit is contained in:
parent
734ebf47e1
commit
471c9e5165
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace liblogtiny {
|
||||
namespace liblogtiny {
|
||||
public partial class LogTiny {
|
||||
public enum LogLevel {
|
||||
Trace,
|
||||
|
|
|
@ -5,26 +5,29 @@ using System.Linq;
|
|||
namespace libpaperang.Helpers {
|
||||
public class CRC {
|
||||
private uint _iv;
|
||||
public uint iv { get => ~_iv; private set => _iv=~value; }
|
||||
public uint mv = 0x35769521;
|
||||
public uint Iv { get => ~_iv; private set => _iv = ~value; }
|
||||
public uint Mv => 0x35769521u;
|
||||
private uint poly = 0xedb88320;
|
||||
private uint[] crctable;
|
||||
public bool IsInitialised=false;
|
||||
public CRC(bool autoinit = true) {
|
||||
iv = 0;
|
||||
if(autoinit) Initialise();
|
||||
Iv = 0;
|
||||
if(autoinit)
|
||||
Initialise();
|
||||
}
|
||||
public CRC(uint iv, bool autoinit = true) {
|
||||
this.iv = iv;
|
||||
if (autoinit) Initialise();
|
||||
Iv = iv;
|
||||
if(autoinit)
|
||||
Initialise();
|
||||
}
|
||||
public void Initialise() {
|
||||
crctable = Enumerable.Range(0, 256).Select(i => {
|
||||
uint e=(uint)i;
|
||||
for (ushort eb = 0; eb<8; eb++)
|
||||
for(ushort eb = 0; eb < 8; eb++) {
|
||||
e = ((e & 1) != 0)
|
||||
? (poly ^ (e >> 1))
|
||||
: (e >> 1);
|
||||
}
|
||||
return e;
|
||||
}).ToArray();
|
||||
IsInitialised = true;
|
||||
|
@ -33,12 +36,13 @@ namespace libpaperang.Helpers {
|
|||
uint ivr=0;
|
||||
for(int i = 0; i < 32; i++) {
|
||||
uint b=(iv>>i)&1;
|
||||
ivr|=(b<<(31-i));
|
||||
ivr |= b << (31 - i);
|
||||
}
|
||||
return ~ivr;
|
||||
}
|
||||
public uint GetChecksumUint<T>(IEnumerable<T> data) {
|
||||
if (!IsInitialised) throw new CrcNotAvailableException();
|
||||
if(!IsInitialised)
|
||||
throw new CrcNotAvailableException();
|
||||
try {
|
||||
return ~data.Aggregate(_iv,
|
||||
(cti, cb) => crctable[(cti & 0xFF) ^ Convert.ToByte(cb)] ^ (cti >> 8));
|
||||
|
@ -51,9 +55,7 @@ namespace libpaperang.Helpers {
|
|||
}
|
||||
}
|
||||
public byte[] GetChecksumBytes<T>(IEnumerable<T> data) => BitConverter.GetBytes(GetChecksumUint(data));
|
||||
public uint GetCrcIv() => iv == mv
|
||||
? iv
|
||||
: iv ^ mv;
|
||||
public uint GetCrcIv() => Iv == Mv ? Iv : Iv ^ Mv;
|
||||
public byte[] GetCrcIvBytes() => BitConverter.GetBytes(GetCrcIv());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
namespace libpaperang.Helpers {
|
||||
class Media {
|
||||
}
|
||||
}
|
|
@ -13,16 +13,22 @@ namespace libpaperang.Helpers {
|
|||
}
|
||||
public byte[] Oper(BaseTypes.Operations Operation) {
|
||||
switch(Operation) {
|
||||
case BaseTypes.Operations.NoOp: return Op.NoOp;
|
||||
case BaseTypes.Operations.LineFeed: return Op.LineFeed;
|
||||
case BaseTypes.Operations.CrcTransmit: return Op.TransmitCrc;
|
||||
case BaseTypes.Operations.Print: return Op.Print;
|
||||
default: throw new InvalidOperationException();
|
||||
case BaseTypes.Operations.NoOp:
|
||||
return Op.NoOp;
|
||||
case BaseTypes.Operations.LineFeed:
|
||||
return Op.LineFeed;
|
||||
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) {
|
||||
switch(Operation) {
|
||||
case BaseTypes.Operations.LineFeed: return BitConverter.GetBytes(SwapWordEndianness(
|
||||
case BaseTypes.Operations.LineFeed:
|
||||
return BitConverter.GetBytes(SwapWordEndianness(
|
||||
0x00000000 | (((((
|
||||
Data & 0xffu) << 16) |
|
||||
Data) & 0xffff00u) >> 8))).Skip(2).ToArray();
|
||||
|
@ -31,7 +37,8 @@ namespace libpaperang.Helpers {
|
|||
0x00010000 | (((((
|
||||
Data & 0xffu) << 16) |
|
||||
Data) & 0xffff00u) >> 8)));
|
||||
default: throw new InvalidOperationException();
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
public byte[] Packet(byte[] oper, byte[] data, CRC checksum) {
|
||||
|
|
|
@ -55,6 +55,8 @@ namespace libpaperang {
|
|||
}
|
||||
public interface IPrinter {
|
||||
short LineWidth { get; }
|
||||
short BasePrintDelay { get; }
|
||||
uint MaximumDataSize { get; }
|
||||
BaseTypes.Connection ConnectionMethod { get; }
|
||||
BaseTypes.Model PrinterVariant { get; }
|
||||
BaseTypes.State Status { get; }
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace libpaperang.Interfaces {
|
|||
// constants
|
||||
private const ushort iV = 0x4348;
|
||||
private const ushort iP = 0x5584;
|
||||
private const short MaxDataSize = 1008;
|
||||
public uint MaximumDataSize => 1008;
|
||||
|
||||
// types
|
||||
private struct UsbComms {
|
||||
|
@ -20,21 +20,35 @@ namespace libpaperang.Interfaces {
|
|||
public UsbEndpointWriter tx;
|
||||
}
|
||||
private UsbComms Printer;
|
||||
private BaseTypes.Model iModel;
|
||||
private bool _initialised=false;
|
||||
|
||||
public short LineWidth {
|
||||
get {
|
||||
switch (iModel) {
|
||||
case BaseTypes.Model.P1: return 48;
|
||||
case BaseTypes.Model.P2: return 72;
|
||||
case BaseTypes.Model.P2S: return 72; //assumption
|
||||
case BaseTypes.Model.T1: throw new PrinterVariantNotSupportedException();
|
||||
default: throw new InvalidOperationException();
|
||||
switch(PrinterVariant) {
|
||||
case BaseTypes.Model.P1:
|
||||
return 48;
|
||||
case BaseTypes.Model.P2:
|
||||
return 72;
|
||||
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.Model PrinterVariant => iModel;
|
||||
public BaseTypes.Model PrinterVariant { get; private set; }
|
||||
public BaseTypes.State Status => BaseTypes.State.Offline;
|
||||
public List<BaseTypes.Printer> AvailablePrinters {
|
||||
get {
|
||||
|
@ -52,25 +66,8 @@ namespace libpaperang.Interfaces {
|
|||
}
|
||||
}
|
||||
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 void ClosePrinter() => Printer.handle?.Close();
|
||||
public void Deinitialise() {
|
||||
Printer.rx?.Dispose();
|
||||
Printer.tx?.Dispose();
|
||||
_ = Printer.iface?.ReleaseInterface(0);
|
||||
_ = Printer.iface?.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);
|
||||
_initialised = true;
|
||||
}
|
||||
public void OpenPrinter(BaseTypes.Printer printer) {
|
||||
bool res;
|
||||
try {
|
||||
|
@ -78,7 +75,27 @@ namespace libpaperang.Interfaces {
|
|||
} catch(Exception) {
|
||||
throw new PrinterNotAvailableException();
|
||||
}
|
||||
if (!res) throw new PrinterNotAvailableException();
|
||||
if(!res)
|
||||
throw new PrinterNotAvailableException();
|
||||
}
|
||||
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() {
|
||||
Printer.rx?.Dispose();
|
||||
Printer.tx?.Dispose();
|
||||
_ = Printer.iface?.ReleaseInterface(0);
|
||||
_ = Printer.iface?.Close();
|
||||
ClosePrinter();
|
||||
}
|
||||
public byte[] ReadBytes() {
|
||||
byte[] readbuf=new byte[1024];
|
||||
|
@ -91,6 +108,6 @@ namespace libpaperang.Interfaces {
|
|||
Thread.Sleep(delay);
|
||||
return _;
|
||||
}
|
||||
public USB(BaseTypes.Model model) => iModel=model;
|
||||
public USB(BaseTypes.Model model) => PrinterVariant = model;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using libpaperang.Helpers;
|
||||
using libpaperang.Interfaces;
|
||||
using liblogtiny;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using liblogtiny;
|
||||
using libpaperang.Helpers;
|
||||
using libpaperang.Interfaces;
|
||||
|
||||
namespace libpaperang.Main {
|
||||
public class Paperang {
|
||||
|
@ -75,7 +75,7 @@ namespace libpaperang.Main {
|
|||
logger?.Trace($"PrintBytes() invoked with data length of {data.Length}");
|
||||
List<byte[]> segments = data
|
||||
.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())
|
||||
.ToList();
|
||||
logger?.Trace($"data split into {segments.Count} segment(s)");
|
||||
|
@ -84,7 +84,9 @@ namespace libpaperang.Main {
|
|||
Transform.Arg(BaseTypes.Operations.Print, (uint)b.Length),
|
||||
b,
|
||||
Crc),
|
||||
200-(b.Length/Printer.LineWidth)));
|
||||
Printer.BasePrintDelay + (b.Length / Printer.LineWidth)));
|
||||
if(autofeed)
|
||||
Feed(185);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using liblogtiny;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
using liblogtiny;
|
||||
|
||||
namespace paperangapp {
|
||||
class LUITextbox : ILogTiny, INotifyPropertyChanged {
|
||||
|
@ -11,9 +11,9 @@ namespace paperangapp {
|
|||
//get { return _LogBuffer; }
|
||||
get => _LogBuffer;
|
||||
set {
|
||||
if (value == _LogBuffer) return;
|
||||
if (value == "!clearlog") _LogBuffer = "";
|
||||
else _LogBuffer = value + "\n" + _LogBuffer;
|
||||
if(value == _LogBuffer)
|
||||
return;
|
||||
_LogBuffer = value == "!clearlog" ? "" : value + "\n" + _LogBuffer;
|
||||
OnPropertyChanged("LogBuffer");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
using liblogtiny;
|
||||
using libpaperang;
|
||||
using libpaperang.Interfaces;
|
||||
using libpaperang.Main;
|
||||
using System;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
//testing
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
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 {
|
||||
public partial class MainWindow : Window {
|
||||
|
@ -25,7 +24,7 @@ namespace paperangapp {
|
|||
UnInitDev,
|
||||
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?
|
||||
public MainWindow() {
|
||||
InitializeComponent();
|
||||
|
@ -35,14 +34,14 @@ namespace paperangapp {
|
|||
usbpoll = new System.Timers.Timer(200) {
|
||||
AutoReset = true
|
||||
};
|
||||
usbpoll.Elapsed += evtUsbPoll;
|
||||
usbpoll.Elapsed += EvtUsbPoll;
|
||||
usbpoll.Start();
|
||||
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 void dgtUsbPoll() {
|
||||
private void DgtUsbPoll() {
|
||||
try {
|
||||
if(state == AppState.UnInitNoDev && prtr.PrinterAvailable) {
|
||||
btInitUSB.IsEnabled = true;
|
||||
|
@ -63,7 +62,8 @@ namespace paperangapp {
|
|||
|
||||
~MainWindow() {
|
||||
logger.Warn("Application closing");
|
||||
if(mmj!=null) USBDeInit();
|
||||
if(mmj != null)
|
||||
USBDeInit();
|
||||
}
|
||||
private void BtClearLog_Click(object sender, RoutedEventArgs e) =>
|
||||
logger.Raw("!clearlog");
|
||||
|
@ -115,9 +115,14 @@ namespace paperangapp {
|
|||
}
|
||||
private void BtFeed_Click(object sender, RoutedEventArgs e) => mmj.Feed((uint)slFeedTime.Value);
|
||||
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));
|
||||
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();
|
||||
Bitmap b=new Bitmap(mmj.Printer.LineWidth*8, (int)szText.Height);
|
||||
g = Graphics.FromImage(b);
|
||||
|
@ -125,14 +130,14 @@ namespace paperangapp {
|
|||
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));
|
||||
TextRenderer.DrawText(g, txInput.Text, fnt, new System.Drawing.Point(0, 0), Color.Black);
|
||||
g.Flush();
|
||||
PrintBitmap(b);
|
||||
g.Dispose();
|
||||
b.Dispose();
|
||||
}
|
||||
private void BtPrintImage_Click(object sender, RoutedEventArgs e) {
|
||||
logger.Debug("Loading image for print");
|
||||
logger.Debug("Invoking file selection dialogue.");
|
||||
OpenFileDialog r = new OpenFileDialog {
|
||||
Title="Select 1 (one) image file",
|
||||
Multiselect=false,
|
||||
|
@ -140,19 +145,22 @@ namespace paperangapp {
|
|||
AutoUpgradeEnabled=true
|
||||
};
|
||||
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;
|
||||
}
|
||||
logger.Debug("Loading image for print");
|
||||
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)));
|
||||
Bitmap bimg=new Bitmap(_, mmj.Printer.LineWidth*8,
|
||||
(int)(mmj.Printer.LineWidth*8*(double)((double)_.Height/(double)_.Width)));
|
||||
logger.Debug("Loaded image as Bitmap");
|
||||
_.Dispose();
|
||||
logger.Debug("Disposed of Image");
|
||||
PrintBitmap(bimg);
|
||||
bimg.Dispose();
|
||||
}
|
||||
private void PrintBitmap(Bitmap bimg) {
|
||||
bimg = CopyToBpp(bimg);
|
||||
|
@ -172,17 +180,12 @@ namespace paperangapp {
|
|||
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)]);
|
||||
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)));
|
||||
#region GDIBitmap1bpp
|
||||
static Bitmap CopyToBpp(Bitmap b) {
|
||||
int w=b.Width, h=b.Height;
|
||||
|
|
Loading…
Reference in New Issue