@@ -17,7 +17,6 @@ import com.myscript.iink.HandwritingResult
1717import com.myscript.iink.IHandwritingGeneratorListener
1818import com.myscript.iink.MimeType
1919import com.myscript.iink.PointerEvent
20- import com.myscript.iink.PredefinedHandwritingProfileId
2120import com.myscript.iink.graphics.Transform
2221import com.myscript.iink.samples.hwgeneration.None.word
2322import kotlinx.coroutines.Dispatchers
@@ -40,23 +39,28 @@ data class Message(
4039}
4140
4241data class GenerationProfile (
43- val id : PredefinedHandwritingProfileId = PredefinedHandwritingProfileId . DEFAULT ,
42+ val index : Int = 0 ,
4443 val profilePath : String? = null ) {
4544
4645 companion object {
47- fun fromId (id : PredefinedHandwritingProfileId ): GenerationProfile {
46+ fun fromId (id : Int ): GenerationProfile {
4847 return GenerationProfile (id, null )
4948 }
5049
5150 fun fromPath (path : String ): GenerationProfile {
52- return GenerationProfile (PredefinedHandwritingProfileId . DEFAULT , path)
51+ return GenerationProfile (- 1 , path)
5352 }
5453 }
5554}
5655
56+ enum class HWGLanguage {
57+ ENGLISH ,
58+ CHINESE
59+ }
60+
5761class GenerationViewModel (application : Application , private val engine : Engine ) : AndroidViewModel(application) {
5862
59- private val generator: HandwritingGenerator
63+ private var generator: HandwritingGenerator ? = null
6064
6165 private val _isGenerating = MutableLiveData (false )
6266 val isGenerating: LiveData <Boolean >
@@ -70,34 +74,60 @@ class GenerationViewModel(application: Application, private val engine: Engine)
7074 val hwrResults: LiveData <List <HWRResult >>
7175 get() = _hwrResults
7276
73- private var _message = MutableLiveData <Message ?>(null )
77+ private val _message = MutableLiveData <Message ?>(null )
7478 val message: LiveData <Message ?>
7579 get() = _message
7680
81+ private val _language = MutableLiveData (DEFAULT_LANGUAGE )
82+ val language: LiveData <HWGLanguage >
83+ get() = _language
84+
7785 init {
7886 _isGenerating .value = false
7987
80- generator = engine.createHandwritingGenerator( )
88+ setLanguage( DEFAULT_LANGUAGE )
8189 }
8290
8391 private interface HWResultListener {
8492 fun onResult (result : HWRResult )
8593 }
8694
95+ fun setLanguage (language : HWGLanguage ) {
96+ if (generator != null && _language .value == language) return
97+
98+ generator?.cancel()
99+
100+ engine.configuration.apply {
101+ when (language) {
102+ HWGLanguage .ENGLISH -> setString(" handwriting-generation.init.resource" ," en-hw-gen.res" )
103+ HWGLanguage .CHINESE -> setString(" handwriting-generation.init.resource" ," zh-hw-gen.res" )
104+ }
105+ }
106+ generator = engine.createHandwritingGenerator()
107+
108+ viewModelScope.launch(Dispatchers .Main ) {
109+ _language .value = language
110+ }
111+ }
112+
87113 fun cancel () {
88- generator.cancel()
114+ generator? .cancel()
89115 viewModelScope.launch(Dispatchers .Main ) {
90116 _isGenerating .value = false
91117 _hwrResults .value = emptyList()
92118 }
93119 }
94120
95121 fun getProfiles (): List <GenerationProfile > {
122+ val generator = generator ? : return emptyList()
123+
96124 val userProfiles = File (getApplication<Application >().filesDir, PROFILE_FOLDER ).listFiles()?.map { file ->
97125 GenerationProfile .fromPath(file.absolutePath)
98126 } ? : emptyList()
99127
100- val predefinedProfiles = PredefinedHandwritingProfileId .entries.toList().map {
128+ var predefinedProfiles = generator.createHandwritingProfileBuilder().predefinedProfileCount.let { count ->
129+ (0 until count).toList()
130+ }.map {
101131 GenerationProfile .fromId(it)
102132 }
103133
@@ -113,6 +143,8 @@ class GenerationViewModel(application: Application, private val engine: Engine)
113143 }
114144
115145 private fun buildProfileInternal (selection : ContentSelection ? = null, iinkFile : File ? = null) {
146+ val generator = generator ? : return
147+
116148 viewModelScope.launch(Dispatchers .Main ) {
117149 _isProfileBuilding .value = true
118150
@@ -147,14 +179,14 @@ class GenerationViewModel(application: Application, private val engine: Engine)
147179 }
148180 }
149181
150- fun generateHandwriting (inputSentence : String , generationProfile : GenerationProfile , inputTextSize : Float , inputX : Float , inputY : Float , width : Float , transform : Transform ) {
182+ fun generateHandwriting (inputSentence : String , generationProfile : GenerationProfile , inputTextSize : Float , inputX : Float , inputY : Float , width : Float , transform : Transform , forceRandomSeed : Boolean = false ) {
151183 if (inputSentence.isEmpty()) return
152184
153185 viewModelScope.launch(Dispatchers .Main ) {
154186 _isGenerating .value = true
155187
156188 withContext(Dispatchers .IO ) {
157- generate(inputSentence, generationProfile, inputTextSize, inputX, inputY, width, transform, object : HWResultListener {
189+ generate(inputSentence, generationProfile, inputTextSize, inputX, inputY, width, transform, forceRandomSeed, object : HWResultListener {
158190 override fun onResult (result : HWRResult ) {
159191 viewModelScope.launch(Dispatchers .Main ) {
160192 val previousList: MutableList <HWRResult > = _hwrResults .value?.toMutableList() ? : mutableListOf ()
@@ -168,20 +200,22 @@ class GenerationViewModel(application: Application, private val engine: Engine)
168200 }
169201 }
170202
171- private fun generate (sentence : String , generationProfile : GenerationProfile , textSize : Float , xOffset : Float , yOffset : Float , width : Float , transform : Transform , listener : HWResultListener ): HWRResult {
203+ private fun generate (sentence : String , generationProfile : GenerationProfile , textSize : Float , xOffset : Float , yOffset : Float , width : Float , transform : Transform , forceRandomSeed : Boolean , listener : HWResultListener ): HWRResult {
204+ val generator = generator ? : return None
205+
172206 val builder = generator.createHandwritingProfileBuilder()
173207
174208 val profile = if (generationProfile.profilePath != null && File (generationProfile.profilePath).exists()) {
175209 builder.load(generationProfile.profilePath)
176210 } else {
177- builder.createFromId (generationProfile.id )
211+ builder.getPredefinedProfileAt (generationProfile.index )
178212 }
179213
180214 val indexLock = Any ()
181215 var currentPointerEventIndex = 0
182216 var wordIndex = 0
183217
184- val words = sentence.split(" " ).filter { it.isNotEmpty() }
218+ val words = sentence.split(" " ).map { " $it " }
185219
186220 generator.setListener(object : IHandwritingGeneratorListener {
187221 override fun onPartialResult (generator : HandwritingGenerator , result : HandwritingResult ) {
@@ -201,7 +235,9 @@ class GenerationViewModel(application: Application, private val engine: Engine)
201235 })
202236
203237 generator.start(" Text" , profile, engine.createParameterSet().apply {
204- setBoolean(" handwriting-generation.session.force-new-line" , false )
238+ setBoolean(" handwriting-generation.session.preserve-new-line" , language.value != HWGLanguage .CHINESE )
239+
240+ setNumber(" handwriting-generation.session.seed" , if (forceRandomSeed) 0L else - 1 )
205241
206242 val invertTransform = Transform (transform).apply {
207243 invert()
@@ -252,6 +288,8 @@ class GenerationViewModel(application: Application, private val engine: Engine)
252288 private const val LINE_GAP_RATIO = 3
253289
254290 private const val PROFILE_FOLDER = " profiles"
291+
292+ private val DEFAULT_LANGUAGE = HWGLanguage .ENGLISH
255293 }
256294}
257295
0 commit comments