content: package com.anlia.pageturn.view;
  
  import android.annotation.TargetApi;
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Matrix;
  import android.graphics.Paint;
  import android.graphics.Path;
  import android.graphics.Region;
  import android.graphics.drawable.GradientDrawable;
  import android.os.Trace;
  import android.support.annotation.Nullable;
  import android.util.AttributeSet;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.animation.LinearInterpolator;
  import android.widget.Scroller;
  
  import com.anlia.pageturn.R;
  import com.anlia.pageturn.bean.MyPoint;
  
  /**
   * Created by anlia on 2017/10/19.
   */
  
  public class BookPageView extends View {
      private Paint pointPaint;//绘制各标识点的画笔
      private Paint bgPaint;//背景画笔
      private Paint pathAPaint;//绘制A区域画笔
      private Paint pathBPaint;//绘制B区域画笔
      private Paint pathCPaint;//绘制C区域画笔
      private Paint textPaint;//绘制文字画笔
      private Paint pathCContentPaint;//绘制C区域内容画笔
  
      private MyPoint a,f,g,e,h,c,j,b,k,d,i;
      private Path pathA;
      private Path pathB;
      private Path pathC;
  
      private int defaultWidth;//默认宽度
      private int defaultHeight;//默认高度
  
      private int viewWidth;
      private int viewHeight;
  
      float lPathAShadowDis = 0;//A区域左阴影矩形短边长度参考值
      float rPathAShadowDis = 0;//A区域右阴影矩形短边长度参考值
      private float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f };
      private Matrix mMatrix;
  
      private Scroller mScroller;
  
      private String style;
      public static final String STYLE_LEFT = "STYLE_LEFT";//点击左边区域
      public static final String STYLE_RIGHT = "STYLE_RIGHT";//点击右边区域
      public static final String STYLE_MIDDLE = "STYLE_MIDDLE";//点击中间区域
      public static final String STYLE_TOP_RIGHT = "STYLE_TOP_RIGHT";//f点在右上角
      public static final String STYLE_LOWER_RIGHT = "STYLE_LOWER_RIGHT";//f点在右下角
  
      private GradientDrawable drawableLeftTopRight;
      private GradientDrawable drawableLeftLowerRight;
  
      private GradientDrawable drawableRightTopRight;
      private GradientDrawable drawableRightLowerRight;
      private GradientDrawable drawableHorizontalLowerRight;
  
      private GradientDrawable drawableBTopRight;
      private GradientDrawable drawableBLowerRight;
  
      private GradientDrawable drawableCTopRight;
      private GradientDrawable drawableCLowerRight;
  
      private Bitmap pathAContentBitmap;//A区域内容Bitmap
      private Bitmap pathBContentBitmap;//B区域内容Bitmap
      private Bitmap pathCContentBitmap;//C区域内容Bitmap
  
      public BookPageView(Context context, @Nullable AttributeSet attrs) {
          super(context, attrs);
          init(context,attrs);
      }
  
      private void init(Context context, @Nullable AttributeSet attrs){
          defaultWidth = 600;
          defaultHeight = 1000;
  
          a = new MyPoint();
          f = new MyPoint();
          g = new MyPoint();
          e = new MyPoint();
          h = new MyPoint();
          c = new MyPoint();
          j = new MyPoint();
          b = new MyPoint();
          k = new MyPoint();
          d = new MyPoint();
          i = new MyPoint();
  
          pointPaint = new Paint();
          pointPaint.setColor(Color.RED);
          pointPaint.setTextSize(25);
          pointPaint.setStyle(Paint.Style.STROKE);
  
          bgPaint = new Paint();
          bgPaint.setColor(Color.GREEN);
  
          pathAPaint = new Paint();
          pathAPaint.setColor(Color.GREEN);
          pathAPaint.setAntiAlias(true);//设置抗锯齿
  
          pathBPaint = new Paint();
          pathBPaint.setColor(getResources().getColor(R.color.blue_light));
          pathBPaint.setAntiAlias(true);//设置抗锯齿
  //        pathBPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));我们不需要单独绘制path了，记得注释掉
  
          pathCPaint = new Paint();
          pathCPaint.setColor(Color.YELLOW);
          pathCPaint.setAntiAlias(true);//设置抗锯齿
  //        pathCPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
  //        pathCPaint.setStyle(Paint.Style.STROKE);
  
          pathCContentPaint = new Paint();
          pathCContentPaint.setColor(Color.YELLOW);
          pathCContentPaint.setAntiAlias(true);//设置抗锯齿
  
          textPaint = new Paint();
          textPaint.setColor(Color.BLACK);
          textPaint.setTextAlign(Paint.Align.CENTER);
          textPaint.setSubpixelText(true);//设置自像素。如果该项为true，将有助于文本在LCD屏幕上的显示效果。
          textPaint.setTextSize(30);
  
          pathA = new Path();
          pathB = new Path();
          pathC = new Path();
  
          style = STYLE_LOWER_RIGHT;
          mScroller = new Scroller(context,new LinearInterpolator());
          mMatrix = new Matrix();
  
          createGradientDrawable();
      }
  
      private void drawPathAContentBitmap(Bitmap bitmap,Paint pathPaint){
          Canvas mCanvas = new Canvas(bitmap);
          //下面开始绘制区域内的内容...
          mCanvas.drawPath(getPathDefault(),pathPaint);
          mCanvas.drawText("这是在A区域的内容...AAAA", viewWidth-260, viewHeight-100, textPaint);
  
          //结束绘制区域内的内容...
      }
  
      private void drawPathBContentBitmap(Bitmap bitmap,Paint pathPaint){
          Canvas mCanvas = new Canvas(bitmap);
          //下面开始绘制区域内的内容...
          mCanvas.drawPath(getPathDefault(),pathPaint);
          mCanvas.drawText("这是在B区域的内容...BBBB", viewWidth-260, viewHeight-100, textPaint);
  
          //结束绘制区域内的内容...
      }
  
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          int height = measureSize(defaultHeight, heightMeasureSpec);
          int width = measureSize(defaultWidth, widthMeasureSpec);
          setMeasuredDimension(width, height);
  
          viewWidth = width;
          viewHeight = height;
          a.x = -1;
          a.y = -1;
          pathAContentBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565);
          drawPathAContentBitmap(pathAContentBitmap,pathAPaint);
  
          pathBContentBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565);
          drawPathBContentBitmap(pathBContentBitmap,pathBPaint);
  
          pathCContentBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.RGB_565);
          drawPathAContentBitmap(pathCContentBitmap,pathCPaint);
      }
  
      private int measureSize(int defaultSize,int measureSpec) {
          int result = defaultSize;
          int specMode = View.MeasureSpec.getMode(measureSpec);
          int specSize = View.MeasureSpec.getSize(measureSpec);
  
          if (specMode == View.MeasureSpec.EXACTLY) {
              result = specSize;
          } else if (specMode == View.MeasureSpec.AT_MOST) {
              result = Math.min(result, specSize);
          }
          return result;
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
  
          canvas.drawColor(Color.YELLOW);
          if(a.x==-1 && a.y==-1){
              drawPathAContent(canvas,getPathDefault());
          }else {
              if(f.x==viewWidth && f.y==0){
                  drawPathAContent(canvas,getPathAFromTopRight());
  
                  drawPathCContent(canvas,getPathAFromTopRight());
                  drawPathBContent(canvas,getPathAFromTopRight());
              }else if(f.x==viewWidth && f.y==viewHeight){
  
                  beginTrace("drawPathA");
                  drawPathAContent(canvas,getPathAFromLowerRight());
                  endTrace();
  
                  beginTrace("drawPathC");
                  drawPathCContent(canvas,getPathAFromLowerRight());
                  endTrace();
  
                  beginTrace("drawPathB");
                  drawPathBContent(canvas,getPathAFromLowerRight());
                  endTrace();
              }
          }
  
          //绘制各标识点
          /*canvas.drawText("a",a.x,a.y,pointPaint);
          canvas.drawText("f",f.x,f.y,pointPaint);
          canvas.drawText("g",g.x,g.y,pointPaint);
  
          canvas.drawText("e",e.x,e.y,pointPaint);
          canvas.drawText("h",h.x,h.y,pointPaint);
  
          canvas.drawText("c",c.x,c.y,pointPaint);
          canvas.drawText("j",j.x,j.y,pointPaint);
  
          canvas.drawText("b",b.x,b.y,pointPaint);
          canvas.drawText("k",k.x,k.y,pointPaint);
  
          canvas.drawText("d",d.x,d.y,pointPaint);
          canvas.drawText("i",i.x,i.y,pointPaint);*/
      }
  
      @TargetApi(18)
      private void beginTrace(String tag){
          Trace.beginSection(tag);
      }
  
      @TargetApi(18)
      private void endTrace(){
          Trace.endSection();
      }
  
      @Override
      public void computeScroll() {
          if (mScroller.computeScrollOffset()) {
              float x = mScroller.getCurrX();
              float y = mScroller.getCurrY();
              if(style.equals(STYLE_TOP_RIGHT)){
                  setTouchPoint(x,y,STYLE_TOP_RIGHT);
              }else {
                  setTouchPoint(x,y,STYLE_LOWER_RIGHT);
              }
              if (mScroller.getFinalX() == x && mScroller.getFinalY() == y){
                  setDefaultPath();
              }
          }
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent event) {
          super.onTouchEvent(event);
          switch (event.getAction()){
              case MotionEvent.ACTION_DOWN:
                  float x = event.getX();
                  float y = event.getY();
                  if(x<=viewWidth/3){//左
                      style = STYLE_LEFT;
                      setTouchPoint(x,y,style);
  
                  }else if(x>viewWidth/3 && y<=viewHeight/3){//上
                      style = STYLE_TOP_RIGHT;
                      setTouchPoint(x,y,style);
  
                  }else if(x>viewWidth*2/3 && y>viewHeight/3 && y<=viewHeight*2/3){//右
                      style = STYLE_RIGHT;
                      setTouchPoint(x,y,style);
  
                  }else if(x>viewWidth/3 && y>viewHeight*2/3){//下
                      style = STYLE_LOWER_RIGHT;
                      setTouchPoint(x,y,style);
  
                  }else if(x>viewWidth/3 && x<viewWidth*2/3 && y>viewHeight/3 && y<viewHeight*2/3){//中
                      style = STYLE_MIDDLE;
                  }
                  break;
              case MotionEvent.ACTION_MOVE:
                  setTouchPoint(event.getX(),event.getY(),style);
                  break;
              case MotionEvent.ACTION_UP:
                  startCancelAnim();
                  break;
          }
          return true;
      }
  
      /**
       * 取消翻页动画,计算滑动位置与时间
       */
      public void startCancelAnim(){
          int dx,dy;
          //让a滑动到f点所在位置，留出1像素是为了防止当a和f重叠时出现View闪烁的情况
          if(style.equals(STYLE_TOP_RIGHT)){
              dx = (int) (viewWidth-1-a.x);
              dy = (int) (1-a.y);
          }else {
              dx = (int) (viewWidth-1-a.x);
              dy = (int) (viewHeight-1-a.y);
          }
          mScroller.startScroll((int) a.x, (int) a.y, dx, dy, 400);
      }
  
      /**
       * 设置触摸点
       * @param x
       * @param y
       * @param style
       */
      public void setTouchPoint(float x, float y, String style){
          MyPoint touchPoint = new MyPoint();
          a.x = x;
          a.y = y;
          this.style = style;
          switch (style){
              case STYLE_TOP_RIGHT:
                  f.x = viewWidth;
                  f.y = 0;
                  calcPointsXY(a,f);
                  touchPoint = new MyPoint(x,y);
                  if(calcPointCX(touchPoint,f)<0){//如果c点x坐标小于0则重新测量a点坐标
                      calcPointAByTouchPoint();
                      calcPointsXY(a,f);
                  }
                  postInvalidate();
                  break;
              case STYLE_LEFT:
              case STYLE_RIGHT:
                  a.y = viewHeight-1;
                  f.x = viewWidth;
                  f.y = viewHeight;
                  calcPointsXY(a,f);
                  postInvalidate();
                  break;
              case STYLE_LOWER_RIGHT:
                  f.x = viewWidth;
                  f.y = viewHeight;
                  calcPointsXY(a,f);
                  touchPoint = new MyPoint(x,y);
                  if(calcPointCX(touchPoint,f)<0){//如果c点x坐标小于0则重新测量a点坐标
                      calcPointAByTouchPoint();
                      calcPointsXY(a,f);
                  }
                  postInvalidate();
                  break;
              default:
                  break;
          }
      }
  
      /**
       * 如果c点x坐标小于0,根据触摸点重新测量a点坐标
       */
      private void calcPointAByTouchPoint(){
          float w0 = viewWidth - c.x;
  
          float w1 = Math.abs(f.x - a.x);
          float w2 = viewWidth * w1 / w0;
          a.x = Math.abs(f.x - w2);
  
          float h1 = Math.abs(f.y - a.y);
          float h2 = w2 * h1 / w1;
          a.y = Math.abs(f.y - h2);
      }
  
      /**
       * 回到默认状态
       */
      public void setDefaultPath(){
          a.x = -1;
          a.y = -1;
          postInvalidate();
      }
  
      /**
       * 初始化各区域阴影GradientDrawable
       */
      private void createGradientDrawable(){
          int deepColor = 0x33333333;
          int lightColor = 0x01333333;
          int[] gradientColors = new int[]{lightColor,deepColor};//渐变颜色数组
          drawableLeftTopRight = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors);
          drawableLeftTopRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
          drawableLeftLowerRight = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors);
          drawableLeftLowerRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
  
          deepColor = 0x22333333;
          lightColor = 0x01333333;
          gradientColors =  new int[]{deepColor,lightColor,lightColor};
          drawableRightTopRight = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, gradientColors);
          drawableRightTopRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
          drawableRightLowerRight = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, gradientColors);
          drawableRightLowerRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
  
          deepColor = 0x44333333;
          lightColor = 0x01333333;
          gradientColors = new int[]{lightColor,deepColor};//渐变颜色数组
          drawableHorizontalLowerRight = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors);;
          drawableHorizontalLowerRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
  
          deepColor = 0x55111111;
          lightColor = 0x00111111;
          gradientColors = new int[] {deepColor,lightColor};//渐变颜色数组
          drawableBTopRight =new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,gradientColors);
          drawableBTopRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);//线性渐变
          drawableBLowerRight =new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT,gradientColors);
          drawableBLowerRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
  
          deepColor = 0x55333333;
          lightColor = 0x00333333;
          gradientColors = new int[]{lightColor,deepColor};//渐变颜色数组
          drawableCTopRight = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, gradientColors);
          drawableCTopRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
          drawableCLowerRight = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, gradientColors);
          drawableCLowerRight.setGradientType(GradientDrawable.LINEAR_GRADIENT);
      }
  
      /**
       * 绘制A区域内容
       * @param canvas
       * @param pathA
       */
      private void drawPathAContent(Canvas canvas, Path pathA){
          canvas.save();
          canvas.clipPath(pathA, Region.Op.INTERSECT);//对绘制内容进行裁剪，取和A区域的交集
          canvas.drawBitmap(pathAContentBitmap, 0, 0, null);
  
          if(style.equals(STYLE_LEFT) || style.equals(STYLE_RIGHT)){
              drawPathAHorizontalShadow(canvas,pathA);
          }else {
              drawPathALeftShadow(canvas,pathA);
              drawPathARightShadow(canvas,pathA);
          }
          canvas.restore();
      }
  
      /**
       * 绘制A区域左阴影
       * @param canvas
       */
      private void drawPathALeftShadow(Canvas canvas, Path pathA){
          canvas.restore();
          canvas.save();
  
          int left;
          int right;
          int top = (int) e.y;
          int bottom = (int) (e.y+viewHeight);
  
          GradientDrawable gradientDrawable;
          if (style.equals(STYLE_TOP_RIGHT)) {
              gradientDrawable = drawableLeftTopRight;
              left = (int) (e.x - lPathAShadowDis /2);
              right = (int) (e.x);
          } else {
              gradientDrawable = drawableLeftLowerRight;
              left = (int) (e.x);
              right = (int) (e.x + lPathAShadowDis /2);
          }
  
          Path mPath = new Path();
          mPath.moveTo(a.x- Math.max(rPathAShadowDis, lPathAShadowDis) /2,a.y);
          mPath.lineTo(d.x,d.y);
          mPath.lineTo(e.x,e.y);
          mPath.lineTo(a.x,a.y);
          mPath.close();
          canvas.clipPath(pathA);
          canvas.clipPath(mPath, Region.Op.INTERSECT);
  
          float mDegrees = (float) Math.toDegrees(Math.atan2(e.x-a.x, a.y-e.y));
          canvas.rotate(mDegrees, e.x, e.y);
  
          gradientDrawable.setBounds(left,top,right,bottom);
          gradientDrawable.draw(canvas);
      }
  
      /**
       * 绘制A区域右阴影
       * @param canvas
       */
      private void drawPathARightShadow(Canvas canvas, Path pathA){
          canvas.restore();
          canvas.save();
  
          float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//view对角线长度
          int left = (int) h.x;
          int right = (int) (h.x + viewDiagonalLength*10);//需要足够长的长度
          int top;
          int bottom;
  
          GradientDrawable gradientDrawable;
          if (style.equals(STYLE_TOP_RIGHT)) {
              gradientDrawable = drawableRightTopRight;
              top = (int) (h.y- rPathAShadowDis /2);
              bottom = (int) h.y;
          } else {
              gradientDrawable = drawableRightLowerRight;
              top = (int) h.y;
              bottom = (int) (h.y+ rPathAShadowDis /2);
          }
          gradientDrawable.setBounds(left,top,right,bottom);
  
          Path mPath = new Path();
          mPath.moveTo(a.x- Math.max(rPathAShadowDis, lPathAShadowDis) /2,a.y);
  //        mPath.lineTo(i.x,i.y);
          mPath.lineTo(h.x,h.y);
          mPath.lineTo(a.x,a.y);
          mPath.close();
          canvas.clipPath(pathA);
          canvas.clipPath(mPath, Region.Op.INTERSECT);
  
          float mDegrees = (float) Math.toDegrees(Math.atan2(a.y-h.y, a.x-h.x));
          canvas.rotate(mDegrees, h.x, h.y);
          gradientDrawable.draw(canvas);
      }
  
      /**
       * 绘制A区域水平翻页阴影
       * @param canvas
       */
      private void drawPathAHorizontalShadow(Canvas canvas, Path pathA){
          canvas.restore();
          canvas.save();
          canvas.clipPath(pathA, Region.Op.INTERSECT);
  
          int maxShadowWidth = 30;//阴影矩形最大的宽度
          int left = (int) (a.x - Math.min(maxShadowWidth,(rPathAShadowDis/2)));
          int right = (int) (a.x);
          int top = 0;
          int bottom = viewHeight;
          GradientDrawable gradientDrawable = drawableHorizontalLowerRight;
          gradientDrawable.setBounds(left,top,right,bottom);
  
          float mDegrees = (float) Math.toDegrees(Math.atan2(f.x-a.x,f.y-h.y));
          canvas.rotate(mDegrees, a.x, a.y);
          gradientDrawable.draw(canvas);
      }
  
      /**
       * 绘制默认的界面
       * @return
       */
      private Path getPathDefault(){
          pathA.reset();
          pathA.lineTo(0, viewHeight);
          pathA.lineTo(viewWidth,viewHeight);
          pathA.lineTo(viewWidth,0);
          pathA.close();
          return pathA;
      }
  
      /**
       * 获取f点在右上角的pathA
       * @return
       */
      private Path getPathAFromTopRight(){
          pathA.reset();
          pathA.lineTo(c.x,c.y);//移动到c点
          pathA.quadTo(e.x,e.y,b.x,b.y);//从c到b画贝塞尔曲线，控制点为e
          pathA.lineTo(a.x,a.y);//移动到a点
          pathA.lineTo(k.x,k.y);//移动到k点
          pathA.quadTo(h.x,h.y,j.x,j.y);//从k到j画贝塞尔曲线，控制点为h
          pathA.lineTo(viewWidth,viewHeight);//移动到右下角
          pathA.lineTo(0, viewHeight);//移动到左下角
          pathA.close();
          return pathA;
      }
  
      /**
       * 获取f点在右下角的pathA
       * @return
       */
      private Path getPathAFromLowerRight(){
          pathA.reset();
          pathA.lineTo(0, viewHeight);//移动到左下角
          pathA.lineTo(c.x,c.y);//移动到c点
          pathA.quadTo(e.x,e.y,b.x,b.y);//从c到b画贝塞尔曲线，控制点为e
          pathA.lineTo(a.x,a.y);//移动到a点
          pathA.lineTo(k.x,k.y);//移动到k点
          pathA.quadTo(h.x,h.y,j.x,j.y);//从k到j画贝塞尔曲线，控制点为h
          pathA.lineTo(viewWidth,0);//移动到右上角
          pathA.close();//闭合区域
          return pathA;
      }
  
      /**
       * 绘制B区域内容
       * @param canvas
       * @param pathA
       */
      private void drawPathBContent(Canvas canvas, Path pathA){
          canvas.save();
          canvas.clipPath(pathA);//裁剪出A区域
          canvas.clipPath(getPathC(),Region.Op.UNION);//裁剪出A和C区域的全集
          canvas.clipPath(getPathB(), Region.Op.REVERSE_DIFFERENCE);//裁剪出B区域中不同于与AC区域的部分
          canvas.drawBitmap(pathBContentBitmap, 0, 0, null);
  
          drawPathBShadow(canvas);
          canvas.restore();
      }
  
      /**
       * 绘制B区域阴影，阴影左深右浅
       * @param canvas
       */
      private void drawPathBShadow(Canvas canvas){
          int deepOffset = 0;//深色端的偏移值
          int lightOffset = 0;//浅色端的偏移值
          float aTof =(float) Math.hypot((a.x - f.x),(a.y - f.y));//a到f的距离
          float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//对角线长度
  
          int left;
          int right;
          int top = (int) c.y;
          int bottom = (int) (viewDiagonalLength + c.y);
          GradientDrawable gradientDrawable;
          if(style.equals(STYLE_TOP_RIGHT)){//f点在右上角
              //从左向右线性渐变
              gradientDrawable = drawableBTopRight;
  
              left = (int) (c.x - deepOffset);//c点位于左上角
              right = (int) (c.x + aTof/4 + lightOffset);
          }else {
              //从右向左线性渐变
              gradientDrawable = drawableBLowerRight;
  
              left = (int) (c.x - aTof/4 - lightOffset);//c点位于左下角
              right = (int) (c.x + deepOffset);
          }
          gradientDrawable.setBounds(left,top,right,bottom);//设置阴影矩形
  
          float rotateDegrees = (float) Math.toDegrees(Math.atan2(e.x- f.x, h.y - f.y));//旋转角度
          canvas.rotate(rotateDegrees, c.x, c.y);//以c为中心点旋转
          gradientDrawable.draw(canvas);
      }
  
      /**
       * 绘制区域B
       * @return
       */
      private Path getPathB(){
          pathB.reset();
          pathB.lineTo(0, viewHeight);//移动到左下角
          pathB.lineTo(viewWidth,viewHeight);//移动到右下角
          pathB.lineTo(viewWidth,0);//移动到右上角
          pathB.close();//闭合区域
          return pathB;
      }
  
      /**
       * 绘制C区域内容
       * @param canvas
       * @param pathA
       */
      private void drawPathCContent(Canvas canvas, Path pathA){
          canvas.save();
          canvas.clipPath(pathA);
          canvas.clipPath(getPathC(), Region.Op.REVERSE_DIFFERENCE);//裁剪出C区域不同于A区域的部分
  //        canvas.drawPath(getPathC(),pathCPaint);
  
          float eh = (float) Math.hypot(f.x - e.x,h.y - f.y);
          float sin0 = (f.x - e.x) / eh;
          float cos0 = (h.y - f.y) / eh;
          //设置翻转和旋转矩阵
          mMatrixArray[0] = -(1-2 * sin0 * sin0);
          mMatrixArray[1] = 2 * sin0 * cos0;
          mMatrixArray[3] = 2 * sin0 * cos0;
          mMatrixArray[4] = 1 - 2 * sin0 * sin0;
  
          mMatrix.reset();
          mMatrix.setValues(mMatrixArray);//翻转和旋转
          mMatrix.preTranslate(-e.x, -e.y);//沿当前XY轴负方向位移得到 矩形A₃B₃C₃D₃
          mMatrix.postTranslate(e.x, e.y);//沿原XY轴方向位移得到 矩形A4 B4 C4 D4
          canvas.drawBitmap(pathCContentBitmap, mMatrix, null);
  
          drawPathCShadow(canvas);
          canvas.restore();
      }
  
      /**
       * 绘制C区域阴影，阴影左浅右深
       * @param canvas
       */
      private void drawPathCShadow(Canvas canvas){
          int deepOffset = 1;//深色端的偏移值
          int lightOffset = -30;//浅色端的偏移值
          float viewDiagonalLength = (float) Math.hypot(viewWidth, viewHeight);//view对角线长度
          int midpoint_ce = (int) (c.x + e.x) / 2;//ce中点
          int midpoint_jh = (int) (j.y + h.y) / 2;//jh中点
          float minDisToControlPoint = Math.min(Math.abs(midpoint_ce - e.x), Math.abs(midpoint_jh - h.y));//中点到控制点的最小值
  
          int left;
          int right;
          int top = (int) c.y;
          int bottom = (int) (viewDiagonalLength + c.y);
          GradientDrawable gradientDrawable;
          if (style.equals(STYLE_TOP_RIGHT)) {
              gradientDrawable = drawableCTopRight;
              left = (int) (c.x - lightOffset);
              right = (int) (c.x + minDisToControlPoint + deepOffset);
          } else {
              gradientDrawable = drawableCLowerRight;
              left = (int) (c.x - minDisToControlPoint - deepOffset);
              right = (int) (c.x + lightOffset);
          }
          gradientDrawable.setBounds(left,top,right,bottom);
  
          float mDegrees = (float) Math.toDegrees(Math.atan2(e.x- f.x, h.y - f.y));
          canvas.rotate(mDegrees, c.x, c.y);
          gradientDrawable.draw(canvas);
      }
  
      /**
       * 绘制区域C
       * @return
       */
      private Path getPathC(){
          pathC.reset();
          pathC.moveTo(i.x,i.y);//移动到i点
          pathC.lineTo(d.x,d.y);//移动到d点
          pathC.lineTo(b.x,b.y);//移动到b点
          pathC.lineTo(a.x,a.y);//移动到a点
          pathC.lineTo(k.x,k.y);//移动到k点
          pathC.close();//闭合区域
          return pathC;
      }
  
      /**
       * 计算各点坐标
       * @param a
       * @param f
       */
      private void calcPointsXY(MyPoint a, MyPoint f){
          g.x = (a.x + f.x) / 2;
          g.y = (a.y + f.y) / 2;
  
          e.x = g.x - (f.y - g.y) * (f.y - g.y) / (f.x - g.x);
          e.y = f.y;
  
          h.x = f.x;
          h.y = g.y - (f.x - g.x) * (f.x - g.x) / (f.y - g.y);
  
          c.x = e.x - (f.x - e.x) / 2;
          c.y = f.y;
  
          j.x = f.x;
          j.y = h.y - (f.y - h.y) / 2;
  
          b = getIntersectionPoint(a,e,c,j);
          k = getIntersectionPoint(a,h,c,j);
  
          d.x = (c.x + 2 * e.x + b.x) / 4;
          d.y = (2 * e.y + c.y + b.y) / 4;
  
          i.x = (j.x + 2 * h.x + k.x) / 4;
          i.y = (2 * h.y + j.y + k.y) / 4;
  
          //计算d点到ae的距离
          float lA = a.y-e.y;
          float lB = e.x-a.x;
          float lC = a.x*e.y-e.x*a.y;
          lPathAShadowDis = Math.abs((lA*d.x+lB*d.y+lC)/(float) Math.hypot(lA,lB));
  
          //计算i点到ah的距离
          float rA = a.y-h.y;
          float rB = h.x-a.x;
          float rC = a.x*h.y-h.x*a.y;
          rPathAShadowDis = Math.abs((rA*i.x+rB*i.y+rC)/(float) Math.hypot(rA,rB));
      }
  
      /**
       * 计算两线段相交点坐标
       * @param lineOne_My_pointOne
       * @param lineOne_My_pointTwo
       * @param lineTwo_My_pointOne
       * @param lineTwo_My_pointTwo
       * @return 返回该点
       */
      private MyPoint getIntersectionPoint(MyPoint lineOne_My_pointOne, MyPoint lineOne_My_pointTwo, MyPoint lineTwo_My_pointOne, MyPoint lineTwo_My_pointTwo){
          float x1,y1,x2,y2,x3,y3,x4,y4;
          x1 = lineOne_My_pointOne.x;
          y1 = lineOne_My_pointOne.y;
          x2 = lineOne_My_pointTwo.x;
          y2 = lineOne_My_pointTwo.y;
          x3 = lineTwo_My_pointOne.x;
          y3 = lineTwo_My_pointOne.y;
          x4 = lineTwo_My_pointTwo.x;
          y4 = lineTwo_My_pointTwo.y;
  
          float pointX =((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1))
                  / ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
          float pointY =((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4))
                  / ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
  
          return  new MyPoint(pointX,pointY);
      }
  
      /**
       * 计算C点的X值
       * @param a
       * @param f
       * @return
       */
      private float calcPointCX(MyPoint a, MyPoint f){
          MyPoint g,e;
          g = new MyPoint();
          e = new MyPoint();
          g.x = (a.x + f.x) / 2;
          g.y = (a.y + f.y) / 2;
  
          e.x = g.x - (f.y - g.y) * (f.y - g.y) / (f.x - g.x);
          e.y = f.y;
  
          return e.x - (f.x - e.x) / 2;
      }
  
      public float getViewWidth(){
          return viewWidth;
      }
  
      public float getViewHeight(){
          return viewHeight;
      }
  }
  