Skip to content

Commit 6061c39

Browse files
author
YDec
committed
update of aditionnal sample to iink 2.0.1
Lasso sample has been removed as this tool is part of iink sdk since 2.0.X All sample have been rewrite to Kotlin Exercise Assessment sample has been enhanced with other type parts and integration of a custom gramar
1 parent 0883c30 commit 6061c39

File tree

206 files changed

+3754
-3770
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

206 files changed

+3754
-3770
lines changed

README.md

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,51 @@ This repository comes in addition with further advanced Android examples that de
88

99
## Installation
1010

11-
1. Clone the examples repository  `git clone https://github.com/MyScript/iink_sdk-additional-examples-android.git`.
11+
1. Clone the examples repository `git clone https://github.com/MyScript/iink_sdk-additional-examples-android.git`.
1212

1313
2. If you already have a certificate go to next step, else claim to receive the free license to start develop your application by following the first steps of [Getting Started](https://developer.myscript.com/getting-started).
1414

1515
3. Copy this certificate to `certificate/src/main/java/com/myscript/certificate/MyCertificate.java`
1616

17+
4. Open `java` folder in Android Studio.
18+
1719
## Various examples
1820

1921
This repository provides you with an additional set of ready-to-use examples based on Android:
2022

21-
1. The batch mode sample is an example of how to integrate iink SDK off-screen, without any user interface. It consists in batch processing content, i.e. processing a series of pointer events corresponding to already collected ink strokes and exporting the recognition result. It comes with four pointer events samples that correspond to four different content types "Text", "Math", "Diagram", "Raw Content". Those content types are exported in respectively .txt, LaTeX, svg and JIIX formats. By default, the example is working with the "Text" content type but all you have to do to try another type is modifying the content type in the MainActivity class:
23+
1. The batch mode sample is an example of how to integrate iink SDK off-screen, without any user interface. It consists in batch processing content, i.e. processing a series of pointer events corresponding to already collected ink strokes and exporting the recognition result. It comes with four pointer events samples that correspond to four different content types "Text", "Math", "Diagram", "Raw Content". When starting the app a dialog will be displayed to choose which type of part you want to proceed. By default those content types are exported in respectively .txt, LaTeX, svg and JIIX formats, but you can choose to export in png by modifying the following line in the MainActivity class:
2224

2325
~~~#!java
24-
// Choose type of content ("Text", "Math", "Diagram", "Raw Content")
25-
private static String partType = "Text";
26+
// this is the function where we process exteranl output and export it
27+
// add true if you want to export in png
28+
offScreenProcess(typeOfPart[it])
2629
~~~
27-
28-
2. The exercise assessment illustrates the case when you want to use several writing areas each one for a specific purpose (here the example is based on problem solving and score writing) in your application. It is thus using multiple editors, one per writing area, as each one has a different purpose: one of them is dedicated to "Math" content types and the three other ones to "Text" content type.
29-
3030
<div align="center">
31-
<img src="assessment.gif" alt="assessment" width="302">
31+
<img src="batch.gif" alt="batch" width="302">
3232
</div>
3333

34-
3. The search example shows how to perform word search on raw digital ink and highlights the result found in the ink. it is based on "Raw Content" Content Type.
34+
NB: you will retrieve data converted in your device internal storage : Android\data\com.myscript.iink.samples.batchmode\files
35+
36+
2. The exercise assessment illustrates the case when you want to use several writing areas each one for a specific purpose in your application. It is thus using multiple editors, one per writing area, as each one has a different purpose:
37+
- First one is dedicated to "Math" content types
38+
- Second one is dedicated to "Math" content types but with user defined gramar which is dynamically loaded at start.
39+
- Third one is dedicated to "Text" content types
40+
- Fourth one is dedicated to "Diagram" content types
41+
- Fifth one is dedicated to "Draw" content types
3542

3643
<div align="center">
37-
<img src="search-sample.gif" alt="search sample" width="302">
44+
<img src="assesment.gif" alt="assessment_new" width="302">
3845
</div>
3946

40-
4. The lasso example is illustrating how you can perform recognition of strokes captured with a lasso in the drawing area of your application: It is based on two "Drawing" parts: one for the drawing/writing area and the other one for the lasso capture. In lasso mode, the lassoed strokes are sent as a series of event to a batch recognition of a "Text" part and the result is displayed.
47+
3. The search example shows how to perform word search on raw digital ink and highlights the result found in the ink. it is based on "Raw Content" Content Type by default but you can change it to "Text Document" by modifying the following line in the MainActivity class:
4148

49+
~~~#!java
50+
// wait for view size initialization before setting part
51+
editorView!!.post(Runnable() {
52+
val partType = "Raw Content" // change to "Text Document" if you want to test
53+
~~~
4254
<div align="center">
43-
<img src="lasso.gif" alt="lasso" width="302">
55+
<img src="search-sample.gif" alt="search sample" width="302">
4456
</div>
4557

4658
## Documentation
@@ -62,4 +74,4 @@ We’re planning to showcase apps using it so let us know by sending a quick mai
6274

6375
We welcome your contributions:
6476
If you would like to extend those examples for your needs, feel free to fork them!
65-
Please sign our [Contributor License Agreement](CONTRIBUTING.md) before submitting your pull request.
77+
Please sign our [Contributor License Agreement](CONTRIBUTING.md) before submitting your pull request.
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
apply plugin: 'com.android.library'
1+
plugins {
2+
id 'com.android.library'
3+
}
24

35
android {
46
compileSdkVersion project.ext.compileSdkVersion
57

68
defaultConfig {
79
minSdkVersion project.ext.minSdkVersion
810
targetSdkVersion project.ext.targetSdkVersion
9-
versionCode 1410
10-
versionName '1.4.1'
11+
versionCode 2010
12+
versionName '2.0.1'
1113

1214
vectorDrawables.useSupportLibrary true
1315
}
1416
}
1517

1618
dependencies {
17-
implementation "androidx.appcompat:appcompat:${project.ext.supportLibraryVersion}"
18-
implementation "com.google.code.gson:gson:2.8.2"
19-
api "com.myscript:iink:1.4.1"
19+
implementation "androidx.appcompat:appcompat:${project.ext.appcompatVersion}"
20+
implementation "com.google.code.gson:gson:${project.ext.gsonVersion}"
21+
api "com.myscript:iink:${project.ext.iinkVersionName}"
2022
}
-171 KB
Binary file not shown.
-325 KB
Binary file not shown.

UIReferenceImplementation/src/main/java/com/myscript/iink/uireferenceimplementation/Canvas.java

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
package com.myscript.iink.uireferenceimplementation;
44

5-
import android.content.res.Resources;
65
import android.graphics.Bitmap;
76
import android.graphics.DashPathEffect;
87
import android.graphics.Matrix;
@@ -12,30 +11,30 @@
1211
import android.graphics.Rect;
1312
import android.graphics.RectF;
1413
import android.graphics.Typeface;
14+
1515
import androidx.annotation.ColorInt;
1616
import androidx.annotation.NonNull;
1717
import androidx.annotation.Nullable;
18+
import androidx.core.graphics.ColorUtils;
19+
1820
import android.text.TextPaint;
19-
import android.util.DisplayMetrics;
2021
import android.util.Log;
2122

22-
import com.myscript.iink.IRenderTarget;
2323
import com.myscript.iink.graphics.Color;
2424
import com.myscript.iink.graphics.FillRule;
25-
import com.myscript.iink.graphics.ICanvas2;
25+
import com.myscript.iink.graphics.ICanvas;
2626
import com.myscript.iink.graphics.IPath;
2727
import com.myscript.iink.graphics.LineCap;
2828
import com.myscript.iink.graphics.LineJoin;
2929
import com.myscript.iink.graphics.Point;
3030
import com.myscript.iink.graphics.Style;
3131
import com.myscript.iink.graphics.Transform;
3232

33-
import java.util.EnumSet;
3433
import java.util.HashSet;
3534
import java.util.Map;
3635
import java.util.Set;
3736

38-
public class Canvas implements ICanvas2
37+
public class Canvas implements ICanvas
3938
{
4039

4140
private static final Style DEFAULT_SVG_STYLE = new Style();
@@ -76,7 +75,6 @@ public class Canvas implements ICanvas2
7675

7776
@Nullable
7877
private final ImageLoader imageLoader;
79-
private final IRenderTarget target;
8078
private final OfflineSurfaceManager offlineSurfaceManager;
8179

8280
private final Set<String> clips;
@@ -86,21 +84,22 @@ public class Canvas implements ICanvas2
8684
private float[] dashArray;
8785
private int dashOffset = 0;
8886

89-
@NonNull
90-
private final DisplayMetrics displayMetrics;
87+
private final float xdpi;
88+
private final float ydpi;
9189

9290
@NonNull
9391
private final Matrix textScaleMatrix;
9492
@NonNull
9593
private final Matrix pointScaleMatrix;
9694

97-
public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, IRenderTarget target, OfflineSurfaceManager offlineSurfaceManager)
95+
public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, @Nullable OfflineSurfaceManager offlineSurfaceManager, float xdpi, float ydpi)
9896
{
9997
this.canvas = canvas;
10098
this.typefaceMap = typefaceMap;
10199
this.imageLoader = imageLoader;
102-
this.target = target;
103100
this.offlineSurfaceManager = offlineSurfaceManager;
101+
this.xdpi = xdpi;
102+
this.ydpi = ydpi;
104103

105104
clips = new HashSet<>();
106105

@@ -127,19 +126,18 @@ public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typ
127126

128127
dashArray = null;
129128

130-
displayMetrics = Resources.getSystem().getDisplayMetrics();
131129
textScaleMatrix = new Matrix();
132-
textScaleMatrix.setScale(25.4f / displayMetrics.xdpi, 25.4f / displayMetrics.ydpi);
130+
textScaleMatrix.setScale(25.4f / xdpi, 25.4f / ydpi);
133131
pointScaleMatrix = new Matrix();
134132
textScaleMatrix.invert(pointScaleMatrix);
135133

136134
// it is mandatory to configure the Paint with SVG defaults represented by default Style object
137135
applyStyle(DEFAULT_SVG_STYLE);
138136
}
139137

140-
public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, IRenderTarget target)
138+
public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, float xdpi, float ydpi)
141139
{
142-
this(canvas, typefaceMap, imageLoader, target, null);
140+
this(canvas, typefaceMap, imageLoader, null, xdpi, ydpi);
143141
}
144142

