summaryrefslogtreecommitdiffstats
path: root/core/jni/android/graphics/Canvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/jni/android/graphics/Canvas.cpp')
-rw-r--r--core/jni/android/graphics/Canvas.cpp1330
1 files changed, 0 insertions, 1330 deletions
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
deleted file mode 100644
index 6254f3d..0000000
--- a/core/jni/android/graphics/Canvas.cpp
+++ /dev/null
@@ -1,1330 +0,0 @@
-/*
- * Copyright (C) 2006-2007 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.
- */
-
-#include "jni.h"
-#include "GraphicsJNI.h"
-#include <android_runtime/AndroidRuntime.h>
-
-#include "SkCanvas.h"
-#include "SkClipStack.h"
-#include "SkDevice.h"
-#include "SkDeque.h"
-#include "SkDrawFilter.h"
-#include "SkGraphics.h"
-#include <SkImageInfo.h>
-#include "SkPorterDuff.h"
-#include "SkShader.h"
-#include "SkTArray.h"
-#include "SkTemplates.h"
-
-#include <minikin/Layout.h>
-#include "MinikinSkia.h"
-#include "MinikinUtils.h"
-
-#include "TypefaceImpl.h"
-
-#include "unicode/ubidi.h"
-#include "unicode/ushape.h"
-
-#include <utils/Log.h>
-
-namespace android {
-
-class ClipCopier : public SkCanvas::ClipVisitor {
-public:
- ClipCopier(SkCanvas* dstCanvas) : m_dstCanvas(dstCanvas) {}
-
- virtual void clipRect(const SkRect& rect, SkRegion::Op op, bool antialias) {
- m_dstCanvas->clipRect(rect, op, antialias);
- }
- virtual void clipRRect(const SkRRect& rrect, SkRegion::Op op, bool antialias) {
- m_dstCanvas->clipRRect(rrect, op, antialias);
- }
- virtual void clipPath(const SkPath& path, SkRegion::Op op, bool antialias) {
- m_dstCanvas->clipPath(path, op, antialias);
- }
-
-private:
- SkCanvas* m_dstCanvas;
-};
-
-// Holds an SkCanvas reference plus additional native data.
-class NativeCanvasWrapper {
-private:
- struct SaveRec {
- int saveCount;
- SkCanvas::SaveFlags saveFlags;
- };
-
-public:
- NativeCanvasWrapper(SkCanvas* canvas)
- : mCanvas(canvas)
- , mSaveStack(NULL) {
- SkASSERT(canvas);
- }
-
- ~NativeCanvasWrapper() {
- delete mSaveStack;
- }
-
- SkCanvas* getCanvas() const {
- return mCanvas.get();
- }
-
- void setCanvas(SkCanvas* canvas) {
- SkASSERT(canvas);
- mCanvas.reset(canvas);
-
- delete mSaveStack;
- mSaveStack = NULL;
- }
-
- int save(SkCanvas::SaveFlags flags) {
- int count = mCanvas->save();
- recordPartialSave(flags);
- return count;
- }
-
- int saveLayer(const SkRect* bounds, const SkPaint* paint,
- SkCanvas::SaveFlags flags) {
- int count = mCanvas->saveLayer(bounds, paint,
- static_cast<SkCanvas::SaveFlags>(flags | SkCanvas::kMatrixClip_SaveFlag));
- recordPartialSave(flags);
- return count;
- }
-
- int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
- SkCanvas::SaveFlags flags) {
- int count = mCanvas->saveLayerAlpha(bounds, alpha,
- static_cast<SkCanvas::SaveFlags>(flags | SkCanvas::kMatrixClip_SaveFlag));
- recordPartialSave(flags);
- return count;
- }
-
- void restore() {
- const SaveRec* rec = (NULL == mSaveStack)
- ? NULL
- : static_cast<SaveRec*>(mSaveStack->back());
- int currentSaveCount = mCanvas->getSaveCount() - 1;
- SkASSERT(NULL == rec || currentSaveCount >= rec->saveCount);
-
- if (NULL == rec || rec->saveCount != currentSaveCount) {
- // Fast path - no record for this frame.
- mCanvas->restore();
- return;
- }
-
- bool preserveMatrix = !(rec->saveFlags & SkCanvas::kMatrix_SaveFlag);
- bool preserveClip = !(rec->saveFlags & SkCanvas::kClip_SaveFlag);
-
- SkMatrix savedMatrix;
- if (preserveMatrix) {
- savedMatrix = mCanvas->getTotalMatrix();
- }
-
- SkTArray<SkClipStack::Element> savedClips;
- if (preserveClip) {
- saveClipsForFrame(savedClips, currentSaveCount);
- }
-
- mCanvas->restore();
-
- if (preserveMatrix) {
- mCanvas->setMatrix(savedMatrix);
- }
-
- if (preserveClip && !savedClips.empty()) {
- applyClips(savedClips);
- }
-
- mSaveStack->pop_back();
- }
-
-private:
- void recordPartialSave(SkCanvas::SaveFlags flags) {
- // A partial save is a save operation which doesn't capture the full canvas state.
- // (either kMatrix_SaveFlags or kClip_SaveFlag is missing).
-
- // Mask-out non canvas state bits.
- flags = static_cast<SkCanvas::SaveFlags>(flags & SkCanvas::kMatrixClip_SaveFlag);
-
- if (SkCanvas::kMatrixClip_SaveFlag == flags) {
- // not a partial save.
- return;
- }
-
- if (NULL == mSaveStack) {
- mSaveStack = new SkDeque(sizeof(struct SaveRec), 8);
- }
-
- SaveRec* rec = static_cast<SaveRec*>(mSaveStack->push_back());
- // Store the save counter in the SkClipStack domain.
- // (0-based, equal to the number of save ops on the stack).
- rec->saveCount = mCanvas->getSaveCount() - 1;
- rec->saveFlags = flags;
- }
-
- void saveClipsForFrame(SkTArray<SkClipStack::Element>& clips,
- int frameSaveCount) {
- SkClipStack::Iter clipIterator(*mCanvas->getClipStack(),
- SkClipStack::Iter::kTop_IterStart);
- while (const SkClipStack::Element* elem = clipIterator.next()) {
- if (elem->getSaveCount() < frameSaveCount) {
- // done with the current frame.
- break;
- }
- SkASSERT(elem->getSaveCount() == frameSaveCount);
- clips.push_back(*elem);
- }
- }
-
- void applyClips(const SkTArray<SkClipStack::Element>& clips) {
- ClipCopier clipCopier(mCanvas);
-
- // The clip stack stores clips in device space.
- SkMatrix origMatrix = mCanvas->getTotalMatrix();
- mCanvas->resetMatrix();
-
- // We pushed the clips in reverse order.
- for (int i = clips.count() - 1; i >= 0; --i) {
- clips[i].replay(&clipCopier);
- }
-
- mCanvas->setMatrix(origMatrix);
- }
-
- SkAutoTUnref<SkCanvas> mCanvas;
- SkDeque* mSaveStack; // lazily allocated, tracks partial saves.
-};
-
-// Returns true if the SkCanvas's clip is non-empty.
-static jboolean hasNonEmptyClip(const SkCanvas& canvas) {
- bool emptyClip = canvas.isClipEmpty();
- return emptyClip ? JNI_FALSE : JNI_TRUE;
-}
-
-class SkCanvasGlue {
-public:
- // Get the native wrapper for a given handle.
- static inline NativeCanvasWrapper* getNativeWrapper(jlong nativeHandle) {
- SkASSERT(nativeHandle);
- return reinterpret_cast<NativeCanvasWrapper*>(nativeHandle);
- }
-
- // Get the SkCanvas for a given native handle.
- static inline SkCanvas* getNativeCanvas(jlong nativeHandle) {
- NativeCanvasWrapper* wrapper = getNativeWrapper(nativeHandle);
- SkCanvas* canvas = wrapper->getCanvas();
- SkASSERT(canvas);
-
- return canvas;
- }
-
- // Construct an SkCanvas from the bitmap.
- static SkCanvas* createCanvas(SkBitmap* bitmap) {
- if (bitmap) {
- return SkNEW_ARGS(SkCanvas, (*bitmap));
- }
-
- // Create an empty bitmap device to prevent callers from crashing
- // if they attempt to draw into this canvas.
- SkBitmap emptyBitmap;
- return new SkCanvas(emptyBitmap);
- }
-
- // Copy the canvas matrix & clip state.
- static void copyCanvasState(SkCanvas* srcCanvas, SkCanvas* dstCanvas) {
- if (srcCanvas && dstCanvas) {
- dstCanvas->setMatrix(srcCanvas->getTotalMatrix());
- if (NULL != srcCanvas->getDevice() && NULL != dstCanvas->getDevice()) {
- ClipCopier copier(dstCanvas);
- srcCanvas->replayClips(&copier);
- }
- }
- }
-
- // Native JNI handlers
- static void finalizer(JNIEnv* env, jobject clazz, jlong nativeHandle) {
- NativeCanvasWrapper* wrapper = reinterpret_cast<NativeCanvasWrapper*>(nativeHandle);
- delete wrapper;
- }
-
- // Native wrapper constructor used by Canvas(Bitmap)
- static jlong initRaster(JNIEnv* env, jobject, jlong bitmapHandle) {
- // No check - 0 is a valid bitmapHandle.
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- SkCanvas* canvas = createCanvas(bitmap);
-
- return reinterpret_cast<jlong>(new NativeCanvasWrapper(canvas));
- }
-
- // Native wrapper constructor used by Canvas(native_canvas)
- static jlong initCanvas(JNIEnv* env, jobject, jlong canvasHandle) {
- SkCanvas* canvas = reinterpret_cast<SkCanvas*>(canvasHandle);
- return reinterpret_cast<jlong>(new NativeCanvasWrapper(canvas));
- }
-
- // Set the given bitmap as the new draw target (wrapped in a new SkCanvas),
- // optionally copying canvas matrix & clip state.
- static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
- jboolean copyState) {
- NativeCanvasWrapper* wrapper = reinterpret_cast<NativeCanvasWrapper*>(canvasHandle);
- SkCanvas* newCanvas = createCanvas(reinterpret_cast<SkBitmap*>(bitmapHandle));
- NPE_CHECK_RETURN_VOID(env, newCanvas);
-
- if (copyState == JNI_TRUE) {
- copyCanvasState(wrapper->getCanvas(), newCanvas);
- }
-
- // setCanvas() unrefs the old canvas.
- wrapper->setCanvas(newCanvas);
- }
-
- static void freeCaches(JNIEnv* env, jobject) {
- SkGraphics::PurgeFontCache();
- }
-
- static void freeTextLayoutCaches(JNIEnv* env, jobject) {
- Layout::purgeCaches();
- }
-
- static jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- bool result = canvas->getDevice()->accessBitmap(false).isOpaque();
- return result ? JNI_TRUE : JNI_FALSE;
- }
-
- static jint getWidth(JNIEnv*, jobject, jlong canvasHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- int width = canvas->getDevice()->accessBitmap(false).width();
- return static_cast<jint>(width);
- }
-
- static jint getHeight(JNIEnv*, jobject, jlong canvasHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- int height = canvas->getDevice()->accessBitmap(false).height();
- return static_cast<jint>(height);
- }
-
- static jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) {
- NativeCanvasWrapper* wrapper = getNativeWrapper(canvasHandle);
- SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
- return static_cast<jint>(wrapper->save(flags));
- }
-
- static jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle,
- jfloat l, jfloat t, jfloat r, jfloat b,
- jlong paintHandle, jint flagsHandle) {
- NativeCanvasWrapper* wrapper = getNativeWrapper(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
- SkRect bounds;
- bounds.set(l, t, r, b);
- return static_cast<jint>(wrapper->saveLayer(&bounds, paint, flags));
- }
-
- static jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle,
- jfloat l, jfloat t, jfloat r, jfloat b,
- jint alpha, jint flagsHandle) {
- NativeCanvasWrapper* wrapper = getNativeWrapper(canvasHandle);
- SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
- SkRect bounds;
- bounds.set(l, t, r, b);
- return static_cast<jint>(wrapper->saveLayerAlpha(&bounds, alpha, flags));
- }
-
- static void restore(JNIEnv* env, jobject, jlong canvasHandle) {
- NativeCanvasWrapper* wrapper = getNativeWrapper(canvasHandle);
- if (wrapper->getCanvas()->getSaveCount() <= 1) { // cannot restore anymore
- doThrowISE(env, "Underflow in restore");
- return;
- }
- wrapper->restore();
- }
-
- static jint getSaveCount(JNIEnv*, jobject, jlong canvasHandle) {
- return static_cast<jint>(getNativeCanvas(canvasHandle)->getSaveCount());
- }
-
- static void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle,
- jint restoreCount) {
- NativeCanvasWrapper* wrapper = getNativeWrapper(canvasHandle);
- if (restoreCount < 1) {
- doThrowIAE(env, "Underflow in restoreToCount");
- return;
- }
-
- while (wrapper->getCanvas()->getSaveCount() > restoreCount) {
- wrapper->restore();
- }
- }
-
- static void translate(JNIEnv*, jobject, jlong canvasHandle,
- jfloat dx, jfloat dy) {
- getNativeCanvas(canvasHandle)->translate(dx, dy);
- }
-
- static void scale__FF(JNIEnv*, jobject, jlong canvasHandle,
- jfloat sx, jfloat sy) {
- getNativeCanvas(canvasHandle)->scale(sx, sy);
- }
-
- static void rotate__F(JNIEnv*, jobject, jlong canvasHandle,
- jfloat degrees) {
- getNativeCanvas(canvasHandle)->rotate(degrees);
- }
-
- static void skew__FF(JNIEnv*, jobject, jlong canvasHandle,
- jfloat sx, jfloat sy) {
- getNativeCanvas(canvasHandle)->skew(sx, sy);
- }
-
- static void concat(JNIEnv* env, jobject, jlong canvasHandle,
- jlong matrixHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
- canvas->concat(*matrix);
- }
-
- static void setMatrix(JNIEnv* env, jobject, jlong canvasHandle,
- jlong matrixHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
- if (NULL == matrix) {
- canvas->resetMatrix();
- } else {
- canvas->setMatrix(*matrix);
- }
- }
-
- static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle,
- jfloat left, jfloat top, jfloat right,
- jfloat bottom, jint op) {
- SkRect r;
- r.set(left, top, right, bottom);
- SkCanvas* c = getNativeCanvas(canvasHandle);
- c->clipRect(r, static_cast<SkRegion::Op>(op));
- return hasNonEmptyClip(*c);
- }
-
- static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle,
- jlong pathHandle, jint op) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- canvas->clipPath(*reinterpret_cast<SkPath*>(pathHandle),
- static_cast<SkRegion::Op>(op));
- return hasNonEmptyClip(*canvas);
- }
-
- static jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle,
- jlong deviceRgnHandle, jint op) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
- SkPath rgnPath;
- if (deviceRgn->getBoundaryPath(&rgnPath)) {
- // The region is specified in device space.
- SkMatrix savedMatrix = canvas->getTotalMatrix();
- canvas->resetMatrix();
- canvas->clipPath(rgnPath, static_cast<SkRegion::Op>(op));
- canvas->setMatrix(savedMatrix);
- } else {
- canvas->clipRect(SkRect::MakeEmpty(), static_cast<SkRegion::Op>(op));
- }
- return hasNonEmptyClip(*canvas);
- }
-
- static void setDrawFilter(JNIEnv* env, jobject, jlong canvasHandle,
- jlong filterHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- canvas->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle));
- }
-
- static jboolean quickReject__Path(JNIEnv* env, jobject, jlong canvasHandle,
- jlong pathHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- bool result = canvas->quickReject(*reinterpret_cast<SkPath*>(pathHandle));
- return result ? JNI_TRUE : JNI_FALSE;
- }
-
- static jboolean quickReject__FFFF(JNIEnv* env, jobject, jlong canvasHandle,
- jfloat left, jfloat top, jfloat right,
- jfloat bottom) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkRect r;
- r.set(left, top, right, bottom);
- bool result = canvas->quickReject(r);
- return result ? JNI_TRUE : JNI_FALSE;
- }
-
- static void drawRGB(JNIEnv* env, jobject, jlong canvasHandle,
- jint r, jint g, jint b) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- canvas->drawARGB(0xFF, r, g, b);
- }
-
- static void drawARGB(JNIEnv* env, jobject, jlong canvasHandle,
- jint a, jint r, jint g, jint b) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- canvas->drawARGB(a, r, g, b);
- }
-
- static void drawColor__I(JNIEnv* env, jobject, jlong canvasHandle,
- jint color) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- canvas->drawColor(color);
- }
-
- static void drawColor__II(JNIEnv* env, jobject, jlong canvasHandle,
- jint color, jint modeHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle);
- canvas->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
- }
-
- static void drawPaint(JNIEnv* env, jobject, jlong canvasHandle,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawPaint(*paint);
- }
-
- static void doPoints(JNIEnv* env, jlong canvasHandle,
- jfloatArray jptsArray, jint offset, jint count,
- jlong paintHandle, jint modeHandle) {
- NPE_CHECK_RETURN_VOID(env, jptsArray);
- SkCanvas::PointMode mode = static_cast<SkCanvas::PointMode>(modeHandle);
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-
- AutoJavaFloatArray autoPts(env, jptsArray);
- float* floats = autoPts.ptr();
- const int length = autoPts.length();
-
- if ((offset | count) < 0 || offset + count > length) {
- doThrowAIOOBE(env);
- return;
- }
-
- // now convert the floats into SkPoints
- count >>= 1; // now it is the number of points
- SkAutoSTMalloc<32, SkPoint> storage(count);
- SkPoint* pts = storage.get();
- const float* src = floats + offset;
- for (int i = 0; i < count; i++) {
- pts[i].set(src[0], src[1]);
- src += 2;
- }
- canvas->drawPoints(mode, count, pts, *paint);
- }
-
- static void drawPoints(JNIEnv* env, jobject, jlong canvasHandle,
- jfloatArray jptsArray, jint offset,
- jint count, jlong paintHandle) {
- doPoints(env, canvasHandle, jptsArray, offset, count, paintHandle,
- SkCanvas::kPoints_PointMode);
- }
-
- static void drawLines(JNIEnv* env, jobject, jlong canvasHandle,
- jfloatArray jptsArray, jint offset, jint count,
- jlong paintHandle) {
- doPoints(env, canvasHandle, jptsArray, offset, count, paintHandle,
- SkCanvas::kLines_PointMode);
- }
-
- static void drawPoint(JNIEnv*, jobject, jlong canvasHandle, jfloat x, jfloat y,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawPoint(x, y, *paint);
- }
-
- static void drawLine__FFFFPaint(JNIEnv* env, jobject, jlong canvasHandle,
- jfloat startX, jfloat startY, jfloat stopX,
- jfloat stopY, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawLine(startX, startY, stopX, stopY, *paint);
- }
-
- static void drawRect__FFFFPaint(JNIEnv* env, jobject, jlong canvasHandle,
- jfloat left, jfloat top, jfloat right,
- jfloat bottom, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawRectCoords(left, top, right, bottom, *paint);
- }
-
- static void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
- jfloat right, jfloat bottom, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
- canvas->drawOval(oval, *paint);
- }
-
- static void drawCircle(JNIEnv* env, jobject, jlong canvasHandle, jfloat cx,
- jfloat cy, jfloat radius, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawCircle(cx, cy, radius, *paint);
- }
-
- static void drawArc(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
- jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle, jboolean useCenter,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
- canvas->drawArc(oval, startAngle, sweepAngle, useCenter, *paint);
- }
-
- static void drawRoundRect(JNIEnv* env, jobject, jlong canvasHandle,
- jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat rx, jfloat ry,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
- canvas->drawRoundRect(rect, rx, ry, *paint);
- }
-
- static void drawPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawPath(*path, *paint);
- }
-
- static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
- jlong canvasHandle, jlong bitmapHandle,
- jfloat left, jfloat top,
- jlong paintHandle, jint canvasDensity,
- jint screenDensity, jint bitmapDensity) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-
- if (canvasDensity == bitmapDensity || canvasDensity == 0
- || bitmapDensity == 0) {
- if (screenDensity != 0 && screenDensity != bitmapDensity) {
- SkPaint filteredPaint;
- if (paint) {
- filteredPaint = *paint;
- }
- filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
- canvas->drawBitmap(*bitmap, left, top, &filteredPaint);
- } else {
- canvas->drawBitmap(*bitmap, left, top, paint);
- }
- } else {
- canvas->save();
- SkScalar scale = canvasDensity / (float)bitmapDensity;
- canvas->translate(left, top);
- canvas->scale(scale, scale);
-
- SkPaint filteredPaint;
- if (paint) {
- filteredPaint = *paint;
- }
- filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
-
- canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
-
- canvas->restore();
- }
- }
-
- static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
- jobject srcIRect, const SkRect& dst, SkPaint* paint,
- jint screenDensity, jint bitmapDensity) {
- SkIRect src, *srcPtr = NULL;
-
- if (NULL != srcIRect) {
- GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
- srcPtr = &src;
- }
-
- if (screenDensity != 0 && screenDensity != bitmapDensity) {
- SkPaint filteredPaint;
- if (paint) {
- filteredPaint = *paint;
- }
- filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
- canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
- } else {
- canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
- }
- }
-
- static void drawBitmapRF(JNIEnv* env, jobject, jlong canvasHandle,
- jlong bitmapHandle, jobject srcIRect,
- jobject dstRectF, jlong paintHandle,
- jint screenDensity, jint bitmapDensity) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkRect dst;
- GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
- doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
- screenDensity, bitmapDensity);
- }
-
- static void drawBitmapRR(JNIEnv* env, jobject, jlong canvasHandle,
- jlong bitmapHandle, jobject srcIRect,
- jobject dstRect, jlong paintHandle,
- jint screenDensity, jint bitmapDensity) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- SkRect dst;
- GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
- doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
- screenDensity, bitmapDensity);
- }
-
- static void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle,
- jintArray jcolors, jint offset, jint stride,
- jfloat x, jfloat y, jint width, jint height,
- jboolean hasAlpha, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will
- // correct the alphaType to kOpaque_SkAlphaType.
- SkImageInfo info = SkImageInfo::Make(width, height,
- hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType,
- kPremul_SkAlphaType);
- SkBitmap bitmap;
- if (!bitmap.allocPixels(info)) {
- return;
- }
-
- if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride,
- 0, 0, width, height, bitmap)) {
- return;
- }
-
- canvas->drawBitmap(bitmap, x, y, paint);
- }
-
- static void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle,
- jlong bitmapHandle, jlong matrixHandle,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- canvas->drawBitmapMatrix(*bitmap, *matrix, paint);
- }
-
- static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle,
- jlong bitmapHandle, jint meshWidth, jint meshHeight,
- jfloatArray jverts, jint vertIndex, jintArray jcolors,
- jint colorIndex, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-
- const int ptCount = (meshWidth + 1) * (meshHeight + 1);
- const int indexCount = meshWidth * meshHeight * 6;
-
- AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1));
- AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
-
- /* Our temp storage holds 2 or 3 arrays.
- texture points [ptCount * sizeof(SkPoint)]
- optionally vertex points [ptCount * sizeof(SkPoint)] if we need a
- copy to convert from float to fixed
- indices [ptCount * sizeof(uint16_t)]
- */
- ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[]
- storageSize += indexCount * sizeof(uint16_t); // indices[]
-
- SkAutoMalloc storage(storageSize);
- SkPoint* texs = (SkPoint*)storage.get();
- SkPoint* verts;
- uint16_t* indices;
-#ifdef SK_SCALAR_IS_FLOAT
- verts = (SkPoint*)(vertA.ptr() + vertIndex);
- indices = (uint16_t*)(texs + ptCount);
-#else
- SkASSERT(false);
-#endif
-
- // cons up texture coordinates and indices
- {
- const SkScalar w = SkIntToScalar(bitmap->width());
- const SkScalar h = SkIntToScalar(bitmap->height());
- const SkScalar dx = w / meshWidth;
- const SkScalar dy = h / meshHeight;
-
- SkPoint* texsPtr = texs;
- SkScalar y = 0;
- for (int i = 0; i <= meshHeight; i++) {
- if (i == meshHeight) {
- y = h; // to ensure numerically we hit h exactly
- }
- SkScalar x = 0;
- for (int j = 0; j < meshWidth; j++) {
- texsPtr->set(x, y);
- texsPtr += 1;
- x += dx;
- }
- texsPtr->set(w, y);
- texsPtr += 1;
- y += dy;
- }
- SkASSERT(texsPtr - texs == ptCount);
- }
-
- // cons up indices
- {
- uint16_t* indexPtr = indices;
- int index = 0;
- for (int i = 0; i < meshHeight; i++) {
- for (int j = 0; j < meshWidth; j++) {
- // lower-left triangle
- *indexPtr++ = index;
- *indexPtr++ = index + meshWidth + 1;
- *indexPtr++ = index + meshWidth + 2;
- // upper-right triangle
- *indexPtr++ = index;
- *indexPtr++ = index + meshWidth + 2;
- *indexPtr++ = index + 1;
- // bump to the next cell
- index += 1;
- }
- // bump to the next row
- index += 1;
- }
- SkASSERT(indexPtr - indices == indexCount);
- SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize);
- }
-
- // double-check that we have legal indices
-#ifdef SK_DEBUG
- {
- for (int i = 0; i < indexCount; i++) {
- SkASSERT((unsigned)indices[i] < (unsigned)ptCount);
- }
- }
-#endif
-
- // cons-up a shader for the bitmap
- SkPaint tmpPaint;
- if (paint) {
- tmpPaint = *paint;
- }
- SkShader* shader = SkShader::CreateBitmapShader(*bitmap,
- SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
- SkSafeUnref(tmpPaint.setShader(shader));
-
- canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts,
- texs, (const SkColor*)colorA.ptr(), NULL, indices,
- indexCount, tmpPaint);
- }
-
- static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
- jint modeHandle, jint vertexCount,
- jfloatArray jverts, jint vertIndex,
- jfloatArray jtexs, jint texIndex,
- jintArray jcolors, jint colorIndex,
- jshortArray jindices, jint indexIndex,
- jint indexCount, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
- const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-
- AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount);
- AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount);
- AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount);
- AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount);
-
- const int ptCount = vertexCount >> 1;
-
- SkPoint* verts;
- SkPoint* texs = NULL;
-#ifdef SK_SCALAR_IS_FLOAT
- verts = (SkPoint*)(vertA.ptr() + vertIndex);
- if (jtexs != NULL) {
- texs = (SkPoint*)(texA.ptr() + texIndex);
- }
-#else
- SkASSERT(false);
-#endif
-
- const SkColor* colors = NULL;
- const uint16_t* indices = NULL;
- if (jcolors != NULL) {
- colors = (const SkColor*)(colorA.ptr() + colorIndex);
- }
- if (jindices != NULL) {
- indices = (const uint16_t*)(indexA.ptr() + indexIndex);
- }
-
- canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL,
- indices, indexCount, *paint);
- }
-
-
- static void drawText___CIIFFIPaintTypeface(JNIEnv* env, jobject, jlong canvasHandle,
- jcharArray text, jint index, jint count,
- jfloat x, jfloat y, jint bidiFlags,
- jlong paintHandle, jlong typefaceHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
- jchar* textArray = env->GetCharArrayElements(text, NULL);
- drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, bidiFlags, paint, typeface);
- env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
- }
-
- static void drawText__StringIIFFIPaintTypeface(JNIEnv* env, jobject,
- jlong canvasHandle, jstring text,
- jint start, jint end,
- jfloat x, jfloat y, jint bidiFlags,
- jlong paintHandle, jlong typefaceHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
- const jchar* textArray = env->GetStringChars(text, NULL);
- drawTextWithGlyphs(canvas, textArray, start, end, x, y, bidiFlags, paint, typeface);
- env->ReleaseStringChars(text, textArray);
- }
-
- class DrawTextFunctor {
- public:
- DrawTextFunctor(const Layout& layout, SkCanvas* canvas, jfloat x, jfloat y, SkPaint* paint,
- uint16_t* glyphs, SkPoint* pos)
- : layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
- pos(pos) { }
-
- void operator()(size_t start, size_t end) {
- for (size_t i = start; i < end; i++) {
- glyphs[i] = layout.getGlyphId(i);
- pos[i].fX = x + layout.getX(i);
- pos[i].fY = y + layout.getY(i);
- }
- canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint);
- }
- private:
- const Layout& layout;
- SkCanvas* canvas;
- jfloat x;
- jfloat y;
- SkPaint* paint;
- uint16_t* glyphs;
- SkPoint* pos;
- };
-
- static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, const Layout& layout, float x, float y) {
- size_t nGlyphs = layout.nGlyphs();
- uint16_t* glyphs = new uint16_t[nGlyphs];
- SkPoint* pos = new SkPoint[nGlyphs];
-
- x += MinikinUtils::xOffsetForTextAlign(paint, layout);
- SkPaint::Align align = paint->getTextAlign();
- paint->setTextAlign(SkPaint::kLeft_Align);
- paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos);
- MinikinUtils::forFontRun(layout, paint, f);
- doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
- paint->setTextAlign(align);
- delete[] glyphs;
- delete[] pos;
- }
-
- static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
- int start, int end,
- jfloat x, jfloat y, int bidiFlags, SkPaint* paint, TypefaceImpl* typeface) {
-
- jint count = end - start;
- drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, bidiFlags, paint,
- typeface);
- }
-
- static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
- int start, int count, int contextCount,
- jfloat x, jfloat y, int bidiFlags, SkPaint* paint, TypefaceImpl* typeface) {
-
- Layout layout;
- std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(textArray, start, count, contextCount, css);
- drawGlyphsToSkia(canvas, paint, layout, x, y);
- }
-
-// Same values used by Skia
-#define kStdStrikeThru_Offset (-6.0f / 21.0f)
-#define kStdUnderline_Offset (1.0f / 9.0f)
-#define kStdUnderline_Thickness (1.0f / 18.0f)
-
- static void doDrawTextDecorations(SkCanvas* canvas, jfloat x, jfloat y, jfloat length,
- SkPaint* paint) {
- uint32_t flags;
- SkDrawFilter* drawFilter = canvas->getDrawFilter();
- if (drawFilter) {
- SkPaint paintCopy(*paint);
- drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type);
- flags = paintCopy.getFlags();
- } else {
- flags = paint->getFlags();
- }
- if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
- SkScalar left = x;
- SkScalar right = x + length;
- float textSize = paint->getTextSize();
- float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f);
- if (flags & SkPaint::kUnderlineText_Flag) {
- SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth;
- SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth;
- canvas->drawRectCoords(left, top, right, bottom, *paint);
- }
- if (flags & SkPaint::kStrikeThruText_Flag) {
- SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth;
- SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth;
- canvas->drawRectCoords(left, top, right, bottom, *paint);
- }
- }
- }
-
- static void doDrawGlyphsPos(SkCanvas* canvas, const jchar* glyphArray, const jfloat* posArray,
- int index, int count, jfloat x, jfloat y, SkPaint* paint) {
- SkPoint* posPtr = new SkPoint[count];
- for (int indx = 0; indx < count; indx++) {
- posPtr[indx].fX = x + posArray[indx * 2];
- posPtr[indx].fY = y + posArray[indx * 2 + 1];
- }
- canvas->drawPosText(glyphArray, count << 1, posPtr, *paint);
- delete[] posPtr;
- }
-
- static void drawTextRun___CIIIIFFZPaintTypeface(
- JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
- jint count, jint contextIndex, jint contextCount,
- jfloat x, jfloat y, jboolean isRtl, jlong paintHandle, jlong typefaceHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
-
- int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
- jchar* chars = env->GetCharArrayElements(text, NULL);
- drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
- count, contextCount, x, y, bidiFlags, paint, typeface);
- env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
- }
-
- static void drawTextRun__StringIIIIFFZPaintTypeface(
- JNIEnv* env, jobject obj, jlong canvasHandle, jstring text, jint start,
- jint end, jint contextStart, jint contextEnd,
- jfloat x, jfloat y, jboolean isRtl, jlong paintHandle, jlong typefaceHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
-
- int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
- jint count = end - start;
- jint contextCount = contextEnd - contextStart;
- const jchar* chars = env->GetStringChars(text, NULL);
- drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
- count, contextCount, x, y, bidiFlags, paint, typeface);
- env->ReleaseStringChars(text, chars);
- }
-
- static void drawPosText___CII_FPaint(JNIEnv* env, jobject, jlong canvasHandle,
- jcharArray text, jint index, jint count,
- jfloatArray pos, jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- jchar* textArray = text ? env->GetCharArrayElements(text, NULL) : NULL;
- jsize textCount = text ? env->GetArrayLength(text) : NULL;
- float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
- int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
- SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
- int indx;
- for (indx = 0; indx < posCount; indx++) {
- posPtr[indx].fX = posArray[indx << 1];
- posPtr[indx].fY = posArray[(indx << 1) + 1];
- }
-
- SkPaint::TextEncoding encoding = paint->getTextEncoding();
- paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
- canvas->drawPosText(textArray + index, count << 1, posPtr, *paint);
- paint->setTextEncoding(encoding);
-
- if (text) {
- env->ReleaseCharArrayElements(text, textArray, 0);
- }
- if (pos) {
- env->ReleaseFloatArrayElements(pos, posArray, 0);
- }
- delete[] posPtr;
- }
-
- static void drawPosText__String_FPaint(JNIEnv* env, jobject,
- jlong canvasHandle, jstring text,
- jfloatArray pos,
- jlong paintHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- const void* text_ = text ? env->GetStringChars(text, NULL) : NULL;
- int byteLength = text ? env->GetStringLength(text) : 0;
- float* posArray = pos ? env->GetFloatArrayElements(pos, NULL) : NULL;
- int posCount = pos ? env->GetArrayLength(pos) >> 1: 0;
- SkPoint* posPtr = posCount > 0 ? new SkPoint[posCount] : NULL;
-
- for (int indx = 0; indx < posCount; indx++) {
- posPtr[indx].fX = posArray[indx << 1];
- posPtr[indx].fY = posArray[(indx << 1) + 1];
- }
-
- SkPaint::TextEncoding encoding = paint->getTextEncoding();
- paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
- canvas->drawPosText(text_, byteLength << 1, posPtr, *paint);
- paint->setTextEncoding(encoding);
-
- if (text) {
- env->ReleaseStringChars(text, (const jchar*) text_);
- }
- if (pos) {
- env->ReleaseFloatArrayElements(pos, posArray, 0);
- }
- delete[] posPtr;
- }
-
- class DrawTextOnPathFunctor {
- public:
- DrawTextOnPathFunctor(const Layout& layout, SkCanvas* canvas, float hOffset,
- float vOffset, SkPaint* paint, SkPath* path)
- : layout(layout), canvas(canvas), hOffset(hOffset), vOffset(vOffset),
- paint(paint), path(path) {
- }
- void operator()(size_t start, size_t end) {
- uint16_t glyphs[1];
- for (size_t i = start; i < end; i++) {
- glyphs[0] = layout.getGlyphId(i);
- float x = hOffset + layout.getX(i);
- float y = vOffset + layout.getY(i);
- canvas->drawTextOnPathHV(glyphs, sizeof(glyphs), *path, x, y, *paint);
- }
- }
- private:
- const Layout& layout;
- SkCanvas* canvas;
- float hOffset;
- float vOffset;
- SkPaint* paint;
- SkPath* path;
- };
-
- static void doDrawTextOnPath(SkPaint* paint, const jchar* text, int count, int bidiFlags,
- float hOffset, float vOffset, SkPath* path, SkCanvas* canvas, TypefaceImpl* typeface) {
- Layout layout;
- std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(text, 0, count, count, css);
- hOffset += MinikinUtils::hOffsetForTextAlign(paint, layout, *path);
- // Set align to left for drawing, as we don't want individual
- // glyphs centered or right-aligned; the offset above takes
- // care of all alignment.
- SkPaint::Align align = paint->getTextAlign();
- paint->setTextAlign(SkPaint::kLeft_Align);
-
- DrawTextOnPathFunctor f(layout, canvas, hOffset, vOffset, paint, path);
- MinikinUtils::forFontRun(layout, paint, f);
- paint->setTextAlign(align);
- }
-
- static void drawTextOnPath___CIIPathFFPaint(JNIEnv* env, jobject,
- jlong canvasHandle, jcharArray text, jint index, jint count,
- jlong pathHandle, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintHandle,
- jlong typefaceHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
-
- jchar* textArray = env->GetCharArrayElements(text, NULL);
- doDrawTextOnPath(paint, textArray + index, count, bidiFlags, hOffset, vOffset,
- path, canvas, typeface);
- env->ReleaseCharArrayElements(text, textArray, 0);
- }
-
- static void drawTextOnPath__StringPathFFPaint(JNIEnv* env, jobject,
- jlong canvasHandle, jstring text, jlong pathHandle,
- jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintHandle,
- jlong typefaceHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
- SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
-
- const jchar* text_ = env->GetStringChars(text, NULL);
- int count = env->GetStringLength(text);
- doDrawTextOnPath(paint, text_, count, bidiFlags, hOffset, vOffset,
- path, canvas, typeface);
- env->ReleaseStringChars(text, text_);
- }
-
-
- // This function is a mirror of SkCanvas::getClipBounds except that it does
- // not outset the edge of the clip to account for anti-aliasing. There is
- // a skia bug to investigate pushing this logic into back into skia.
- // (see https://code.google.com/p/skia/issues/detail?id=1303)
- static bool getHardClipBounds(SkCanvas* canvas, SkRect* bounds) {
- SkIRect ibounds;
- if (!canvas->getClipDeviceBounds(&ibounds)) {
- return false;
- }
-
- SkMatrix inverse;
- // if we can't invert the CTM, we can't return local clip bounds
- if (!canvas->getTotalMatrix().invert(&inverse)) {
- if (bounds) {
- bounds->setEmpty();
- }
- return false;
- }
-
- if (NULL != bounds) {
- SkRect r = SkRect::Make(ibounds);
- inverse.mapRect(bounds, r);
- }
- return true;
- }
-
- static jboolean getClipBounds(JNIEnv* env, jobject, jlong canvasHandle,
- jobject bounds) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkRect r;
- SkIRect ir;
- bool result = getHardClipBounds(canvas, &r);
-
- if (!result) {
- r.setEmpty();
- }
- r.round(&ir);
-
- (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
- return result ? JNI_TRUE : JNI_FALSE;
- }
-
- static void getCTM(JNIEnv* env, jobject, jlong canvasHandle,
- jlong matrixHandle) {
- SkCanvas* canvas = getNativeCanvas(canvasHandle);
- SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
- *matrix = canvas->getTotalMatrix();
- }
-};
-
-static JNINativeMethod gCanvasMethods[] = {
- {"finalizer", "(J)V", (void*) SkCanvasGlue::finalizer},
- {"initRaster", "(J)J", (void*) SkCanvasGlue::initRaster},
- {"initCanvas", "(J)J", (void*) SkCanvasGlue::initCanvas},
- {"native_setBitmap", "(JJZ)V", (void*) SkCanvasGlue::setBitmap},
- {"native_isOpaque","(J)Z", (void*) SkCanvasGlue::isOpaque},
- {"native_getWidth","(J)I", (void*) SkCanvasGlue::getWidth},
- {"native_getHeight","(J)I", (void*) SkCanvasGlue::getHeight},
- {"native_save","(JI)I", (void*) SkCanvasGlue::save},
- {"native_saveLayer","(JFFFFJI)I", (void*) SkCanvasGlue::saveLayer},
- {"native_saveLayerAlpha","(JFFFFII)I", (void*) SkCanvasGlue::saveLayerAlpha},
- {"native_restore","(J)V", (void*) SkCanvasGlue::restore},
- {"native_getSaveCount","(J)I", (void*) SkCanvasGlue::getSaveCount},
- {"native_restoreToCount","(JI)V", (void*) SkCanvasGlue::restoreToCount},
- {"native_translate","(JFF)V", (void*) SkCanvasGlue::translate},
- {"native_scale","(JFF)V", (void*) SkCanvasGlue::scale__FF},
- {"native_rotate","(JF)V", (void*) SkCanvasGlue::rotate__F},
- {"native_skew","(JFF)V", (void*) SkCanvasGlue::skew__FF},
- {"native_concat","(JJ)V", (void*) SkCanvasGlue::concat},
- {"native_setMatrix","(JJ)V", (void*) SkCanvasGlue::setMatrix},
- {"native_clipRect","(JFFFFI)Z", (void*) SkCanvasGlue::clipRect},
- {"native_clipPath","(JJI)Z", (void*) SkCanvasGlue::clipPath},
- {"native_clipRegion","(JJI)Z", (void*) SkCanvasGlue::clipRegion},
- {"nativeSetDrawFilter", "(JJ)V", (void*) SkCanvasGlue::setDrawFilter},
- {"native_getClipBounds","(JLandroid/graphics/Rect;)Z",
- (void*) SkCanvasGlue::getClipBounds},
- {"native_getCTM", "(JJ)V", (void*)SkCanvasGlue::getCTM},
- {"native_quickReject","(JJ)Z", (void*) SkCanvasGlue::quickReject__Path},
- {"native_quickReject","(JFFFF)Z", (void*)SkCanvasGlue::quickReject__FFFF},
- {"native_drawRGB","(JIII)V", (void*) SkCanvasGlue::drawRGB},
- {"native_drawARGB","(JIIII)V", (void*) SkCanvasGlue::drawARGB},
- {"native_drawColor","(JI)V", (void*) SkCanvasGlue::drawColor__I},
- {"native_drawColor","(JII)V", (void*) SkCanvasGlue::drawColor__II},
- {"native_drawPaint","(JJ)V", (void*) SkCanvasGlue::drawPaint},
- {"native_drawPoint", "(JFFJ)V", (void*) SkCanvasGlue::drawPoint},
- {"native_drawPoints", "(J[FIIJ)V", (void*) SkCanvasGlue::drawPoints},
- {"native_drawLines", "(J[FIIJ)V", (void*) SkCanvasGlue::drawLines},
- {"native_drawLine","(JFFFFJ)V", (void*) SkCanvasGlue::drawLine__FFFFPaint},
- {"native_drawRect","(JFFFFJ)V", (void*) SkCanvasGlue::drawRect__FFFFPaint},
- {"native_drawOval","(JFFFFJ)V", (void*) SkCanvasGlue::drawOval},
- {"native_drawCircle","(JFFFJ)V", (void*) SkCanvasGlue::drawCircle},
- {"native_drawArc","(JFFFFFFZJ)V", (void*) SkCanvasGlue::drawArc},
- {"native_drawRoundRect","(JFFFFFFJ)V",
- (void*) SkCanvasGlue::drawRoundRect},
- {"native_drawPath","(JJJ)V", (void*) SkCanvasGlue::drawPath},
- {"native_drawBitmap","(JJFFJIII)V",
- (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
- {"native_drawBitmap","(JJLandroid/graphics/Rect;Landroid/graphics/RectF;JII)V",
- (void*) SkCanvasGlue::drawBitmapRF},
- {"native_drawBitmap","(JJLandroid/graphics/Rect;Landroid/graphics/Rect;JII)V",
- (void*) SkCanvasGlue::drawBitmapRR},
- {"native_drawBitmap", "(J[IIIFFIIZJ)V",
- (void*)SkCanvasGlue::drawBitmapArray},
- {"nativeDrawBitmapMatrix", "(JJJJ)V",
- (void*)SkCanvasGlue::drawBitmapMatrix},
- {"nativeDrawBitmapMesh", "(JJII[FI[IIJ)V",
- (void*)SkCanvasGlue::drawBitmapMesh},
- {"nativeDrawVertices", "(JII[FI[FI[II[SIIJ)V",
- (void*)SkCanvasGlue::drawVertices},
- {"native_drawText","(J[CIIFFIJJ)V",
- (void*) SkCanvasGlue::drawText___CIIFFIPaintTypeface},
- {"native_drawText","(JLjava/lang/String;IIFFIJJ)V",
- (void*) SkCanvasGlue::drawText__StringIIFFIPaintTypeface},
- {"native_drawTextRun","(J[CIIIIFFZJJ)V",
- (void*) SkCanvasGlue::drawTextRun___CIIIIFFZPaintTypeface},
- {"native_drawTextRun","(JLjava/lang/String;IIIIFFZJJ)V",
- (void*) SkCanvasGlue::drawTextRun__StringIIIIFFZPaintTypeface},
- {"native_drawTextOnPath","(J[CIIJFFIJJ)V",
- (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
- {"native_drawTextOnPath","(JLjava/lang/String;JFFIJJ)V",
- (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
-
- {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches},
-
- {"freeTextLayoutCaches", "()V", (void*) SkCanvasGlue::freeTextLayoutCaches}
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include <android_runtime/AndroidRuntime.h>
-
-#define REG(env, name, array) \
- result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
- SK_ARRAY_COUNT(array)); \
- if (result < 0) return result
-
-int register_android_graphics_Canvas(JNIEnv* env) {
- int result;
-
- REG(env, "android/graphics/Canvas", gCanvasMethods);
-
- return result;
-}
-
-} // namespace android
-
-// GraphicsJNI helper for external clients.
-// We keep the implementation here to avoid exposing NativeCanvasWrapper
-// externally.
-SkCanvas* GraphicsJNI::getNativeCanvas(jlong nativeHandle) {
- return android::SkCanvasGlue::getNativeCanvas(nativeHandle);
-}