Skip to content

Commit

Permalink
[Samples] Updating to iink 2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
yannchevalier committed Dec 7, 2023
1 parent 41417f3 commit 2625e2f
Show file tree
Hide file tree
Showing 8 changed files with 430 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@

import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

public class Canvas implements ICanvas
{

private static final Style DEFAULT_SVG_STYLE = new Style();

@NonNull
private final android.graphics.Canvas canvas;
@Nullable
private android.graphics.Canvas canvas;

@NonNull
private final Paint strokePaint;
Expand Down Expand Up @@ -77,6 +78,8 @@ public class Canvas implements ICanvas
private final ImageLoader imageLoader;
private final OfflineSurfaceManager offlineSurfaceManager;

private boolean clearOnStartDraw = true;

private final Set<String> clips;

private final Map<String, Typeface> typefaceMap;
Expand All @@ -92,7 +95,7 @@ public class Canvas implements ICanvas
@NonNull
private final Matrix pointScaleMatrix;

public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, @Nullable OfflineSurfaceManager offlineSurfaceManager, float xdpi, float ydpi)
public Canvas(@Nullable android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, @Nullable OfflineSurfaceManager offlineSurfaceManager, float xdpi, float ydpi)
{
this.canvas = canvas;
this.typefaceMap = typefaceMap;
Expand Down Expand Up @@ -135,11 +138,21 @@ public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typ
applyStyle(DEFAULT_SVG_STYLE);
}

public Canvas(@NonNull android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, float xdpi, float ydpi)
public Canvas(@Nullable android.graphics.Canvas canvas, Map<String, Typeface> typefaceMap, ImageLoader imageLoader, float xdpi, float ydpi)
{
this(canvas, typefaceMap, imageLoader, null, xdpi, ydpi);
}

public void setCanvas(@NonNull android.graphics.Canvas canvas)
{
this.canvas = canvas;
}

public void setClearOnStartDraw(boolean clearOnStartDraw)
{
this.clearOnStartDraw = clearOnStartDraw;
}

private void applyStyle(@NonNull Style style)
{
setStrokeColor(style.getStrokeColor());
Expand Down Expand Up @@ -174,6 +187,7 @@ public void setTransform(@NonNull Transform transform)
transformValues[Matrix.MSCALE_Y] = (float) transform.yy;
transformValues[Matrix.MTRANS_Y] = (float) transform.ty;

Objects.requireNonNull(canvas);
transformMatrix.setValues(transformValues);
canvas.setMatrix(transformMatrix);

Expand Down Expand Up @@ -313,6 +327,7 @@ public final void setFontProperties(@NonNull String fontFamily, float fontLineHe
@Override
public void startDraw(int x, int y, int width, int height)
{
Objects.requireNonNull(canvas);
canvas.save();

pointsCache[0] = x;
Expand All @@ -322,7 +337,7 @@ public void startDraw(int x, int y, int width, int height)

// When offscreen rendering is supported, clear the destination
// Otherwise, do not clear the destination (e.g. when exporting image, we want a white background)
if (offlineSurfaceManager != null)
if (offlineSurfaceManager != null && clearOnStartDraw)
canvas.drawRect(pointsCache[0], pointsCache[1], pointsCache[2], pointsCache[3], clearPaint);

// Hardware canvas does not support PorterDuffXfermode
Expand All @@ -332,6 +347,7 @@ public void startDraw(int x, int y, int width, int height)
@Override
public void endDraw()
{
Objects.requireNonNull(canvas);
canvas.restore();
}

Expand All @@ -340,6 +356,7 @@ public void startGroup(@NonNull String id, float x, float y, float width, float
{
if (clipContent)
{
Objects.requireNonNull(canvas);
clips.add(id);
canvas.save();

Expand All @@ -352,6 +369,7 @@ public void endGroup(@NonNull String id)
{
if (clips.remove(id))
{
Objects.requireNonNull(canvas);
canvas.restore();
}
}
Expand All @@ -378,6 +396,7 @@ public final IPath createPath()
@Override
public void drawPath(@NonNull IPath ipath)
{
Objects.requireNonNull(canvas);
Path path = (Path) ipath;

if (android.graphics.Color.alpha(fillPaint.getColor()) != 0)
Expand All @@ -394,6 +413,7 @@ public void drawPath(@NonNull IPath ipath)
@Override
public void drawRectangle(float x, float y, float width, float height)
{
Objects.requireNonNull(canvas);
if (android.graphics.Color.alpha(fillPaint.getColor()) != 0)
{
canvas.drawRect(x, y, x + width, y + height, fillPaint);
Expand All @@ -407,6 +427,7 @@ public void drawRectangle(float x, float y, float width, float height)
@Override
public void drawLine(float x1, float y1, float x2, float y2)
{
Objects.requireNonNull(canvas);
canvas.drawLine(x1, y1, x2, y2, strokePaint);
}

Expand All @@ -416,16 +437,16 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
if (imageLoader == null)
return;

Point screenMin = new Point(x, y);
transform.apply(screenMin);
Point screenMax = new Point(x + width, y + height);
transform.apply(screenMax);
Objects.requireNonNull(canvas);

RectF pixelSize = new RectF(x,y,x + width, y + height);
transformMatrix.mapRect(pixelSize);

final Rect targetRect = new Rect(
(int) Math.floor(screenMin.x),
(int) Math.floor(screenMin.y),
(int) (Math.ceil(screenMax.x) - x),
(int) (Math.ceil(screenMax.y) - y));
(int) Math.floor(pixelSize.left),
(int) Math.floor(pixelSize.top),
(int) (Math.ceil(pixelSize.right)),
(int) (Math.ceil(pixelSize.bottom)));

synchronized (imageLoader)
{
Expand All @@ -441,22 +462,6 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
}
else
{
// adjust rectangle so that the image gets fit into original rectangle
float fx = width / image.getWidth();
float fy = height / image.getHeight();
if (fx > fy)
{
float w = image.getWidth() * fy;
x += (width - w) / 2;
width = w;
}
else
{
float h = image.getHeight() * fx;
y += (height - h) / 2;
height = h;
}

// draw the image
Rect srcRect = new Rect(0, 0, image.getWidth(), image.getHeight());
RectF dstRect = new RectF(x, y, x + width, y + height);
Expand All @@ -471,6 +476,7 @@ public void drawObject(@NonNull String url, @NonNull String mimeType, float x, f
@Override
public void drawText(@NonNull String label, float x, float y, float xmin, float ymin, float xmax, float ymax)
{
Objects.requireNonNull(canvas);
// transform the insertion point so that it is not impacted by text scale
pointsCache[0] = x;
pointsCache[1] = y;
Expand All @@ -496,6 +502,7 @@ public void blendOffscreen(int id, float srcX, float srcY, float srcWidth, float

if (bitmap != null)
{
Objects.requireNonNull(canvas);
floatRectCache.set(destX, destY, destX + destWidth, destY + destHeight);
simpleRectCache.set(Math.round(srcX), Math.round(srcY),
Math.round(srcX + srcWidth), Math.round(srcY + srcHeight));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Adapted from:
// https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:input/input-motionprediction/

package com.myscript.iink.uireferenceimplementation;

import android.content.Context;
import android.os.Build;
import android.view.Display;
import android.view.WindowManager;

import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

/**
* Get screen fastest refresh rate (in ms)
*/
@SuppressWarnings("deprecation")
public class FrameTimeEstimator {
private static final float LEGACY_FRAME_TIME_MS = 16f;
private static final float MS_IN_A_SECOND = 1000f;

static public float getFrameTime(@NonNull Context context)
{
return getFastestFrameTimeMs(context);
}

private static Display getDisplayForContext(Context context)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
{
return Api30Impl.getDisplayForContext(context);
}
return ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
}

private static float getFastestFrameTimeMs(Context context)
{
Display defaultDisplay = getDisplayForContext(context);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
return Api23Impl.getFastestFrameTimeMs(defaultDisplay);
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
return Api21Impl.getFastestFrameTimeMs(defaultDisplay);
}
else
{
return LEGACY_FRAME_TIME_MS;
}
}

@SuppressWarnings("deprecation")
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
static class Api21Impl
{
private Api21Impl()
{
// Not instantiable
}

@DoNotInline
static float getFastestFrameTimeMs(Display display)
{
float[] refreshRates = display.getSupportedRefreshRates();
float largestRefreshRate = refreshRates[0];

for (int c = 1; c < refreshRates.length; c++)
{
if (refreshRates[c] > largestRefreshRate)
largestRefreshRate = refreshRates[c];
}

return MS_IN_A_SECOND / largestRefreshRate;
}
}

@RequiresApi(Build.VERSION_CODES.M)
static class Api23Impl
{
private Api23Impl()
{
// Not instantiable
}

@DoNotInline
static float getFastestFrameTimeMs(Display display)
{
Display.Mode[] displayModes = display.getSupportedModes();
float largestRefreshRate = displayModes[0].getRefreshRate();

for (int c = 1; c < displayModes.length; c++)
{
float currentRefreshRate = displayModes[c].getRefreshRate();
if (currentRefreshRate > largestRefreshRate)
largestRefreshRate = currentRefreshRate;
}

return MS_IN_A_SECOND / largestRefreshRate;
}
}

@RequiresApi(Build.VERSION_CODES.R)
static class Api30Impl
{
private Api30Impl()
{
// Not instantiable
}

@DoNotInline
static Display getDisplayForContext(Context context)
{
return context.getDisplay();
}
}
}

0 comments on commit 2625e2f

Please sign in to comment.