The bigger update to Canvas
All draw* calls in Canvas are regular JNI All draw* calls in DisplayListCanvas are FastNative Unifies Canvas JNI on nMethodName naming CanvasPerf results before: INSTRUMENTATION_STATUS: basicViewGroupDraw_min=12492 INSTRUMENTATION_STATUS: recordSimpleBitmapView_min=13912 and after: INSTRUMENTATION_STATUS: basicViewGroupDraw_min=11945 INSTRUMENTATION_STATUS: recordSimpleBitmapView_min=13318 Test: refactor, makes & boots Change-Id: I06000df1d125e17d60c6498865be7a7638a4a13e
This commit is contained in:
@@ -16,31 +16,30 @@
|
|||||||
|
|
||||||
package android.text;
|
package android.text;
|
||||||
|
|
||||||
|
import android.graphics.BaseCanvas;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Please implement this interface if your CharSequence can do quick
|
* Please implement this interface if your CharSequence can do quick draw/measure/widths
|
||||||
* draw/measure/widths calculations from an internal array.
|
* calculations from an internal array.
|
||||||
* {@hide}
|
*
|
||||||
|
* @hide
|
||||||
*/
|
*/
|
||||||
public interface GraphicsOperations
|
public interface GraphicsOperations extends CharSequence {
|
||||||
extends CharSequence
|
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Just like {@link Canvas#drawText}.
|
* Just like {@link Canvas#drawText}.
|
||||||
*/
|
*/
|
||||||
void drawText(Canvas c, int start, int end,
|
void drawText(BaseCanvas c, int start, int end,
|
||||||
float x, float y, Paint p);
|
float x, float y, Paint p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just like {@link Canvas#drawTextRun}.
|
* Just like {@link Canvas#drawTextRun}.
|
||||||
* {@hide}
|
|
||||||
*/
|
*/
|
||||||
void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd,
|
void drawTextRun(BaseCanvas c, int start, int end, int contextStart, int contextEnd,
|
||||||
float x, float y, boolean isRtl, Paint p);
|
float x, float y, boolean isRtl, Paint p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just like {@link Paint#measureText}.
|
* Just like {@link Paint#measureText}.
|
||||||
*/
|
*/
|
||||||
float measureText(int start, int end, Paint p);
|
float measureText(int start, int end, Paint p);
|
||||||
@@ -52,14 +51,12 @@ extends CharSequence
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Just like {@link Paint#getTextRunAdvances}.
|
* Just like {@link Paint#getTextRunAdvances}.
|
||||||
* @hide
|
|
||||||
*/
|
*/
|
||||||
float getTextRunAdvances(int start, int end, int contextStart, int contextEnd,
|
float getTextRunAdvances(int start, int end, int contextStart, int contextEnd,
|
||||||
boolean isRtl, float[] advances, int advancesIndex, Paint paint);
|
boolean isRtl, float[] advances, int advancesIndex, Paint paint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just like {@link Paint#getTextRunCursor}.
|
* Just like {@link Paint#getTextRunCursor}.
|
||||||
* @hide
|
|
||||||
*/
|
*/
|
||||||
int getTextRunCursor(int contextStart, int contextEnd, int dir, int offset,
|
int getTextRunCursor(int contextStart, int contextEnd, int dir, int offset,
|
||||||
int cursorOpt, Paint p);
|
int cursorOpt, Paint p);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
package android.text;
|
package android.text;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.BaseCanvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -1357,7 +1357,8 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
|
|||||||
* Don't call this yourself -- exists for Canvas to use internally.
|
* Don't call this yourself -- exists for Canvas to use internally.
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public void drawText(Canvas c, int start, int end, float x, float y, Paint p) {
|
@Override
|
||||||
|
public void drawText(BaseCanvas c, int start, int end, float x, float y, Paint p) {
|
||||||
checkRange("drawText", start, end);
|
checkRange("drawText", start, end);
|
||||||
|
|
||||||
if (end <= mGapStart) {
|
if (end <= mGapStart) {
|
||||||
@@ -1378,7 +1379,8 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
|
|||||||
* Don't call this yourself -- exists for Canvas to use internally.
|
* Don't call this yourself -- exists for Canvas to use internally.
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public void drawTextRun(Canvas c, int start, int end, int contextStart, int contextEnd,
|
@Override
|
||||||
|
public void drawTextRun(BaseCanvas c, int start, int end, int contextStart, int contextEnd,
|
||||||
float x, float y, boolean isRtl, Paint p) {
|
float x, float y, boolean isRtl, Paint p) {
|
||||||
checkRange("drawTextRun", start, end);
|
checkRange("drawTextRun", start, end);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package android.view;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.CanvasProperty;
|
import android.graphics.CanvasProperty;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.util.Pools.SynchronizedPool;
|
import android.util.Pools.SynchronizedPool;
|
||||||
@@ -34,7 +33,7 @@ import dalvik.annotation.optimization.FastNative;
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class DisplayListCanvas extends Canvas {
|
public final class DisplayListCanvas extends RecordingCanvas {
|
||||||
// The recording canvas pool should be large enough to handle a deeply nested
|
// The recording canvas pool should be large enough to handle a deeply nested
|
||||||
// view hierarchy because display lists are generated recursively.
|
// view hierarchy because display lists are generated recursively.
|
||||||
private static final int POOL_LIMIT = 25;
|
private static final int POOL_LIMIT = 25;
|
||||||
@@ -42,7 +41,7 @@ public class DisplayListCanvas extends Canvas {
|
|||||||
private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
|
private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
|
||||||
|
|
||||||
private static final SynchronizedPool<DisplayListCanvas> sPool =
|
private static final SynchronizedPool<DisplayListCanvas> sPool =
|
||||||
new SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
|
new SynchronizedPool<>(POOL_LIMIT);
|
||||||
|
|
||||||
RenderNode mNode;
|
RenderNode mNode;
|
||||||
private int mWidth;
|
private int mWidth;
|
||||||
|
|||||||
641
core/java/android/view/RecordingCanvas.java
Normal file
641
core/java/android/view/RecordingCanvas.java
Normal file
@@ -0,0 +1,641 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.view;
|
||||||
|
|
||||||
|
import android.annotation.ColorInt;
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.Size;
|
||||||
|
import android.graphics.BaseCanvas;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.NinePatch;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Picture;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.TemporaryBuffer;
|
||||||
|
import android.text.GraphicsOperations;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.SpannedString;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import dalvik.annotation.optimization.FastNative;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a base class for canvases that defer drawing operations, so all
|
||||||
|
* the draw operations can be marked @FastNative. It contains a re-implementation of
|
||||||
|
* all the methods in {@link BaseCanvas}.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public class RecordingCanvas extends Canvas {
|
||||||
|
|
||||||
|
public RecordingCanvas(long nativeCanvas) {
|
||||||
|
super(nativeCanvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawArc(float left, float top, float right, float bottom, float startAngle,
|
||||||
|
float sweepAngle, boolean useCenter, @NonNull Paint paint) {
|
||||||
|
nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
|
||||||
|
useCenter, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle,
|
||||||
|
boolean useCenter, @NonNull Paint paint) {
|
||||||
|
drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
|
||||||
|
paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawARGB(int a, int r, int g, int b) {
|
||||||
|
drawColor(Color.argb(a, r, g, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
|
||||||
|
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
|
||||||
|
bitmap.mDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
|
||||||
|
paint != null ? paint.getNativeInstance() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
if (dst == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
|
||||||
|
int left, top, right, bottom;
|
||||||
|
if (src == null) {
|
||||||
|
left = top = 0;
|
||||||
|
right = bitmap.getWidth();
|
||||||
|
bottom = bitmap.getHeight();
|
||||||
|
} else {
|
||||||
|
left = src.left;
|
||||||
|
right = src.right;
|
||||||
|
top = src.top;
|
||||||
|
bottom = src.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
|
||||||
|
bitmap.mDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
if (dst == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
|
||||||
|
float left, top, right, bottom;
|
||||||
|
if (src == null) {
|
||||||
|
left = top = 0;
|
||||||
|
right = bitmap.getWidth();
|
||||||
|
bottom = bitmap.getHeight();
|
||||||
|
} else {
|
||||||
|
left = src.left;
|
||||||
|
right = src.right;
|
||||||
|
top = src.top;
|
||||||
|
bottom = src.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
|
||||||
|
bitmap.mDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated checkstyle */
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public final void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y,
|
||||||
|
int width, int height, boolean hasAlpha, @Nullable Paint paint) {
|
||||||
|
// check for valid input
|
||||||
|
if (width < 0) {
|
||||||
|
throw new IllegalArgumentException("width must be >= 0");
|
||||||
|
}
|
||||||
|
if (height < 0) {
|
||||||
|
throw new IllegalArgumentException("height must be >= 0");
|
||||||
|
}
|
||||||
|
if (Math.abs(stride) < width) {
|
||||||
|
throw new IllegalArgumentException("abs(stride) must be >= width");
|
||||||
|
}
|
||||||
|
int lastScanline = offset + (height - 1) * stride;
|
||||||
|
int length = colors.length;
|
||||||
|
if (offset < 0 || (offset + width > length) || lastScanline < 0
|
||||||
|
|| (lastScanline + width > length)) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
// quick escape if there's nothing to draw
|
||||||
|
if (width == 0 || height == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// punch down to native for the actual draw
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
|
||||||
|
paint != null ? paint.getNativeInstance() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated checkstyle */
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public final void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y,
|
||||||
|
int width, int height, boolean hasAlpha, @Nullable Paint paint) {
|
||||||
|
// call through to the common float version
|
||||||
|
drawBitmap(colors, offset, stride, (float) x, (float) y, width, height,
|
||||||
|
hasAlpha, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight,
|
||||||
|
@NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (meshWidth == 0 || meshHeight == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = (meshWidth + 1) * (meshHeight + 1);
|
||||||
|
// we mul by 2 since we need two floats per vertex
|
||||||
|
checkRange(verts.length, vertOffset, count * 2);
|
||||||
|
if (colors != null) {
|
||||||
|
// no mul by 2, since we need only 1 color per vertex
|
||||||
|
checkRange(colors.length, colorOffset, count);
|
||||||
|
}
|
||||||
|
nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
|
||||||
|
verts, vertOffset, colors, colorOffset,
|
||||||
|
paint != null ? paint.getNativeInstance() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
|
||||||
|
nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawColor(@ColorInt int color) {
|
||||||
|
nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
|
||||||
|
nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawLine(float startX, float startY, float stopX, float stopY,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
|
||||||
|
drawLines(pts, 0, pts.length, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawOval(float left, float top, float right, float bottom,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
|
||||||
|
if (oval == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPaint(@NonNull Paint paint) {
|
||||||
|
nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
Bitmap bitmap = patch.getBitmap();
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
|
||||||
|
mDensity, patch.getDensity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
Bitmap bitmap = patch.getBitmap();
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
|
||||||
|
mDensity, patch.getDensity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPath(@NonNull Path path, @NonNull Paint paint) {
|
||||||
|
if (path.isSimplePath && path.rects != null) {
|
||||||
|
nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
|
||||||
|
} else {
|
||||||
|
nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPicture(@NonNull Picture picture) {
|
||||||
|
picture.endRecording();
|
||||||
|
int restoreCount = save();
|
||||||
|
picture.draw(this);
|
||||||
|
restoreToCount(restoreCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPicture(@NonNull Picture picture, @NonNull Rect dst) {
|
||||||
|
save();
|
||||||
|
translate(dst.left, dst.top);
|
||||||
|
if (picture.getWidth() > 0 && picture.getHeight() > 0) {
|
||||||
|
scale((float) dst.width() / picture.getWidth(),
|
||||||
|
(float) dst.height() / picture.getHeight());
|
||||||
|
}
|
||||||
|
drawPicture(picture);
|
||||||
|
restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPicture(@NonNull Picture picture, @NonNull RectF dst) {
|
||||||
|
save();
|
||||||
|
translate(dst.left, dst.top);
|
||||||
|
if (picture.getWidth() > 0 && picture.getHeight() > 0) {
|
||||||
|
scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
|
||||||
|
}
|
||||||
|
drawPicture(picture);
|
||||||
|
restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPoint(float x, float y, @NonNull Paint paint) {
|
||||||
|
nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
|
||||||
|
drawPoints(pts, 0, pts.length, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated checkstyle */
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public final void drawPosText(@NonNull char[] text, int index, int count,
|
||||||
|
@NonNull @Size(multiple = 2) float[] pos,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if (index < 0 || index + count > text.length || count * 2 > pos.length) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated checkstyle */
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public final void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawRect(float left, float top, float right, float bottom,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawRect(@NonNull Rect r, @NonNull Paint paint) {
|
||||||
|
drawRect(r.left, r.top, r.right, r.bottom, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
|
||||||
|
nDrawRect(mNativeCanvasWrapper,
|
||||||
|
rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawRGB(int r, int g, int b) {
|
||||||
|
drawColor(Color.rgb(r, g, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawRoundRect(float left, float top, float right, float bottom,
|
||||||
|
float rx, float ry, @NonNull Paint paint) {
|
||||||
|
nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
|
||||||
|
paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
|
||||||
|
drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawText(@NonNull char[] text, int index, int count, float x, float y,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if ((index | count | (index + count)
|
||||||
|
| (text.length - index - count)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
|
||||||
|
paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if ((start | end | (end - start) | (text.length() - end)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (text instanceof String || text instanceof SpannedString
|
||||||
|
|| text instanceof SpannableString) {
|
||||||
|
nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
} else if (text instanceof GraphicsOperations) {
|
||||||
|
((GraphicsOperations) text).drawText(this, start, end, x, y,
|
||||||
|
paint);
|
||||||
|
} else {
|
||||||
|
char[] buf = TemporaryBuffer.obtain(end - start);
|
||||||
|
TextUtils.getChars(text, start, end, buf, 0);
|
||||||
|
nDrawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
TemporaryBuffer.recycle(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
|
||||||
|
nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
|
||||||
|
paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawText(@NonNull String text, int start, int end, float x, float y,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if ((start | end | (end - start) | (text.length() - end)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
|
||||||
|
paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
|
||||||
|
float hOffset, float vOffset, @NonNull Paint paint) {
|
||||||
|
if (index < 0 || index + count > text.length) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
|
||||||
|
path.readOnlyNI(), hOffset, vOffset,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
|
||||||
|
float vOffset, @NonNull Paint paint) {
|
||||||
|
if (text.length() > 0) {
|
||||||
|
nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
|
||||||
|
int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
|
||||||
|
|
||||||
|
if (text == null) {
|
||||||
|
throw new NullPointerException("text is null");
|
||||||
|
}
|
||||||
|
if (paint == null) {
|
||||||
|
throw new NullPointerException("paint is null");
|
||||||
|
}
|
||||||
|
if ((index | count | contextIndex | contextCount | index - contextIndex
|
||||||
|
| (contextIndex + contextCount) - (index + count)
|
||||||
|
| text.length - (contextIndex + contextCount)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
|
||||||
|
x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
|
||||||
|
int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
|
||||||
|
|
||||||
|
if (text == null) {
|
||||||
|
throw new NullPointerException("text is null");
|
||||||
|
}
|
||||||
|
if (paint == null) {
|
||||||
|
throw new NullPointerException("paint is null");
|
||||||
|
}
|
||||||
|
if ((start | end | contextStart | contextEnd | start - contextStart | end - start
|
||||||
|
| contextEnd - end | text.length() - contextEnd) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text instanceof String || text instanceof SpannedString
|
||||||
|
|| text instanceof SpannableString) {
|
||||||
|
nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
|
||||||
|
contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
} else if (text instanceof GraphicsOperations) {
|
||||||
|
((GraphicsOperations) text).drawTextRun(this, start, end,
|
||||||
|
contextStart, contextEnd, x, y, isRtl, paint);
|
||||||
|
} else {
|
||||||
|
int contextLen = contextEnd - contextStart;
|
||||||
|
int len = end - start;
|
||||||
|
char[] buf = TemporaryBuffer.obtain(contextLen);
|
||||||
|
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
|
||||||
|
nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
|
||||||
|
0, contextLen, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
TemporaryBuffer.recycle(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void drawVertices(@NonNull VertexMode mode, int vertexCount,
|
||||||
|
@NonNull float[] verts, int vertOffset, @Nullable float[] texs, int texOffset,
|
||||||
|
@Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset,
|
||||||
|
int indexCount, @NonNull Paint paint) {
|
||||||
|
checkRange(verts.length, vertOffset, vertexCount);
|
||||||
|
if (isHardwareAccelerated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (texs != null) {
|
||||||
|
checkRange(texs.length, texOffset, vertexCount);
|
||||||
|
}
|
||||||
|
if (colors != null) {
|
||||||
|
checkRange(colors.length, colorOffset, vertexCount / 2);
|
||||||
|
}
|
||||||
|
if (indices != null) {
|
||||||
|
checkRange(indices.length, indexOffset, indexCount);
|
||||||
|
}
|
||||||
|
nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
|
||||||
|
vertOffset, texs, texOffset, colors, colorOffset,
|
||||||
|
indices, indexOffset, indexCount, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
|
||||||
|
long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap,
|
||||||
|
float srcLeft, float srcTop, float srcRight, float srcBottom,
|
||||||
|
float dstLeft, float dstTop, float dstRight, float dstBottom,
|
||||||
|
long nativePaintOrZero, int screenDensity, int bitmapDensity);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
|
||||||
|
float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawColor(long nativeCanvas, int color, int mode);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawPaint(long nativeCanvas, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawPoint(long canvasHandle, float x, float y, long paintHandle);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawPoints(long canvasHandle, float[] pts, int offset, int count,
|
||||||
|
long paintHandle);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX,
|
||||||
|
float stopY, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawLines(long canvasHandle, float[] pts, int offset, int count,
|
||||||
|
long paintHandle);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawRect(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawOval(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawCircle(long nativeCanvas, float cx, float cy, float radius,
|
||||||
|
long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawArc(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, float rx, float ry, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
|
||||||
|
float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
|
||||||
|
int screenDensity, int bitmapDensity);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
|
||||||
|
long nativeMatrix, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
|
||||||
|
int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
|
||||||
|
long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts,
|
||||||
|
int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
|
||||||
|
short[] indices, int indexOffset, int indexCount, long nativePaint);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawText(long nativeCanvas, char[] text, int index, int count,
|
||||||
|
float x, float y, int flags, long nativePaint, long nativeTypeface);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawText(long nativeCanvas, String text, int start, int end,
|
||||||
|
float x, float y, int flags, long nativePaint, long nativeTypeface);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawTextRun(long nativeCanvas, String text, int start, int end,
|
||||||
|
int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint,
|
||||||
|
long nativeTypeface);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
|
||||||
|
int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
|
||||||
|
long nativeTypeface);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
|
||||||
|
long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint,
|
||||||
|
long nativeTypeface);
|
||||||
|
|
||||||
|
@FastNative
|
||||||
|
private static native void nDrawTextOnPath(long nativeCanvas, String text, long nativePath,
|
||||||
|
float hOffset, float vOffset, int flags, long nativePaint, long nativeTypeface);
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ import android.content.res.Configuration;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
|
import android.graphics.BaseCanvas;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@@ -10222,12 +10223,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
System.arraycopy(mChars, start + mStart, buf, off, end - start);
|
System.arraycopy(mChars, start + mStart, buf, off, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawText(Canvas c, int start, int end,
|
@Override
|
||||||
|
public void drawText(BaseCanvas c, int start, int end,
|
||||||
float x, float y, Paint p) {
|
float x, float y, Paint p) {
|
||||||
c.drawText(mChars, start + mStart, end - start, x, y, p);
|
c.drawText(mChars, start + mStart, end - start, x, y, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawTextRun(Canvas c, int start, int end,
|
@Override
|
||||||
|
public void drawTextRun(BaseCanvas c, int start, int end,
|
||||||
int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint p) {
|
int contextStart, int contextEnd, float x, float y, boolean isRtl, Paint p) {
|
||||||
int count = end - start;
|
int count = end - start;
|
||||||
int contextCount = contextEnd - contextStart;
|
int contextCount = contextEnd - contextStart;
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ static void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jobject jbitmap,
|
static void drawBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
|
||||||
jfloat left, jfloat top, jlong paintHandle, jint canvasDensity,
|
jfloat left, jfloat top, jlong paintHandle, jint canvasDensity,
|
||||||
jint screenDensity, jint bitmapDensity) {
|
jint screenDensity, jint bitmapDensity) {
|
||||||
Canvas* canvas = get_canvas(canvasHandle);
|
Canvas* canvas = get_canvas(canvasHandle);
|
||||||
@@ -571,67 +571,77 @@ static void freeTextLayoutCaches(JNIEnv* env, jobject) {
|
|||||||
}; // namespace CanvasJNI
|
}; // namespace CanvasJNI
|
||||||
|
|
||||||
static const JNINativeMethod gMethods[] = {
|
static const JNINativeMethod gMethods[] = {
|
||||||
{"getNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer},
|
{"nGetNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer},
|
||||||
{"initRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
|
{"nInitRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
|
||||||
{"freeCaches", "()V", (void*) CanvasJNI::freeCaches},
|
{"nFreeCaches", "()V", (void*) CanvasJNI::freeCaches},
|
||||||
{"freeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches},
|
{"nFreeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches},
|
||||||
{"native_drawBitmap","(JLandroid/graphics/Bitmap;FFJIII)V", (void*) CanvasJNI::drawBitmap},
|
|
||||||
{"native_drawBitmap","(JLandroid/graphics/Bitmap;FFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
|
|
||||||
{"native_drawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
|
|
||||||
|
|
||||||
// ------------ @FastNative ----------------
|
// ------------ @FastNative ----------------
|
||||||
{"native_setBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
|
{"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
|
||||||
{"native_isOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
|
{"nIsOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
|
||||||
{"native_getWidth","(J)I", (void*) CanvasJNI::getWidth},
|
{"nGetWidth","(J)I", (void*) CanvasJNI::getWidth},
|
||||||
{"native_getHeight","(J)I", (void*) CanvasJNI::getHeight},
|
{"nGetHeight","(J)I", (void*) CanvasJNI::getHeight},
|
||||||
{"native_setHighContrastText","(JZ)V", (void*) CanvasJNI::setHighContrastText},
|
{"nSetHighContrastText","(JZ)V", (void*) CanvasJNI::setHighContrastText},
|
||||||
{"native_save","(JI)I", (void*) CanvasJNI::save},
|
{"nSave","(JI)I", (void*) CanvasJNI::save},
|
||||||
{"native_saveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
|
{"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
|
||||||
{"native_saveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
|
{"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
|
||||||
{"native_getSaveCount","(J)I", (void*) CanvasJNI::getSaveCount},
|
{"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount},
|
||||||
{"native_restore","(JZ)V", (void*) CanvasJNI::restore},
|
{"nRestore","(JZ)V", (void*) CanvasJNI::restore},
|
||||||
{"native_restoreToCount","(JIZ)V", (void*) CanvasJNI::restoreToCount},
|
{"nRestoreToCount","(JIZ)V", (void*) CanvasJNI::restoreToCount},
|
||||||
{"native_getCTM", "(JJ)V", (void*)CanvasJNI::getCTM},
|
{"nGetCTM", "(JJ)V", (void*)CanvasJNI::getCTM},
|
||||||
{"native_setMatrix","(JJ)V", (void*) CanvasJNI::setMatrix},
|
{"nSetMatrix","(JJ)V", (void*) CanvasJNI::setMatrix},
|
||||||
{"native_concat","(JJ)V", (void*) CanvasJNI::concat},
|
{"nConcat","(JJ)V", (void*) CanvasJNI::concat},
|
||||||
{"native_rotate","(JF)V", (void*) CanvasJNI::rotate},
|
{"nRotate","(JF)V", (void*) CanvasJNI::rotate},
|
||||||
{"native_scale","(JFF)V", (void*) CanvasJNI::scale},
|
{"nScale","(JFF)V", (void*) CanvasJNI::scale},
|
||||||
{"native_skew","(JFF)V", (void*) CanvasJNI::skew},
|
{"nSkew","(JFF)V", (void*) CanvasJNI::skew},
|
||||||
{"native_translate","(JFF)V", (void*) CanvasJNI::translate},
|
{"nTranslate","(JFF)V", (void*) CanvasJNI::translate},
|
||||||
{"native_getClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds},
|
{"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds},
|
||||||
{"native_quickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath},
|
{"nQuickReject","(JJ)Z", (void*) CanvasJNI::quickRejectPath},
|
||||||
{"native_quickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect},
|
{"nQuickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect},
|
||||||
{"native_clipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect},
|
{"nClipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect},
|
||||||
{"native_clipPath","(JJI)Z", (void*) CanvasJNI::clipPath},
|
{"nClipPath","(JJI)Z", (void*) CanvasJNI::clipPath},
|
||||||
{"native_clipRegion","(JJI)Z", (void*) CanvasJNI::clipRegion},
|
{"nClipRegion","(JJI)Z", (void*) CanvasJNI::clipRegion},
|
||||||
{"native_drawColor","(JII)V", (void*) CanvasJNI::drawColor},
|
{"nSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setDrawFilter},
|
||||||
{"native_drawPaint","(JJ)V", (void*) CanvasJNI::drawPaint},
|
};
|
||||||
{"native_drawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint},
|
|
||||||
{"native_drawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints},
|
// If called from Canvas these are regular JNI
|
||||||
{"native_drawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
|
// If called from DisplayListCanvas they are @FastNative
|
||||||
{"native_drawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines},
|
static const JNINativeMethod gDrawMethods[] = {
|
||||||
{"native_drawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
|
{"nDrawColor","(JII)V", (void*) CanvasJNI::drawColor},
|
||||||
{"native_drawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion },
|
{"nDrawPaint","(JJ)V", (void*) CanvasJNI::drawPaint},
|
||||||
{"native_drawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
|
{"nDrawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint},
|
||||||
{"native_drawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
|
{"nDrawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints},
|
||||||
{"native_drawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
|
{"nDrawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
|
||||||
{"native_drawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc},
|
{"nDrawLines", "(J[FIIJ)V", (void*) CanvasJNI::drawLines},
|
||||||
{"native_drawPath","(JJJ)V", (void*) CanvasJNI::drawPath},
|
{"nDrawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
|
||||||
{"nativeDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
|
{"nDrawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion },
|
||||||
{"native_drawNinePatch", "(JJJFFFFJII)V", (void*)CanvasJNI::drawNinePatch},
|
{"nDrawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
|
||||||
{"nativeDrawBitmapMatrix", "(JLandroid/graphics/Bitmap;JJ)V", (void*)CanvasJNI::drawBitmapMatrix},
|
{"nDrawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
|
||||||
{"nativeDrawBitmapMesh", "(JLandroid/graphics/Bitmap;II[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
|
{"nDrawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
|
||||||
{"native_drawText","(J[CIIFFIJJ)V", (void*) CanvasJNI::drawTextChars},
|
{"nDrawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc},
|
||||||
{"native_drawText","(JLjava/lang/String;IIFFIJJ)V", (void*) CanvasJNI::drawTextString},
|
{"nDrawPath","(JJJ)V", (void*) CanvasJNI::drawPath},
|
||||||
{"native_drawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars},
|
{"nDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
|
||||||
{"native_drawTextRun","(JLjava/lang/String;IIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunString},
|
{"nDrawNinePatch", "(JJJFFFFJII)V", (void*)CanvasJNI::drawNinePatch},
|
||||||
{"native_drawTextOnPath","(J[CIIJFFIJJ)V", (void*) CanvasJNI::drawTextOnPathChars},
|
{"nDrawBitmapMatrix", "(JLandroid/graphics/Bitmap;JJ)V", (void*)CanvasJNI::drawBitmapMatrix},
|
||||||
{"native_drawTextOnPath","(JLjava/lang/String;JFFIJJ)V", (void*) CanvasJNI::drawTextOnPathString},
|
{"nDrawBitmapMesh", "(JLandroid/graphics/Bitmap;II[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
|
||||||
{"nativeSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setDrawFilter},
|
{"nDrawBitmap","(JLandroid/graphics/Bitmap;FFJIII)V", (void*) CanvasJNI::drawBitmap},
|
||||||
|
{"nDrawBitmap","(JLandroid/graphics/Bitmap;FFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
|
||||||
|
{"nDrawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
|
||||||
|
{"nDrawText","(J[CIIFFIJJ)V", (void*) CanvasJNI::drawTextChars},
|
||||||
|
{"nDrawText","(JLjava/lang/String;IIFFIJJ)V", (void*) CanvasJNI::drawTextString},
|
||||||
|
{"nDrawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars},
|
||||||
|
{"nDrawTextRun","(JLjava/lang/String;IIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunString},
|
||||||
|
{"nDrawTextOnPath","(J[CIIJFFIJJ)V", (void*) CanvasJNI::drawTextOnPathChars},
|
||||||
|
{"nDrawTextOnPath","(JLjava/lang/String;JFFIJJ)V", (void*) CanvasJNI::drawTextOnPathString},
|
||||||
};
|
};
|
||||||
|
|
||||||
int register_android_graphics_Canvas(JNIEnv* env) {
|
int register_android_graphics_Canvas(JNIEnv* env) {
|
||||||
return RegisterMethodsOrDie(env, "android/graphics/Canvas", gMethods, NELEM(gMethods));
|
int ret = 0;
|
||||||
|
ret |= RegisterMethodsOrDie(env, "android/graphics/Canvas", gMethods, NELEM(gMethods));
|
||||||
|
ret |= RegisterMethodsOrDie(env, "android/graphics/BaseCanvas", gDrawMethods, NELEM(gDrawMethods));
|
||||||
|
ret |= RegisterMethodsOrDie(env, "android/view/RecordingCanvas", gDrawMethods, NELEM(gDrawMethods));
|
||||||
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|||||||
557
graphics/java/android/graphics/BaseCanvas.java
Normal file
557
graphics/java/android/graphics/BaseCanvas.java
Normal file
@@ -0,0 +1,557 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
import android.annotation.ColorInt;
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.Size;
|
||||||
|
import android.graphics.Canvas.VertexMode;
|
||||||
|
import android.text.GraphicsOperations;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.SpannedString;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.RecordingCanvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a base class for Canvas's drawing operations. Any modifications here
|
||||||
|
* should be accompanied by a similar modification to {@link RecordingCanvas}.
|
||||||
|
*
|
||||||
|
* The purpose of this class is to minimize the cost of deciding between regular JNI
|
||||||
|
* and @FastNative JNI to just the virtual call that Canvas already has.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public abstract class BaseCanvas {
|
||||||
|
/**
|
||||||
|
* Should only be assigned in constructors (or setBitmap if software canvas),
|
||||||
|
* freed by NativeAllocation.
|
||||||
|
*/
|
||||||
|
protected long mNativeCanvasWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine when compatibility scaling is in effect.
|
||||||
|
*/
|
||||||
|
protected int mScreenDensity = Bitmap.DENSITY_NONE;
|
||||||
|
protected int mDensity = Bitmap.DENSITY_NONE;
|
||||||
|
|
||||||
|
protected void throwIfCannotDraw(Bitmap bitmap) {
|
||||||
|
if (bitmap.isRecycled()) {
|
||||||
|
throw new RuntimeException("Canvas: trying to use a recycled bitmap " + bitmap);
|
||||||
|
}
|
||||||
|
if (!bitmap.isPremultiplied() && bitmap.getConfig() == Bitmap.Config.ARGB_8888 &&
|
||||||
|
bitmap.hasAlpha()) {
|
||||||
|
throw new RuntimeException("Canvas: trying to use a non-premultiplied bitmap "
|
||||||
|
+ bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final static void checkRange(int length, int offset, int count) {
|
||||||
|
if ((offset | count) < 0 || offset + count > length) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHardwareAccelerated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Drawing methods
|
||||||
|
// These are also implemented in DisplayListCanvas so that we can
|
||||||
|
// selectively apply on them
|
||||||
|
// Everything below here is copy/pasted from Canvas.java
|
||||||
|
// The JNI registration is handled by android_view_Canvas.cpp
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void drawArc(float left, float top, float right, float bottom, float startAngle,
|
||||||
|
float sweepAngle, boolean useCenter, @NonNull Paint paint) {
|
||||||
|
nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
|
||||||
|
useCenter, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
|
||||||
|
paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawARGB(int a, int r, int g, int b) {
|
||||||
|
drawColor(Color.argb(a, r, g, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
|
||||||
|
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
|
||||||
|
bitmap.mDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
|
||||||
|
nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
|
||||||
|
paint != null ? paint.getNativeInstance() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
if (dst == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
|
||||||
|
int left, top, right, bottom;
|
||||||
|
if (src == null) {
|
||||||
|
left = top = 0;
|
||||||
|
right = bitmap.getWidth();
|
||||||
|
bottom = bitmap.getHeight();
|
||||||
|
} else {
|
||||||
|
left = src.left;
|
||||||
|
right = src.right;
|
||||||
|
top = src.top;
|
||||||
|
bottom = src.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
|
||||||
|
bitmap.mDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
if (dst == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
|
||||||
|
float left, top, right, bottom;
|
||||||
|
if (src == null) {
|
||||||
|
left = top = 0;
|
||||||
|
right = bitmap.getWidth();
|
||||||
|
bottom = bitmap.getHeight();
|
||||||
|
} else {
|
||||||
|
left = src.left;
|
||||||
|
right = src.right;
|
||||||
|
top = src.top;
|
||||||
|
bottom = src.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
|
||||||
|
bitmap.mDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y,
|
||||||
|
int width, int height, boolean hasAlpha, @Nullable Paint paint) {
|
||||||
|
// check for valid input
|
||||||
|
if (width < 0) {
|
||||||
|
throw new IllegalArgumentException("width must be >= 0");
|
||||||
|
}
|
||||||
|
if (height < 0) {
|
||||||
|
throw new IllegalArgumentException("height must be >= 0");
|
||||||
|
}
|
||||||
|
if (Math.abs(stride) < width) {
|
||||||
|
throw new IllegalArgumentException("abs(stride) must be >= width");
|
||||||
|
}
|
||||||
|
int lastScanline = offset + (height - 1) * stride;
|
||||||
|
int length = colors.length;
|
||||||
|
if (offset < 0 || (offset + width > length) || lastScanline < 0
|
||||||
|
|| (lastScanline + width > length)) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
// quick escape if there's nothing to draw
|
||||||
|
if (width == 0 || height == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// punch down to native for the actual draw
|
||||||
|
nDrawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
|
||||||
|
paint != null ? paint.getNativeInstance() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y,
|
||||||
|
int width, int height, boolean hasAlpha, @Nullable Paint paint) {
|
||||||
|
// call through to the common float version
|
||||||
|
drawBitmap(colors, offset, stride, (float) x, (float) y, width, height,
|
||||||
|
hasAlpha, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight,
|
||||||
|
@NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset,
|
||||||
|
@Nullable Paint paint) {
|
||||||
|
if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (meshWidth == 0 || meshHeight == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = (meshWidth + 1) * (meshHeight + 1);
|
||||||
|
// we mul by 2 since we need two floats per vertex
|
||||||
|
checkRange(verts.length, vertOffset, count * 2);
|
||||||
|
if (colors != null) {
|
||||||
|
// no mul by 2, since we need only 1 color per vertex
|
||||||
|
checkRange(colors.length, colorOffset, count);
|
||||||
|
}
|
||||||
|
nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
|
||||||
|
verts, vertOffset, colors, colorOffset,
|
||||||
|
paint != null ? paint.getNativeInstance() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
|
||||||
|
nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawColor(@ColorInt int color) {
|
||||||
|
nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
|
||||||
|
nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawLine(float startX, float startY, float stopX, float stopY,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
|
||||||
|
drawLines(pts, 0, pts.length, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {
|
||||||
|
nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
|
||||||
|
if (oval == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPaint(@NonNull Paint paint) {
|
||||||
|
nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst, @Nullable Paint paint) {
|
||||||
|
Bitmap bitmap = patch.getBitmap();
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
|
||||||
|
mDensity, patch.getDensity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst, @Nullable Paint paint) {
|
||||||
|
Bitmap bitmap = patch.getBitmap();
|
||||||
|
throwIfCannotDraw(bitmap);
|
||||||
|
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||||
|
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
|
||||||
|
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
|
||||||
|
mDensity, patch.getDensity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPath(@NonNull Path path, @NonNull Paint paint) {
|
||||||
|
if (path.isSimplePath && path.rects != null) {
|
||||||
|
nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
|
||||||
|
} else {
|
||||||
|
nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPoint(float x, float y, @NonNull Paint paint) {
|
||||||
|
nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
|
||||||
|
drawPoints(pts, 0, pts.length, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void drawPosText(@NonNull char[] text, int index, int count,
|
||||||
|
@NonNull @Size(multiple = 2) float[] pos,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if (index < 0 || index + count > text.length || count * 2 > pos.length) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {
|
||||||
|
nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawRect(@NonNull Rect r, @NonNull Paint paint) {
|
||||||
|
drawRect(r.left, r.top, r.right, r.bottom, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
|
||||||
|
nDrawRect(mNativeCanvasWrapper,
|
||||||
|
rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawRGB(int r, int g, int b) {
|
||||||
|
drawColor(Color.rgb(r, g, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
|
||||||
|
paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
|
||||||
|
drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawText(@NonNull char[] text, int index, int count, float x, float y,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if ((index | count | (index + count) |
|
||||||
|
(text.length - index - count)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
|
||||||
|
paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if ((start | end | (end - start) | (text.length() - end)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (text instanceof String || text instanceof SpannedString ||
|
||||||
|
text instanceof SpannableString) {
|
||||||
|
nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
} else if (text instanceof GraphicsOperations) {
|
||||||
|
((GraphicsOperations) text).drawText(this, start, end, x, y,
|
||||||
|
paint);
|
||||||
|
} else {
|
||||||
|
char[] buf = TemporaryBuffer.obtain(end - start);
|
||||||
|
TextUtils.getChars(text, start, end, buf, 0);
|
||||||
|
nDrawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
TemporaryBuffer.recycle(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
|
||||||
|
nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
|
||||||
|
paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawText(@NonNull String text, int start, int end, float x, float y,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
if ((start | end | (end - start) | (text.length() - end)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
|
||||||
|
paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
|
||||||
|
float hOffset, float vOffset, @NonNull Paint paint) {
|
||||||
|
if (index < 0 || index + count > text.length) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
|
||||||
|
path.readOnlyNI(), hOffset, vOffset,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
|
||||||
|
float vOffset, @NonNull Paint paint) {
|
||||||
|
if (text.length() > 0) {
|
||||||
|
nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
|
||||||
|
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
|
||||||
|
int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
|
||||||
|
|
||||||
|
if (text == null) {
|
||||||
|
throw new NullPointerException("text is null");
|
||||||
|
}
|
||||||
|
if (paint == null) {
|
||||||
|
throw new NullPointerException("paint is null");
|
||||||
|
}
|
||||||
|
if ((index | count | contextIndex | contextCount | index - contextIndex
|
||||||
|
| (contextIndex + contextCount) - (index + count)
|
||||||
|
| text.length - (contextIndex + contextCount)) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
|
||||||
|
x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
|
||||||
|
int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
|
||||||
|
|
||||||
|
if (text == null) {
|
||||||
|
throw new NullPointerException("text is null");
|
||||||
|
}
|
||||||
|
if (paint == null) {
|
||||||
|
throw new NullPointerException("paint is null");
|
||||||
|
}
|
||||||
|
if ((start | end | contextStart | contextEnd | start - contextStart | end - start
|
||||||
|
| contextEnd - end | text.length() - contextEnd) < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text instanceof String || text instanceof SpannedString ||
|
||||||
|
text instanceof SpannableString) {
|
||||||
|
nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
|
||||||
|
contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
} else if (text instanceof GraphicsOperations) {
|
||||||
|
((GraphicsOperations) text).drawTextRun(this, start, end,
|
||||||
|
contextStart, contextEnd, x, y, isRtl, paint);
|
||||||
|
} else {
|
||||||
|
int contextLen = contextEnd - contextStart;
|
||||||
|
int len = end - start;
|
||||||
|
char[] buf = TemporaryBuffer.obtain(contextLen);
|
||||||
|
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
|
||||||
|
nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
|
||||||
|
0, contextLen, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
|
||||||
|
TemporaryBuffer.recycle(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawVertices(@NonNull VertexMode mode, int vertexCount, @NonNull float[] verts,
|
||||||
|
int vertOffset, @Nullable float[] texs, int texOffset, @Nullable int[] colors,
|
||||||
|
int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount,
|
||||||
|
@NonNull Paint paint) {
|
||||||
|
checkRange(verts.length, vertOffset, vertexCount);
|
||||||
|
if (isHardwareAccelerated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (texs != null) {
|
||||||
|
checkRange(texs.length, texOffset, vertexCount);
|
||||||
|
}
|
||||||
|
if (colors != null) {
|
||||||
|
checkRange(colors.length, colorOffset, vertexCount / 2);
|
||||||
|
}
|
||||||
|
if (indices != null) {
|
||||||
|
checkRange(indices.length, indexOffset, indexCount);
|
||||||
|
}
|
||||||
|
nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
|
||||||
|
vertOffset, texs, texOffset, colors, colorOffset,
|
||||||
|
indices, indexOffset, indexCount, paint.getNativeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
|
||||||
|
long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
|
||||||
|
|
||||||
|
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float srcLeft,
|
||||||
|
float srcTop,
|
||||||
|
float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
|
||||||
|
float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity);
|
||||||
|
|
||||||
|
private static native void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
|
||||||
|
float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero);
|
||||||
|
|
||||||
|
private static native void nDrawColor(long nativeCanvas, int color, int mode);
|
||||||
|
|
||||||
|
private static native void nDrawPaint(long nativeCanvas, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawPoint(long canvasHandle, float x, float y, long paintHandle);
|
||||||
|
|
||||||
|
private static native void nDrawPoints(long canvasHandle, float[] pts, int offset, int count,
|
||||||
|
long paintHandle);
|
||||||
|
|
||||||
|
private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX,
|
||||||
|
float stopY, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawLines(long canvasHandle, float[] pts, int offset, int count,
|
||||||
|
long paintHandle);
|
||||||
|
|
||||||
|
private static native void nDrawRect(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawOval(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawCircle(long nativeCanvas, float cx, float cy, float radius,
|
||||||
|
long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawArc(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right,
|
||||||
|
float bottom, float rx, float ry, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
|
||||||
|
float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
|
||||||
|
int screenDensity, int bitmapDensity);
|
||||||
|
|
||||||
|
private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
|
||||||
|
long nativeMatrix, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
|
||||||
|
int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
|
||||||
|
long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts,
|
||||||
|
int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
|
||||||
|
short[] indices, int indexOffset, int indexCount, long nativePaint);
|
||||||
|
|
||||||
|
private static native void nDrawText(long nativeCanvas, char[] text, int index, int count,
|
||||||
|
float x, float y, int flags, long nativePaint, long nativeTypeface);
|
||||||
|
|
||||||
|
private static native void nDrawText(long nativeCanvas, String text, int start, int end,
|
||||||
|
float x, float y, int flags, long nativePaint, long nativeTypeface);
|
||||||
|
|
||||||
|
private static native void nDrawTextRun(long nativeCanvas, String text, int start, int end,
|
||||||
|
int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint,
|
||||||
|
long nativeTypeface);
|
||||||
|
|
||||||
|
private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
|
||||||
|
int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
|
||||||
|
long nativeTypeface);
|
||||||
|
|
||||||
|
private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
|
||||||
|
long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint,
|
||||||
|
long nativeTypeface);
|
||||||
|
|
||||||
|
private static native void nDrawTextOnPath(long nativeCanvas, String text, long nativePath,
|
||||||
|
float hOffset, float vOffset, int flags, long nativePaint, long nativeTypeface);
|
||||||
|
}
|
||||||
@@ -73,8 +73,8 @@ public final class Bitmap implements Parcelable {
|
|||||||
private int mHeight;
|
private int mHeight;
|
||||||
private boolean mRecycled;
|
private boolean mRecycled;
|
||||||
|
|
||||||
// Package-scoped for fast access.
|
/** @hide */
|
||||||
int mDensity = getDefaultDensity();
|
public int mDensity = getDefaultDensity();
|
||||||
|
|
||||||
private static volatile Matrix sScaleMatrix;
|
private static volatile Matrix sScaleMatrix;
|
||||||
|
|
||||||
@@ -130,8 +130,9 @@ public final class Bitmap implements Parcelable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the pointer to the native object.
|
* Return the pointer to the native object.
|
||||||
|
* @hide
|
||||||
*/
|
*/
|
||||||
long getNativeInstance() {
|
public long getNativeInstance() {
|
||||||
return mNativePtr;
|
return mNativePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -838,7 +838,8 @@ public class Matrix {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ final long ni() {
|
/** @hide */
|
||||||
|
public final long ni() {
|
||||||
return native_instance;
|
return native_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -775,7 +775,8 @@ public class Path {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final long readOnlyNI() {
|
/** @hide */
|
||||||
|
public final long readOnlyNI() {
|
||||||
return mNativePath;
|
return mNativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user