Skip to content

Instantly share code, notes, and snippets.

@mustafardestroyer
Last active November 10, 2020 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mustafardestroyer/b58cfb73f680a903048308de76f40482 to your computer and use it in GitHub Desktop.
Save mustafardestroyer/b58cfb73f680a903048308de76f40482 to your computer and use it in GitHub Desktop.
MyScript Recognition
import Foundation
import Combine
import os
func initIInkEngine() -> IINKEngine? {
// Check that the MyScript certificate is present
if myCertificate.length == 0 {
os_log(.error, "Could not locate MyScript certificate")
return nil
}
// Create the iink runtime environment
let data = Data(bytes: myCertificate.bytes, count: myCertificate.length)
guard let engine = IINKEngine(certificate: data) else {
os_log(.error, "Invalid MyScript certificate")
return nil
}
// Configure the iink runtime environment
let configurationPath = Bundle.main.bundlePath.appending("/recognition-assets/conf")
do {
try engine.configuration.setStringArray(
[configurationPath], forKey: "configuration-manager.search-path"
) // Tells the engine where to load the recognition assets from.
} catch {
os_log(.error, "MyScript error, please check your resources assets: %@", error.localizedDescription)
return nil
}
// Set the temporary directory
do {
try engine.configuration.setString(NSTemporaryDirectory(), forKey: "content-package.temp-folder")
} catch {
os_log(.error, "Failed to set temporary folder: %@", error.localizedDescription)
return nil
}
do {
// Recommended for off-screen usage
try engine.configuration.setBoolean(false, forKey: "text.guides.enable")
} catch {
os_log(.error, "Failed disable myscript guides: %@", error.localizedDescription)
return nil
}
return engine
}
func initEditor(engine: IINKEngine) -> IINKEditor? {
let renderer = try! engine.createRenderer(
withDpiX: AppConstants.NcodeDPI,
dpiY: AppConstants.NcodeDPI,
target: nil,
error: ()
)
guard let editor = engine.createEditor(renderer) else {
return nil
}
let fontMetricsProvider = FontMetricsProvider()
editor.setFontMetricsProvider(fontMetricsProvider)
var error: NSError?
editor.setViewSize(
CGSize(width: IdeaPadSpec.NcodeWidth, height: IdeaPadSpec.NcodeHeight),
error: &error
)
if error != nil {
os_log(.error, "Failed to set view size: %@", error!.localizedDescription)
return nil
}
var package: IINKContentPackage
package = try! engine.createPackage("text_\(UUID().uuidString).iink")
let part = try! package.createPart("Text")
editor.setPart(part, error: &error)
if error != nil {
os_log(.error, "Could not set MyScript Part: %@", error!.localizedDescription)
return nil
}
return editor
}
protocol HandwritingRecognizer {
func pointerDown(xStart: Double, yStart: Double)
func pointerMove(xNew: Double, yNew: Double)
func pointerUp(xEnd: Double, yEnd: Double)
func generateText() -> Future<String, TranscriptionError>
}
class MyScriptHandwritingRecognizer: HandwritingRecognizer {
var editor: IINKEditor
var events = [IINKPointerEvent]()
init(editor: IINKEditor) {
self.editor = editor
}
func pointerDown(xStart: Double, yStart: Double) {
events.append(
IINKPointerEventMakeDown(
CGPoint(x: xStart, y: yStart),
-1, // at
1.0, // force
.pen, // type
-1 // pointerId
)
)
}
func pointerMove(xNew: Double, yNew: Double) {
events.append(
IINKPointerEventMakeMove(
CGPoint(x: xNew, y: yNew),
-1, // at
1.0, // force
.pen, // type
-1 // pointerId
)
)
}
func pointerUp(xEnd: Double, yEnd: Double) {
events.append(
IINKPointerEventMakeUp(
CGPoint(x: xEnd, y: yEnd),
-1, // at
1.0, // force
.pen, // type
-1 // pointerId
)
)
}
func generateText() -> Future<String, TranscriptionError> {
let eventsCount = self.events.count
return Future { promise in
let result = self.events.withUnsafeMutableBufferPointer { (
eventsPtr: inout UnsafeMutableBufferPointer<IINKPointerEvent>
) in
return eventsPtr.baseAddress?.withMemoryRebound(
to: IINKPointerEvent.self, capacity: eventsCount, { ptr -> String in
do {
try self.editor.pointerEvents(ptr, count: eventsCount, doProcessGestures: false)
} catch {
return "Sorry, there was an error transcribing this page."
}
self.editor.waitForIdle()
let result = try! self.editor.export_(self.editor.rootBlock, mimeType: .text)
return result
})
}
self.editor.clear()
self.events.removeAll()
promise(.success(result!))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment