Skip to content

Post-Math/Ncode-SDK-for-Linux

Postmath Ncode SDK for Linux

A Go SDK for generating Ncode-overlaid PDFs that the NeoLAB Neo smartpen can read, on Linux, macOS, and Windows.

A community SDK that complements — and on Linux, fills the gaps of — the official NeoLAB / NeoSmartpen Ncode-SDK 2.0.

Heads-up: the official SDK is the upstream source of truth for the dot-pattern algorithm. If you are starting from scratch on Windows and don't need any of the contributions below, you should use it directly.

What this SDK adds on top of the official one

  1. Linux / macOS support. The official SDK ships a single Windows-only NeoLABNcodeSDK.dll and was authored against Windows path semantics. The DLL's GetImage() writes its output by concatenating workingFolder + "\\" + filename, with a literal backslash, which on Linux / macOS produces a file whose name contains a backslash — and the SDK's catch-all error handler then reports failure code 380 with no useful diagnostic. We patched this in tools/ncode-cli so the same managed DLL runs correctly under Mono 6.8+ on Linux. See docs/linux-support.md and tools/ncode-cli/MONO_PATH_WORKAROUND.md for the full diagnosis and fix.

  2. 3-pixel triangle and 4-pixel custom dot-pattern dilation kernels. The official SDK exposes only isBold = {false, true} for ink-footprint shaping (1 px or a 2×2 cluster). On real laser printers, the 1 px dot gets eaten by the halftone screen and the 2×2 cluster is heavier than needed — both of these affect pen recognition rates. This SDK adds:

    • Tri3Up / Tri3Down (3-pixel triangles, alternated row-major to average out halftone interaction with a single orientation — the recommended production default),
    • Tri4Up / Tri4Down (4-pixel filled triangles),
    • Diamond4 (4-pixel cardinal diamond — same ink count as isBold's 2×2 cluster but visually lighter),

    plus the generic ApplyKernel / ApplySquare / ApplyDisc / ApplyAlternating transforms in pattern/kernels. Every kernel keeps its footprint within ±1 pixel of the original SDK pixel — well inside the ~9 px Anoto cell pitch at 600 DPI — so the pen's IR camera reads the same Ncode coordinate regardless of kernel choice. See docs/kernels.md.

  3. Idiomatic Go API for the K-removal + ImageMask overlay pipeline. The official samples ship in C++ (with MuPDF) and C# (with Datalogics Adobe PDFL). This repo packages the equivalent pipeline as a single pdf.Publish() call backed by pdfcpu, go-fitz (MuPDF bindings), and hhrutter/tiff. No Datalogics licence required.

Repository layout

Path Purpose
ncode/ Domain types: NcodeType, Ticket, PageID, Page, PaperSize, DotMode.
pattern/ Bitmap, Generator interface, Request.
pattern/neolab/ Production Generator that drives the C# wrapper subprocess (Mono on Linux/macOS).
pattern/stub/ Deterministic non-pen-readable Generator for SDK-internal tests and downstream test suites. NOT for production.
pattern/kernels/ Tri3 / Tri4 / Diamond4 dilation kernels and bitmap transforms.
pdf/ K-removal compositor, A4 sizing, two-layer ImageMask injection, Publish() entry point.
tools/ncode-cli/ C# console that wraps NeoLABNcodeSDK.dll. Includes the Mono path-workaround.
examples/publish/ Production end-to-end example. Requires NeoLAB credentials; no offline fallback.
examples/discover-tickets/ Production example: enumerate the (section, owner, book, page) ranges your app key is provisioned for.
docs/ Linux support notes, kernel rationale, pipeline overview.

Quick start

import (
    "context"

    "github.com/Post-Math/Ncode-SDK-for-Linux/ncode"
    "github.com/Post-Math/Ncode-SDK-for-Linux/pattern/kernels"
    "github.com/Post-Math/Ncode-SDK-for-Linux/pattern/neolab"
    "github.com/Post-Math/Ncode-SDK-for-Linux/pdf"
)

ticket := ncode.Ticket{
    Type:       ncode.NcodeTypeN3C6,
    Section:    3,
    OwnerStart: 100, OwnerSize: 1,
    BookStart:  0,   BookSize:  1,
    PageStart:  0,   PageSize:  64,
}

_, err := pdf.Publish(context.Background(), pdf.PublishRequest{
    Input:     "input.pdf",
    Output:    "output-ncoded.pdf",
    Generator: neolab.Generator{
        ExePath: "/opt/ncode-cli/ncode-cli.exe",
        AppKey:  os.Getenv("NCODE_APPKEY"),
    },
    Ticket:           ticket,
    DPI:              600,
    DotMode:          ncode.DotModeLine,
    DilationKernel:   kernels.Tri3Up,
    DilationKernelB:  kernels.Tri3Down,
}, nil)

Two runnable versions live in examples/:

  • examples/publish — full publishing flow, takes one source PDF in and writes one Ncoded PDF out.
  • examples/discover-tickets — enumerate the ticket ranges your app key is provisioned for and print the first PageID each one resolves to. Useful as the first step before running examples/publish, since the (section, owner, book, page) values it expects are NeoLAB-allocated, not freely chosen.

Both examples require NeoLAB-issued assets and do not fall back to any offline mode. For offline development see Running the test suite without NeoLAB credentials below.

Running the test suite without NeoLAB credentials

go test ./... runs end-to-end on a clean machine without any NeoLAB credentials, the proprietary SDK binary, or Mono. The PDF pipeline tests synthesise a sample input PDF at runtime via pdfcpu and feed it through Publish using the SDK-internal stub Generator in pattern/stub.

pattern/stub is exported so downstream codebases can use it the same way: drop stub.Generator{} anywhere a pattern.Generator is expected to write integration tests for your wrapping code.

The stub's output is uniform-grid noise, not an Anoto pattern; the Neo smartpen will reject any document produced with it. Use the stub only in tests and never in production paths.

Runtime requirements (production / pen-readable output)

These apply when running either example, or any code path that uses the pattern/neolab Generator.

  • Go 1.25+ with CGo enabled (go-fitz statically links MuPDF).
  • A NeoLAB-issued application secret key (the "appSecretKey"), obtained through NeoLAB's technical-agreement programme.
  • NeoLABNcodeSDK.dll from the official Ncode-SDK 2.0 release (.NET Framework 4.5, x64). This SDK does not redistribute that DLL — by NeoLAB licensing policy it must come from your own agreement. Drop it next to tools/ncode-cli/NcodeCli.csproj and follow that directory's README to build ncode-cli.exe.
  • On Linux/macOS: Mono 6.8+ and libgdiplus 6.1+. On Windows: nothing extra.
  • Outbound network access to api.neolab.net while running the generator (the DLL's GetTickets() and GenerateNcode() are REST calls).

Licensing

Source code in this repository is published under the Apache License 2.0. See LICENSE for the full notice. The license covers only the code in this repository and not the proprietary NeoLAB SDK binary, the Anoto pattern algorithm itself, or any NeoSmartpen trademarks; those require separate agreements with NeoLAB / Anoto.

AGPL-3.0 transitive dependency (read before distributing binaries)

The pdf package depends on go-fitz, which statically links MuPDF (AGPL-3.0) via cgo. The Apache-2.0 licence of this repository's source code is unaffected, but any binary that imports github.com/Post-Math/Ncode-SDK-for-Linux/pdf is a combined work that incorporates AGPL-3.0 code. Redistributing such a binary — or running it as a network-accessible service — triggers AGPL-3.0 obligations (notably §13 source-availability for network use).

If AGPL-3.0 is not acceptable for your distribution model:

  • The ncode/, pattern/, pattern/kernels/, pattern/neolab/, and pattern/stub/ packages do not import go-fitz and are unaffected. You can use them without triggering the AGPL transitive obligation — at the cost of bringing your own source-PDF rendering step.
  • Alternatively, acquire a commercial MuPDF licence from Artifex Software, or replace the rendering step with a non-AGPL library.

See LICENSE for the full third-party notice. This is informational and not legal advice.

Contributing

Issues and pull requests welcome. Please describe the printer / driver combination on which you observed any kernel or dot-mode behaviour you report — pen-recognition results are sensitive to the halftone characteristics of the specific RIP in use.

Contributors

jphan32
jphan32

Acknowledgements

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors