|

A little while ago, I had to build a desktop app that received input from devices which I had no control of. Although each implementation had similar requirements, the devices connected to the app were slightly different and so were the inputs received from them. I’ve looked for other similar implementations and found that some people implemented device specific parsers. Furthermore, they used configuration to select the correct parser. I think there is at least one issue with this approach: any change to the known inputs would require the application to change as well. Maybe there is a better way…

The trick I want to demonstrate relies on named group capturing from Regular Expression and a little fiddling with reflection.

Note: this technique works great for most scenarios but if you are looking for a super high performance solution, this is not for you.

Alright! Let’s see some code.

So with above code you can, for instance, parse a string that represents Product and Price into a typed object:

I find this most useful when you don’t really have control of the input, maybe it is a device input or a legacy system that just drop you some info. Regardless, this can save a bunch of time when the input changes or a new device needs to be supported.

You can find samples at my github repo.

Happy coding!

|

Fact check: market thermal label systems are freaking expensive. Maybe I could build my own label WYSIWYG designer? Should be simple, right?

To spice things up, I decided to try building this as a web solution. Thus, I started playing with html5 canvas to draw text, barcodes, rectangles and images. Once the design was created I could save the configuration for the items drawn and create actual printer specific commands.

A quick research showed that someone had already done something similar to what I wanted: Teynon’s Label Designer. However, the UI could use some improvement and it needed some features like content rotation, more control over layout properties and a document outline. Then I thought “go big or go home!” and decided to also convert the solution to typescript. Let the fun begin!

Check out the code on github

Or maybe just a demo

The cool stuff (context = canvas.getContext(“2d”)):

  • In order to add interactivity to the canvas, make it redraw itself after each user interaction. Although that can cause the canvas to refresh hundreds of times during a drag operation, it doesn’t really cause a noticeable performance impact.
  • Use context.fillText() to draw text
  • Use context.fillRect() to draw a rectangle
  • Use context.drawImage() to draw an image
  • Use JsBarcode to draw a barcode image into a canvas and transfer it to the main canvas by using context.drawImage(canvasWithBarcode[0], x, y)
  • To draw something rotated, first rotate the context itself context.rotate((angle * Math.pi) / 180) then draw the component desired and finally context.restore()

The not so cool stuff:

  • Scenario: you want to print a 3” x 4” label in a thermal printer that is 200DPI. The desired label should have a single text block of 1” in height or 200 dots. Your canvas measure a proportional size in pixels. Say 300px x 400px. Therefore it is rather easy to guess the text block should measure 100px (300px / 3”). Sounds easy? Unfortunately you won’t be able to translate everything, for instance, text blocks will require the actual printer fonts otherwise the final output won’t be loyal to the design.
  • The conversion of the canvas components metadata to printer command can be troublesome. There are multiple printer languages and each printer model has slight differences.

To make this work correctly it is essential that you have access to the printer fonts. Also, there might be some customization for each printer model you want to support.

That’s all for now. Have fun!