145143
private void applyStyle(@NonNull Style style)
@@ -154,7 +152,9 @@ private void applyStyle(@NonNull Style style)
154152
setFillColor(style.getFillColor());
155153
setFillRule(style.getFillRule());
156154

157-
setFontProperties(FontMetricsProvider.toPlatformFontFamily(style), style.getFontLineHeight(), style.getFontSize(),
155+
setDropShadow(style.getDropShadowXOffset(), style.getDropShadowYOffset(), style.getDropShadowRadius(), style.getDropShadowColor());
156+
157+
setFontProperties(style.getFontFamily(), style.getFontLineHeight(), style.getFontSize(),
158158
style.getFontStyle(), style.getFontVariant(), style.getFontWeight());
159159
}
160160

@@ -286,18 +286,28 @@ public void setFillRule(@NonNull FillRule fillRule)
286286
}
287287

288288
@Override
289-
public final void setFontProperties(@NonNull String fontFamily, float fontLineHeight, float fontSize, String fontStyle,
289+
public void setDropShadow(float xOffset, float yOffset, float radius, @NonNull Color color)
290+
{
291+
@ColorInt int androidColor = argb(color);
292+
boolean isTransparent = color.a() == 0;
293+
int opaqueColor = ColorUtils.setAlphaComponent(androidColor, 0xFF);
294+
strokePaint.setShadowLayer(radius / 20f, xOffset, yOffset, isTransparent ? android.graphics.Color.TRANSPARENT : opaqueColor);
295+
textPaint.setShadowLayer(radius / 10f, xOffset * 2.5f, yOffset * 5f, isTransparent ? android.graphics.Color.TRANSPARENT : opaqueColor);
296+
fillPaint.setShadowLayer(radius / 20f, xOffset, yOffset, isTransparent ? android.graphics.Color.TRANSPARENT : opaqueColor);
297+
}
298+
299+
@Override
300+
public final void setFontProperties(@NonNull String fontFamily, float fontLineHeight, float fontSize, @NonNull String fontStyle,
290301
@NonNull String fontVariant, int fontWeight)
291302
{
292-
String resolvedFontFamily = FontMetricsProvider.toPlatformFontFamily(fontFamily, fontStyle);
293-
Typeface typeface = typefaceMap == null ?
294-
FontUtils.getTypeface(resolvedFontFamily, fontStyle, fontVariant, fontWeight) :
295-
FontUtils.getTypeface(typefaceMap, resolvedFontFamily, fontStyle, fontVariant, fontWeight);
303+
Typeface typeface = typefaceMap == null
304+
? FontUtils.getTypeface(fontFamily, fontStyle, fontVariant, fontWeight)
305+
: FontUtils.getTypeface(typefaceMap, fontFamily, fontStyle, fontVariant, fontWeight);
296306

297307
// scale font size to the canvas transform scale, to ensure best font rendering
298308
// (text size is expressed in pixels, while fontSize is in mm)
299309
textPaint.setTypeface(typeface);
300-
textPaint.setTextSize(Math.round((fontSize / 25.4f) * displayMetrics.ydpi));
310+
textPaint.setTextSize(Math.round((fontSize / 25.4f) * ydpi));
301311
}
302312

303313
@Override
@@ -358,6 +368,7 @@ public void endItem(@NonNull String id)
358368
// no-op
359369
}
360370

