Home | History | Annotate | Download | only in browser
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.browser;
     18 
     19 import android.graphics.Bitmap;
     20 import android.graphics.utils.BoundaryPatch;
     21 import android.graphics.Canvas;
     22 import android.graphics.Paint;
     23 import android.webkit.WebView;
     24 
     25 /*package*/ class MeshTracker extends WebView.DragTracker {
     26 
     27     private static class Mesh {
     28         private int mWhich;
     29         private int mRows;
     30         private int mCols;
     31         private BoundaryPatch mPatch = new BoundaryPatch();
     32         private float[] mCubics = new float[24];
     33         private float[] mOrig = new float[24];
     34         private float mStretchX, mStretchY;
     35 
     36         Mesh(int which, int rows, int cols) {
     37             mWhich = which;
     38             mRows = rows;
     39             mCols = cols;
     40         }
     41 
     42         private void rebuildPatch() {
     43             mPatch.setCubicBoundary(mCubics, 0, mRows, mCols);
     44         }
     45 
     46         private void setSize(float w, float h) {
     47             float[] pts = mCubics;
     48             float x1 = w*0.3333f;
     49             float y1 = h*0.3333f;
     50             float x2 = w*0.6667f;
     51             float y2 = h*0.6667f;
     52             pts[0*2+0] = 0;  pts[0*2+1] = 0;
     53             pts[1*2+0] = x1; pts[1*2+1] = 0;
     54             pts[2*2+0] = x2; pts[2*2+1] = 0;
     55 
     56             pts[3*2+0] = w; pts[3*2+1] = 0;
     57             pts[4*2+0] = w; pts[4*2+1] = y1;
     58             pts[5*2+0] = w; pts[5*2+1] = y2;
     59 
     60             pts[6*2+0] = w; pts[6*2+1] = h;
     61             pts[7*2+0] = x2; pts[7*2+1] = h;
     62             pts[8*2+0] = x1; pts[8*2+1] = h;
     63 
     64             pts[9*2+0] = 0;  pts[9*2+1] = h;
     65             pts[10*2+0] = 0; pts[10*2+1] = y2;
     66             pts[11*2+0] = 0; pts[11*2+1] = y1;
     67 
     68             System.arraycopy(pts, 0, mOrig, 0, 24);
     69 
     70             // recall our stretcher
     71             setStretch(mStretchX, mStretchY);
     72         }
     73 
     74         public void setBitmap(Bitmap bm) {
     75             mPatch.setTexture(bm);
     76             setSize(bm.getWidth(), bm.getHeight());
     77         }
     78 
     79         // first experimental behavior
     80         private void doit1(float dx, float dy) {
     81             final float scale = 0.75f;  // temper how far we actually move
     82             dx *= scale;
     83             dy *= scale;
     84 
     85             int index;
     86             if (dx < 0) {
     87                 index = 10;
     88             } else {
     89                 index = 4;
     90             }
     91             mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx;
     92             mCubics[index*2 + 2] = mOrig[index*2 + 2] + dx;
     93 
     94             if (dy < 0) {
     95                 index = 1;
     96             } else {
     97                 index = 7;
     98             }
     99             mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy;
    100             mCubics[index*2 + 3] = mOrig[index*2 + 3] + dy;
    101         }
    102 
    103         private void doit2(float dx, float dy) {
    104             final float scale = 0.35f;  // temper how far we actually move
    105             dx *= scale;
    106             dy *= scale;
    107             final float cornerScale = 0.25f;
    108 
    109             int index;
    110             if (dx < 0) {
    111                 index = 4;
    112             } else {
    113                 index = 10;
    114             }
    115             mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx;
    116             mCubics[index*2 + 2] = mOrig[index*2 + 2] + dx;
    117             // corners
    118             index -= 1;
    119             mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx * cornerScale;
    120             index = (index + 3) % 12; // next corner
    121             mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx * cornerScale;
    122 
    123             if (dy < 0) {
    124                 index = 7;
    125             } else {
    126                 index = 1;
    127             }
    128             mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy;
    129             mCubics[index*2 + 3] = mOrig[index*2 + 3] + dy;
    130             // corners
    131             index -= 1;
    132             mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy * cornerScale;
    133             index = (index + 3) % 12; // next corner
    134             mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy * cornerScale;
    135         }
    136 
    137         public void setStretch(float dx, float dy) {
    138             mStretchX = dx;
    139             mStretchY = dy;
    140             switch (mWhich) {
    141                 case 1:
    142                     doit1(dx, dy);
    143                     break;
    144                 case 2:
    145                     doit2(dx, dy);
    146                     break;
    147             }
    148             rebuildPatch();
    149         }
    150 
    151         public void draw(Canvas canvas) {
    152             mPatch.draw(canvas);
    153         }
    154     }
    155 
    156     private Mesh mMesh;
    157     private Bitmap mBitmap;
    158     private int mWhich;
    159     private Paint mBGPaint;
    160 
    161     public MeshTracker(int which) {
    162         mWhich = which;
    163     }
    164 
    165     public void setBGPaint(Paint paint) {
    166         mBGPaint = paint;
    167     }
    168 
    169     @Override public void onStartDrag(float x, float y) {
    170         mMesh = new Mesh(mWhich, 16, 16);
    171     }
    172 
    173     @Override public void onBitmapChange(Bitmap bm) {
    174         mBitmap = bm;
    175         mMesh.setBitmap(bm);
    176     }
    177 
    178     @Override public boolean onStretchChange(float sx, float sy) {
    179         mMesh.setStretch(-sx, -sy);
    180         return true;
    181     }
    182 
    183     @Override public void onStopDrag() {
    184         mMesh = null;
    185     }
    186 
    187     @Override public void onDraw(Canvas canvas) {
    188         if (mWhich == 2) {
    189             if (mBGPaint != null) {
    190                 canvas.drawPaint(mBGPaint);
    191             } else {
    192                 canvas.drawColor(0xFF000000);
    193             }
    194         }
    195         mMesh.draw(canvas);
    196     }
    197 }
    198 
    199