Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8cb6a36 authored by The Android Automerger's avatar The Android Automerger
Browse files

Merge branch 'eclair' into eclair-release

parents f1c2f57f 6f9e2c64
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -147,12 +147,9 @@ public class ScaleGestureDetector {

    public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
        ViewConfiguration config = ViewConfiguration.get(context);
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        mContext = context;
        mListener = listener;
        mEdgeSlop = config.getScaledEdgeSlop();
        mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
        mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
    }

    public boolean onTouchEvent(MotionEvent event) {
@@ -165,6 +162,11 @@ public class ScaleGestureDetector {
                    event.getPointerCount() >= 2) {
                // We have a new multi-finger gesture

                // as orientation can change, query the metrics in touch down
                DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
                mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
                mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;

                // Be paranoid in case we missed an event
                reset();

@@ -185,12 +187,16 @@ public class ScaleGestureDetector {
                final float x1 = getRawX(event, 1);
                final float y1 = getRawY(event, 1);

                boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop ||
                        x1 < edgeSlop || y1 < edgeSlop;
                boolean p1sloppy = x0 > rightSlop || y0 > bottomSlop ||
                        x1 > rightSlop || y1 > bottomSlop;
                boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop
                        || x0 > rightSlop || y0 > bottomSlop;
                boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop
                        || x1 > rightSlop || y1 > bottomSlop;

                if (p0sloppy) {
                if(p0sloppy && p1sloppy) {
                    mFocusX = -1;
                    mFocusY = -1;
                    mSloppyGesture = true;
                } else if (p0sloppy) {
                    mFocusX = event.getX(1);
                    mFocusY = event.getY(1);
                    mSloppyGesture = true;
@@ -211,12 +217,15 @@ public class ScaleGestureDetector {
                final float x1 = getRawX(event, 1);
                final float y1 = getRawY(event, 1);

                boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop ||
                x1 < edgeSlop || y1 < edgeSlop;
                boolean p1sloppy = x0 > rightSlop || y0 > bottomSlop ||
                x1 > rightSlop || y1 > bottomSlop;
                boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop
                        || x0 > rightSlop || y0 > bottomSlop;
                boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop
                        || x1 > rightSlop || y1 > bottomSlop;

                if (p0sloppy) {
                if(p0sloppy && p1sloppy) {
                    mFocusX = -1;
                    mFocusY = -1;
                } else if (p0sloppy) {
                    mFocusX = event.getX(1);
                    mFocusY = event.getY(1);
                } else if (p1sloppy) {
@@ -226,6 +235,14 @@ public class ScaleGestureDetector {
                    mSloppyGesture = false;
                    mGestureInProgress = mListener.onScaleBegin(this);
                }
            } else if ((action == MotionEvent.ACTION_POINTER_1_UP
                    || action == MotionEvent.ACTION_POINTER_2_UP)
                    && mSloppyGesture) {
                // Set focus point to the remaining finger
                int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK)
                        >> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0;
                mFocusX = event.getX(id);
                mFocusY = event.getY(id);
            }
        } else {
            // Transform gesture in progress - attempt to handle it
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ class DebugFlags {
    public static final boolean CALLBACK_PROXY = false;
    public static final boolean COOKIE_MANAGER = false;
    public static final boolean COOKIE_SYNC_MANAGER = false;
    public static final boolean DRAG_TRACKER = false;
    public static final String DRAG_TRACKER_LOGTAG = "skia";
    public static final boolean FRAME_LOADER = false;
    public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
    public static final boolean LOAD_LISTENER = false;
+267 −37
Original line number Diff line number Diff line
@@ -200,6 +200,8 @@ public class WebView extends AbsoluteLayout
        implements ViewTreeObserver.OnGlobalFocusChangeListener,
        ViewGroup.OnHierarchyChangeListener {

    // enable debug output for drag trackers
    private static final boolean DEBUG_DRAG_TRACKER = false;
    // if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
    // the screen all-the-time. Good for profiling our drawing code
    static private final boolean AUTO_REDRAW_HACK = false;
@@ -534,8 +536,10 @@ public class WebView extends AbsoluteLayout
    static int DEFAULT_SCALE_PERCENT;
    private float mDefaultScale;

    // set to true temporarily while the zoom control is being dragged
    // set to true temporarily during ScaleGesture triggered zoom
    private boolean mPreviewZoomOnly = false;
    // extra scale during zoom preview
    private float mPreviewExtraZoomScale = 1.0f;

    // computed scale and inverse, from mZoomWidth.
    private float mActualScale;
@@ -2796,16 +2800,7 @@ public class WebView extends AbsoluteLayout
        return super.drawChild(canvas, child, drawingTime);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // if mNativeClass is 0, the WebView has been destroyed. Do nothing.
        if (mNativeClass == 0) {
            return;
        }
        int saveCount = canvas.save();
        if (mTitleBar != null) {
            canvas.translate(0, (int) mTitleBar.getHeight());
        }
    private void drawContent(Canvas canvas) {
        // Update the buttons in the picture, so when we draw the picture
        // to the screen, they are in the correct state.
        // Tell the native side if user is a) touching the screen,
@@ -2817,11 +2812,34 @@ public class WebView extends AbsoluteLayout
        nativeRecordButtons(hasFocus() && hasWindowFocus(),
                mTouchMode == TOUCH_SHORTPRESS_START_MODE
                || mTrackballDown || mGotCenterDown, false);
        drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing);
        canvas.restoreToCount(saveCount);
        // use the DKGRAY as background when drawing zoom preview
        drawCoreAndCursorRing(canvas, mPreviewZoomOnly ? Color.DKGRAY
                : mBackgroundColor, mDrawCursorRing);
    }

        // Now draw the shadow.
    @Override
    protected void onDraw(Canvas canvas) {
        // if mNativeClass is 0, the WebView has been destroyed. Do nothing.
        if (mNativeClass == 0) {
            return;
        }
        int saveCount = canvas.save();
        if (mPreviewZoomOnly) {
            // scale after canvas.save() so that the child, like titlebar, will
            // not be scaled.
            canvas.scale(mPreviewExtraZoomScale, mPreviewExtraZoomScale,
                    mZoomCenterX + mScrollX, mZoomCenterY + mScrollY);
        }
        if (mTitleBar != null) {
            canvas.translate(0, (int) mTitleBar.getHeight());
        }
        if (mDragTrackerHandler == null || !mDragTrackerHandler.draw(canvas)) {
            drawContent(canvas);
        }
        canvas.restoreToCount(saveCount);

        // Now draw the shadow, skip if it is in zoom preview mode.
        if ((mTitleBar != null && !mPreviewZoomOnly)) {
            int y = mScrollY + getVisibleTitleHeight();
            int height = (int) (5f * getContext().getResources()
                    .getDisplayMetrics().density);
@@ -3726,6 +3744,8 @@ public class WebView extends AbsoluteLayout
    private class ScaleDetectorListener implements
            ScaleGestureDetector.OnScaleGestureListener {

        float mStartX, mStartY;

        public boolean onScaleBegin(ScaleGestureDetector detector) {
            // cancel the single touch handling
            cancelTouch();
@@ -3739,6 +3759,9 @@ public class WebView extends AbsoluteLayout
            if (inEditingMode() && nativeFocusCandidateIsPassword()) {
                mWebTextView.setInPassword(false);
            }
            mPreviewExtraZoomScale = 1.0f;
            mStartX = detector.getFocusX();
            mStartY = detector.getFocusY();
            return true;
        }

@@ -3747,13 +3770,12 @@ public class WebView extends AbsoluteLayout
                mPreviewZoomOnly = false;
                mAnchorX = viewToContentX((int) mZoomCenterX + mScrollX);
                mAnchorY = viewToContentY((int) mZoomCenterY + mScrollY);
                float scale = mPreviewExtraZoomScale * mActualScale;
                // don't reflow when zoom in; when zoom out, do reflow if the
                // new scale is almost minimum scale;
                boolean reflowNow = (mActualScale - mMinZoomScale <= 0.01f)
                        || ((mActualScale <= 0.8 * mTextWrapScale));
                // force zoom after mPreviewZoomOnly is set to false so that the
                // new view size will be passed to the WebKit
                setNewZoomScale(mActualScale, reflowNow, true);
                boolean reflowNow = (scale - mMinZoomScale <= 0.01f)
                        || ((scale <= 0.8 * mTextWrapScale));
                setNewZoomScale(scale, reflowNow, false);
                // call invalidate() to draw without zoom filter
                invalidate();
            }
@@ -3770,26 +3792,197 @@ public class WebView extends AbsoluteLayout
        }

        public boolean onScale(ScaleGestureDetector detector) {
            float currScale = mPreviewExtraZoomScale * mActualScale;
            float scale = (float) (Math.round(detector.getScaleFactor()
                    * mActualScale * 100) / 100.0);
            if (Math.abs(scale - mActualScale) >= PREVIEW_SCALE_INCREMENT) {
                mPreviewZoomOnly = true;
                    * currScale * 100) / 100.0);
            // limit the scale change per step
                if (scale > mActualScale) {
                    scale = Math.min(scale, mActualScale * 1.25f);
            if (scale > currScale) {
                scale = Math.min(scale, currScale * 1.25f);
            } else {
                    scale = Math.max(scale, mActualScale * 0.8f);
                // the preview scale can be 80% of mMinZoomScale for feedback
                scale = Math.max(Math.max(scale, currScale * 0.8f),
                        mMinZoomScale * 0.8f);
            }
            if (Math.abs(scale - currScale) >= PREVIEW_SCALE_INCREMENT) {
                mPreviewZoomOnly = true;
                // FIXME: mZoomCenterX/Y need to be relative to mActualScale.
                // Ideally the focusX/Y should be a fixed point. But currently
                // it just returns the center of the two pointers. If only one
                // pointer is moving, the center is shifting. Currently we only
                // adjust it for zoom in case to get better result.
                if (mPreviewExtraZoomScale > 1.0f) {
                    mZoomCenterX = mStartX - (mStartX - detector.getFocusX())
                            / mPreviewExtraZoomScale;
                    mZoomCenterY = mStartY - (mStartY - detector.getFocusY())
                            / mPreviewExtraZoomScale;
                } else {
                    mZoomCenterX = detector.getFocusX();
                    mZoomCenterY = detector.getFocusY();
                setNewZoomScale(scale, false, false);
                }
                mPreviewExtraZoomScale = scale / mActualScale;
                invalidate();
                return true;
            }
            return false;
        }
    }

    // if the page can scroll <= this value, we won't allow the drag tracker
    // to have any effect.
    private static final int MIN_SCROLL_AMOUNT_TO_DISABLE_DRAG_TRACKER = 4;

    private class DragTrackerHandler {
        private final DragTracker mProxy;
        private final float mStartY, mStartX;
        private final float mMinDY, mMinDX;
        private final float mMaxDY, mMaxDX;
        private float mCurrStretchY, mCurrStretchX;
        private int mSX, mSY;

        public DragTrackerHandler(float x, float y, DragTracker proxy) {
            mProxy = proxy;

            int docBottom = computeVerticalScrollRange() + getTitleHeight();
            int viewTop = getScrollY();
            int viewBottom = viewTop + getHeight();

            mStartY = y;
            mMinDY = -viewTop;
            mMaxDY = docBottom - viewBottom;

            if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
                Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, " dragtracker y= " + y +
                      " up/down= " + mMinDY + " " + mMaxDY);
            }

            int docRight = computeHorizontalScrollRange();
            int viewLeft = getScrollX();
            int viewRight = viewLeft + getWidth();
            mStartX = x;
            mMinDX = -viewLeft;
            mMaxDX = docRight - viewRight;

            mProxy.onStartDrag(x, y);

            // ensure we buildBitmap at least once
            mSX = -99999;
        }

        private float computeStretch(float delta, float min, float max) {
            float stretch = 0;
            if (max - min > MIN_SCROLL_AMOUNT_TO_DISABLE_DRAG_TRACKER) {
                if (delta < min) {
                    stretch = delta - min;
                } else if (delta > max) {
                    stretch = delta - max;
                }
            }
            return stretch;
        }

        public void dragTo(float x, float y) {
            float sy = computeStretch(mStartY - y, mMinDY, mMaxDY);
            float sx = computeStretch(mStartX - x, mMinDX, mMaxDX);

            if (mCurrStretchX != sx || mCurrStretchY != sy) {
                mCurrStretchX = sx;
                mCurrStretchY = sy;
                if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
                    Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, "---- stretch " + sx +
                          " " + sy);
                }
                if (mProxy.onStretchChange(sx, sy)) {
                    invalidate();
                }
            }
        }

        public void stopDrag() {
            if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
                Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, "----- stopDrag");
            }
            mProxy.onStopDrag();
        }

        private int hiddenHeightOfTitleBar() {
            return getTitleHeight() - getVisibleTitleHeight();
        }

        // need a way to know if 565 or 8888 is the right config for
        // capturing the display and giving it to the drag proxy
        private Bitmap.Config offscreenBitmapConfig() {
            // hard code 565 for now
            return Bitmap.Config.RGB_565;
        }

        /*  If the tracker draws, then this returns true, otherwise it will
         return false, and draw nothing.
         */
        public boolean draw(Canvas canvas) {
            if (mCurrStretchX != 0 || mCurrStretchY != 0) {
                int sx = getScrollX();
                int sy = getScrollY() - hiddenHeightOfTitleBar();

                if (mSX != sx || mSY != sy) {
                    buildBitmap(sx, sy);
                    mSX = sx;
                    mSY = sy;
                }

                int count = canvas.save(Canvas.MATRIX_SAVE_FLAG);
                canvas.translate(sx, sy);
                mProxy.onDraw(canvas);
                canvas.restoreToCount(count);
                return true;
            }
            if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
                Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, " -- draw false " +
                      mCurrStretchX + " " + mCurrStretchY);
            }
            return false;
        }

        private void buildBitmap(int sx, int sy) {
            int w = getWidth();
            int h = getViewHeight();
            Bitmap bm = Bitmap.createBitmap(w, h, offscreenBitmapConfig());
            Canvas canvas = new Canvas(bm);
            canvas.translate(-sx, -sy);
            drawContent(canvas);

            if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
                Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, "--- buildBitmap " + sx +
                      " " + sy + " " + w + " " + h);
            }
            mProxy.onBitmapChange(bm);
        }
    }

    /** @hide */
    public static class DragTracker {
        public void onStartDrag(float x, float y) {}
        public boolean onStretchChange(float sx, float sy) {
            // return true to have us inval the view
            return false;
        }
        public void onStopDrag() {}
        public void onBitmapChange(Bitmap bm) {}
        public void onDraw(Canvas canvas) {}
    }

    /** @hide */
    public DragTracker getDragTracker() {
        return mDragTracker;
    }

    /** @hide */
    public void setDragTracker(DragTracker tracker) {
        mDragTracker = tracker;
    }

    private DragTracker mDragTracker;
    private DragTrackerHandler mDragTrackerHandler;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mNativeClass == 0 || !isClickable() || !isLongClickable()) {
@@ -3801,18 +3994,39 @@ public class WebView extends AbsoluteLayout
                    + mTouchMode);
        }

        int action;
        float x, y;
        long eventTime = ev.getEventTime();

        // FIXME: we may consider to give WebKit an option to handle multi-touch
        // events later.
        if (mSupportMultiTouch && mMinZoomScale < mMaxZoomScale
                && ev.getPointerCount() > 1) {
            mLastTouchTime = ev.getEventTime();
            return mScaleDetector.onTouchEvent(ev);
        if (mSupportMultiTouch && ev.getPointerCount() > 1) {
            mScaleDetector.onTouchEvent(ev);
            if (mScaleDetector.isInProgress()) {
                mLastTouchTime = eventTime;
                return true;
            }
            x = mScaleDetector.getFocusX();
            y = mScaleDetector.getFocusY();
            action = ev.getAction() & MotionEvent.ACTION_MASK;
            if (action == MotionEvent.ACTION_POINTER_DOWN) {
                cancelTouch();
                action = MotionEvent.ACTION_DOWN;
            } else if (action == MotionEvent.ACTION_POINTER_UP) {
                // set mLastTouchX/Y to the remaining point
                mLastTouchX = x;
                mLastTouchY = y;
            } else if (action == MotionEvent.ACTION_MOVE) {
                // negative x or y indicate it is on the edge, skip it.
                if (x < 0 || y < 0) {
                    return true;
                }
            }
        } else {
            action = ev.getAction();
            x = ev.getX();
            y = ev.getY();
        }

        int action = ev.getAction();
        float x = ev.getX();
        float y = ev.getY();
        long eventTime = ev.getEventTime();

        // Due to the touch screen edge effect, a touch closer to the edge
        // always snapped to the edge. As getViewWidth() can be different from
@@ -3888,6 +4102,10 @@ public class WebView extends AbsoluteLayout
                }
                // Remember where the motion event started
                startTouch(x, y, eventTime);
                if (mDragTracker != null) {
                    mDragTrackerHandler = new DragTrackerHandler(x, y,
                                                                 mDragTracker);
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {
@@ -4045,6 +4263,10 @@ public class WebView extends AbsoluteLayout
                    }
                }

                if (mDragTrackerHandler != null) {
                    mDragTrackerHandler.dragTo(x, y);
                }

                if (done) {
                    // keep the scrollbar on the screen even there is no scroll
                    awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(),
@@ -4056,6 +4278,10 @@ public class WebView extends AbsoluteLayout
                break;
            }
            case MotionEvent.ACTION_UP: {
                if (mDragTrackerHandler != null) {
                    mDragTrackerHandler.stopDrag();
                    mDragTrackerHandler = null;
                }
                mLastTouchUpTime = eventTime;
                switch (mTouchMode) {
                    case TOUCH_DOUBLE_TAP_MODE: // double tap
@@ -4131,6 +4357,10 @@ public class WebView extends AbsoluteLayout
                break;
            }
            case MotionEvent.ACTION_CANCEL: {
                if (mDragTrackerHandler != null) {
                    mDragTrackerHandler.stopDrag();
                    mDragTrackerHandler = null;
                }
                cancelTouch();
                break;
            }
+41 −1
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@
#include "SkShader.h"
#include "SkTemplates.h"

#include "SkBoundaryPatch.h"
#include "SkMeshUtils.h"

#define TIME_DRAWx

static uint32_t get_thread_msec() {
@@ -965,6 +968,42 @@ static JNINativeMethod gCanvasMethods[] = {
    {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
};

///////////////////////////////////////////////////////////////////////////////

static void BoundaryPatch_computeCubic(JNIEnv* env, jobject, jfloatArray jpts,
                                       int texW, int texH, int rows, int cols,
                                       jfloatArray jverts, jshortArray jidx) {
    AutoJavaFloatArray ptsArray(env, jpts, 24);

    int vertCount = rows * cols;
    AutoJavaFloatArray vertsArray(env, jverts, vertCount * 4);
    SkPoint* verts = (SkPoint*)vertsArray.ptr();
    SkPoint* texs = verts + vertCount;

    int idxCount = (rows - 1) * (cols - 1) * 6;
    AutoJavaShortArray idxArray(env, jidx, idxCount);
    uint16_t* idx = (uint16_t*)idxArray.ptr();  // cast from int16_t*

    SkCubicBoundary cubic;
    memcpy(cubic.fPts, ptsArray.ptr(), 12 * sizeof(SkPoint));

    SkBoundaryPatch patch;
    patch.setBoundary(&cubic);
    // generate our verts
    patch.evalPatch(verts, rows, cols);

    SkMeshIndices mesh;
    // generate our texs and idx
    mesh.init(texs, idx, texW, texH, rows, cols);
}

static JNINativeMethod gBoundaryPatchMethods[] = {
    {"nativeComputeCubicPatch", "([FIIII[F[S)V",
    (void*)BoundaryPatch_computeCubic },
};

///////////////////////////////////////////////////////////////////////////////

#include <android_runtime/AndroidRuntime.h>

#define REG(env, name, array) \
@@ -976,6 +1015,7 @@ int register_android_graphics_Canvas(JNIEnv* env) {
    int result;

    REG(env, "android/graphics/Canvas", gCanvasMethods);
    REG(env, "android/graphics/utils/BoundaryPatch", gBoundaryPatchMethods);

    return result;
}
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ static SkTypeface* Typeface_createFromTypeface(JNIEnv* env, jobject, SkTypeface*
}
 
static void Typeface_unref(JNIEnv* env, jobject obj, SkTypeface* face) {
    face->unref();
    SkSafeUnref(face);
}

static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) {
Loading