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