model¶
The SDK's vocabulary — the types that appear in the signature of every other Uncial module.
Features¶
- Zero dependencies: Kotlin stdlib only. No coroutines, no serialization, no io, no platform code.
- All targets: android, jvm, iosArm64, iosSimulatorArm64, iosX64.
- One coordinate model: every box is top-down pixels with the origin at the page's top-left, whichever engine produced it.
- A closed error set:
OcrErrorinstead ofnullplus a printed reason.
Core Components¶
Recognized text (…uncial.model.text)¶
OcrDocument:pages, plus derivedtext,lines,pageCount,isEmpty, and asource.OcrPage:index,size(in the same pixel units as the boxes on it),lines,orientation,source.OcrLine:text,box,fontSize,confidence,words,language,skewDegrees, plusscriptcomputed on demand.OcrWord:text,box,confidence. Only populated whenOcrOptions.includeWordsis set and the engine supports it.ExtractionSource:DigitalTextLayer,Ocr,Mixed— which path produced a page or document.ExtractionSource.of(pageSources)reduces per-page sources to a document-level one.Confidence: a@JvmInline value classoverFloat, normalized to0.0..1.0.Unknown(backed byNaN),Certain,of(normalized),ofPercent(percent)for Tesseract's0..100, plusisKnownandorElse(fallback). Comparable, withUnknownsorting below every known value.TextScript:Latin,Cyrillic,Mixed,Unknown, andTextScript.of(text)— coarser than a language on purpose, because engines tell scripts apart far more reliably than languages.
Geometry (…uncial.model.geometry)¶
Point,Size(withisEmpty).BoundingBox:left,top,width,height, withright,bottom,center,area,union(other)andBoundingBox.Zero.Orientation:Up,Right,Down,Left, each withdegrees. Coarse 90° page rotation — fine skew lives onOcrLine.skewDegrees.
Structure (…uncial.model.structure)¶
DocBlock: a sealed interface withtext, implemented byHeading(level, text)andParagraph(text). Produced bystructure, never by an engine.
Configuration and errors¶
OcrLanguage: deliberately not an enum, so bring-your-own.traineddatastays possible. ConstantsUkrainian,English,Default; anything else goes throughOcrLanguage.custom(tesseractCode, bcp47). Carries both identifiers the engines need —tesseractCodefor Tesseract,bcp47(nullable) for Vision. Custom codes are restricted to[A-Za-z0-9_-]{1,32}because the code becomes a filename and a URL segment.OcrOptions:languages,renderDpi(default 200),maxPageSide(default 2600),preferDigitalLayer,recognitionQuality,rasterColor,includeWords,pageRange, plus the derivedrenderScale. Validated ininit— an out-of-range dpi or a reversedpageRangeis rejected rather than silently producing nothing.OcrOptions.Fastis a preset at 150 dpi withRecognitionQuality.Fast.RecognitionQuality(Fast/Accurate) andRasterColor(Grayscale/Color).OcrError: a sealed class extendingException, so the same type works as aResultfailure in Kotlin and as a thrown, typed error in Swift. Cases:NoLanguageData(languages, searchedPath),RenderFailed(pageIndex),EngineInit,Unsupported,InvalidInput,RecognitionFailed(pageIndex).
Usage¶
document.pages.forEach { page ->
page.lines.forEach { line ->
if (line.confidence.isKnown && line.confidence.value < 0.6f) flagForReview(line)
}
}
There is no OcrError.Cancelled
Cancelling an extraction throws CancellationException, exactly as any other suspend
function would. Uncial never wraps it, so structured concurrency keeps working.
when over OcrError and DocBlock needs an else
Both hierarchies are expected to gain subtypes in minor releases — lists and tables for
DocBlock, new failure cases for OcrError.
OcrDocument.copy(pages = …) keeps the old source
source is a constructor property with a default derived from the pages, and copy()
does not re-run default arguments. Narrowing a Mixed document with copy leaves it
reporting Mixed; use the constructor instead so the default runs again.