371+
@NonNull
361372
@Override
362373
public final IPath createPath()
363374
{
@@ -369,12 +380,12 @@ public void drawPath(@NonNull IPath ipath)
369380
{
370381
Path path = (Path) ipath;
371382

372-
if (fillPaint.getColor() != android.graphics.Color.TRANSPARENT)
383+
if (android.graphics.Color.alpha(fillPaint.getColor()) != 0)
373384
{
374385
path.setFillType(fillRule == FillRule.EVENODD ? android.graphics.Path.FillType.EVEN_ODD : android.graphics.Path.FillType.WINDING);
375386
canvas.drawPath(path, fillPaint);
376387
}
377-
if (strokePaint.getColor() != android.graphics.Color.TRANSPARENT)
388+
if (android.graphics.Color.alpha(strokePaint.getColor()) != 0)
378389
{
379390
canvas.drawPath(path, strokePaint);
380391
}
@@ -383,11 +394,11 @@ public void drawPath(@NonNull IPath ipath)
383394
@Override
384395
public void drawRectangle(float x, float y, float width, float height)
385396
{
386-
if (fillPaint.getColor() != android.graphics.Color.TRANSPARENT)
397+
if (android.graphics.Color.alpha(fillPaint.getColor()) != 0)
387398
{
388399
canvas.drawRect(x, y, x + width, y + height, fillPaint);
389400
}
390-
if (strokePaint.getColor() != android.graphics.Color.TRANSPARENT)
401+
if (android.graphics.Color.alpha(strokePaint.getColor()) != 0)
391402
{
392403
canvas.drawRect(x, y, x + width, y + height, strokePaint);
393404
}
@@ -423,7 +434,7 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
423434
if (image == null)
424435
{
425436
// image is not ready yet...
426-
if (fillPaint.getColor() != android.graphics.Color.TRANSPARENT)
437+
if (android.graphics.Color.alpha(fillPaint.getColor()) != 0)
427438
{
428439
canvas.drawRect(x, y, width, height, fillPaint);
429440
}
@@ -461,22 +472,23 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
461472
public void drawText(@NonNull String label, float x, float y, float xmin, float ymin, float xmax, float ymax)
462473
{
463474
// transform the insertion point so that it is not impacted by text scale
464-
float[] p = {x, y};
465-
pointScaleMatrix.mapPoints(p);
475+
pointsCache[0] = x;
476+
pointsCache[1] = y;
477+
pointScaleMatrix.mapPoints(pointsCache);
466478

467479
// transform the text to account for font size in pixel (not mm)
468480
canvas.concat(textScaleMatrix);
469481

470482
// draw text
471-
canvas.drawText(label, p[0], p[1], textPaint);
483+
canvas.drawText(label, pointsCache[0], pointsCache[1], textPaint);
472484

473485
// restore transform
474486
canvas.setMatrix(transformMatrix);
475487
}
476488

477489
@Override
478490
public void blendOffscreen(int id, float srcX, float srcY, float srcWidth, float srcHeight,
479-
float destX, float destY, float destWidth, float destHeight, Color blendColor)
491+
float destX, float destY, float destWidth, float destHeight, @NonNull Color blendColor)
480492
{
481493
if (offlineSurfaceManager != null)
482494
{
@@ -486,12 +498,12 @@ public void blendOffscreen(int id, float srcX, float srcY, float srcWidth, float
486498
{
487499
floatRectCache.set(destX, destY, destX + destWidth, destY + destHeight);
488500
simpleRectCache.set(Math.round(srcX), Math.round(srcY),
489-
Math.round(srcX + srcWidth), Math.round(srcY + srcHeight));
501+
Math.round(srcX + srcWidth), Math.round(srcY + srcHeight));
490502
bitmapAlphaPaint.setColor(argb(blendColor));
491503

492504
canvas.drawBitmap(bitmap,
493-
simpleRectCache, floatRectCache,
494-
bitmapAlphaPaint);
505+
simpleRectCache, floatRectCache,
506+
bitmapAlphaPaint);
495507
}
496508
}
497509
}

0 commit comments

Comments
 (0)