{"id":47067141,"url":"https://github.com/steffest/boox-einkdraw","last_synced_at":"2026-03-13T06:01:05.442Z","repository":{"id":343476815,"uuid":"1174193679","full_name":"steffest/Boox-EinkDraw","owner":"steffest","description":"A native drawing app for the Oyux Boox series.","archived":false,"fork":false,"pushed_at":"2026-03-10T13:44:25.000Z","size":27483,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-12T08:46:58.787Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steffest.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-06T07:01:25.000Z","updated_at":"2026-03-12T00:42:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/steffest/Boox-EinkDraw","commit_stats":null,"previous_names":["steffest/boox-einkdraw"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/steffest/Boox-EinkDraw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steffest%2FBoox-EinkDraw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steffest%2FBoox-EinkDraw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steffest%2FBoox-EinkDraw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steffest%2FBoox-EinkDraw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steffest","download_url":"https://codeload.github.com/steffest/Boox-EinkDraw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steffest%2FBoox-EinkDraw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30459760,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T03:55:51.346Z","status":"ssl_error","status_checked_at":"2026-03-13T03:55:33.055Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-12T05:08:59.885Z","updated_at":"2026-03-13T06:01:05.434Z","avatar_url":"https://github.com/steffest.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Boox E-Ink Draw\n\nMinimal but fast Android drawing app focused on Onyx Boox e-ink devices, with priority on low stylus latency and stable stroke replay.\n\n![BooxDraw icon](docs/title.png)\n\n## Download and installation\nFetch the APK from the [releases](https://github.com/steffest/Boox-EinkDraw/releases/) page and install it on your Boox device.\n\n\n\n## What is this?\n\nThis project is a Boox-specific drawing app that combines:\n\n- Hardware pen preview (near-zero latency on e-ink)\n- Software canvas rendering (persistent bitmap/export/load)\n\nCurrent app includes:\n\n- Brush selector (exposing all hardware brush types found in their SDK)\n- Brush-width slider\n- Color swatches and color picker\n- Layer panel to manage layers\n- Full-screen drawing surface\n- Basic pinch zooming/panning\n\n## For what tablet?\n\nPrimary target and test device:\n\n- **Onyx Boox Note Air4C** (Android 13)\n\nThis app was made to scratch a personal itch.  \nIt probably can run on other Onyx Boox tablets that expose the same Onyx pen APIs, but behavior can vary by firmware/device generation.  \n(so it's very much a \"it works on my device\" project)\n\n## Hardware brushes available\n\nFrom `HardwarePenStyle`:\n\n- `PENCIL` (default width `5px`)\n- `FOUNTAIN` (`8px`)\n- `MARKER` (`20px`)\n- `NEO_BRUSH` (`12px`)\n- `CHARCOAL` (`10px`)\n- `DASH` (`5px`)\n- `CHARCOAL_V2` (`10px`)\n- `SQUARE_PEN` (`8px`)\n\nThese map to Onyx hardware stroke-style IDs used by `TouchHelper`.\n\n## File format\nNext to PNG, this app loads and saves the [Dpaint.js](https://dpaint.app/) format.  \nDpaint.js is my fully featured pixel drawing app. Dpaint.js works fine on the Boox tablet (install as chrome app recomended) - but as all generic 3rth party drawing apps, it is quite slow on the Boox tablet because it doesn't use the device specific hardware brushes.   \nThis app was created to fill that gap.  \nThe Dpaint.js file format supports layers and all other features found in this app.  \n\n## Onyx SDK\n\nthe Onyx Eink devices deliver a native zero-latency drawing experience. \nThis is achieved by using a hardware-driven pen experience: during drawing, the \"Android screen\" gets frozen and there is a direct communication line to the display controller, updating the screen with a pre-defined set of system brushes. \nThese strokes are then synced with the software app canvas.\n\nOnyx SDK documentation is sparse, missing or outdated. \nAPI behavior is partially firmware-dependent.  \n \nthis is is a call-out to Onyx to show there are developer out there that want to develop for your devices. Your low-latency Eink drawing libraries deliver a best-in-class drawing experience.  \nBut .... for peeps sake .... you make it VERY hard for developers to find the correct documentation needed to use these in their own apps.  \nPlease update your documentation and put out some recent code examples.\n\nThis app uses Onyx pen/e-ink APIs from:\n\n- `onyxsdk-base`\n- `onyxsdk-device`\n- `onyxsdk-pen`\n\nIt also bundles missing native-pen Java classes used by wrappers:\n\n- `app/libs/onyxsdk-pen-native-classes.jar`\n\nHowever ... these classes contain wrappers to functions that reside in `libneo_pen.so` - this a system library that only system apps can access.\n(so 3rth party apps can't use them directly)\n\nIn this project, a copy of this library is included.  \nAs this is a system-level library, it's device and firmware dependant, so it may very wall fail on your device.\n\n## Hardware-enabled drawing approach (zero-latency)\n\nCore idea: let the hardware path draw immediately, while software reconstruction happens in parallel.\n\n1. `TouchHelper` is created with `FEATURE_ALL_TOUCH_RENDER`.\n2. On brush/width/color changes, hardware is configured in strict order:\n   - width\n   - color\n   - limit rect\n   - `openRawDrawing()`\n   - style\n   - reapply width/color (some styles reset these internally)\n   - `setRawDrawingRenderEnabled(false)` for hardware preview\n   - enable/disable raw input based on UI suppression state\n3. During pen movement, `RawInputCallback` receives points.\n4. On pen-up, points are rendered into a software bitmap (`OnyxStrokeRenderer`).\n5. Hardware preview clears, software bitmap is shown, then e-ink refresh is triggered.\n\nThis gives low perceived latency while still producing a persistent/exportable canvas.\n\n\n## Moving from hardware preview to software canvas\n\nThis is the critical handoff path:\n\n1. Hardware preview draws live stroke immediately.\n2. Callback streams are collected:\n   - authority list stream (`onRawDrawingTouchPointListReceived`)\n   - raw move stream (`onRawDrawingTouchPointMoveReceived`)\n3. On pen-up:\n   - app selects the best point source (especially for charcoal where one stream can lose tilt/pressure fidelity)\n   - stroke is rendered into software canvas with matching brush renderer\n   - snapshot is updated for fast rebuild/clear/load paths\n4. `onPenUpRefresh` (or fallback timer) invalidates view so software result replaces hardware preview cleanly.\n\nImplementation anchors:\n\n- hardware bridge + callback orchestration: `HardwarePenSurfaceView`\n- per-brush software renderer: `OnyxStrokeRenderer`\n\n## Build requirements\n\n- Android Gradle Plugin: `8.6.1`\n- Kotlin plugin: `1.9.25`\n- Compile SDK / Target SDK: `34`\n- Min SDK: `26`\n- Java/Kotlin target: `17`\n\n## Build\n\n### Android Studio\n\n1. Open the project folder.\n2. Let Gradle sync.\n3. Connect Boox device (ADB USB or wireless).\n4. Run `app` on device.\n\n### Command line\n\n```bash\n./gradlew :app:assembleDebug\nadb install -r app/build/outputs/apk/debug/app-debug.apk\n```\n\n\n## Known missing features / shortcomings:\n\n- Zooming is supported, but when zoomed-in, the direct mapping between hardware enabled system brushes and the software canvas falls apart very quickly. This means that the zero-latency hardware preview of the stroke won't match the end result on the canvas all that well when drawing on a zoomed in canvas.\n- undo/redo is not there yet (just think of it like real paper :-)\n\nIt is not my goal to build a fully features drawing app for android.\n(I have [dpaint.js](https://github.com/steffest/DPaint-js) for that - which works fine on Android tablets as installed Chrome app.)  \nThis project might be useful for other devs as example how to use the Boox hardware brushes in your own app.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteffest%2Fboox-einkdraw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteffest%2Fboox-einkdraw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteffest%2Fboox-einkdraw/lists"}