Example #1
0
  void render(LineLabel label) {
    tx.reset(canvas);

    String txt = label.getText();

    Paint p = label.get(Paint.class, Paint.class);

    List<LineSegment> path = label.getPath();
    for (int i = 0; i < txt.length(); i++) {
      LineSegment line = path.get(i);

      PointF p0 = tx.getWorldToCanvas().map(line.p0);
      PointF p1 = tx.getWorldToCanvas().map(line.p1);

      double theta = Math.atan((p1.y - p0.y) / (p1.x - p0.x));

      Matrix m = canvas.getMatrix();
      Matrix n = new Matrix(canvas.getMatrix());
      n.preRotate((float) Math.toDegrees(theta), p0.x, p0.y);

      // Paint debug = new Paint();
      // debug.setColor(Color.RED);
      // canvas.drawLine(p0.x, p0.y, p1.x, p1.y, debug);

      canvas.setMatrix(n);
      canvas.drawText(txt, i, i + 1, p0.x, p0.y, p);
      canvas.setMatrix(m);
    }

    tx.apply(canvas);
    // canvas.drawTextOnPath(l.text, l.getPath(), 0, 0, l.get(Paint.class,Paint.class));
  }
Example #2
0
  /**
   * 绘制,实现自sceneInterface
   *
   * @param canvas 画布
   */
  public void onDraw(Canvas canvas, Paint paint) {
    if (paint == null) {
      paint = DEFAULT_PAINT;
    }
    final Iterator<AbstractSprite> it = dynLevel.getSpriteList().iterator();
    while (it.hasNext()) {
      final AbstractSprite obj = it.next();
      if (obj instanceof Moveable) {
        ((Moveable) obj).autoMove();
      }
      if (obj instanceof StaCollidable) {
        ((StaCollidable) obj).handleStaCollision();
      }
    }
    checkCollision();
    if (mel != null) {
      MapEvent met = map.checkEvent((Rect) hero.getRect());
      if (met != null) {
        mel.mapEventOccured(met);
      }
    }
    if (hero != null) {

      offsetX = hero.getX() - SystemData.getActivityWidth() / 2;
      offsetY = hero.getY() - SystemData.getActivityHeight() / 2;
    }

    if (offsetX < 0) offsetX = 0;
    if (offsetY < 0) offsetY = 0;

    if (offsetX + SystemData.getActivityWidth() > map.getWidth()) {
      offsetX = map.getWidth() - SystemData.getActivityWidth();
    }
    if (offsetY + SystemData.getActivityHeight() > map.getHeight()) {
      offsetY = map.getHeight() - SystemData.getActivityHeight();
    }

    Matrix m = new Matrix();
    m.setTranslate(-offsetX, -offsetY);
    canvas.setMatrix(m);

    // map.setOffsetXY(offsetX, offsetY);
    // dynLevel.setOffsetXY(offsetX, offsetY);

    if (map != null) {
      map.drawDown(canvas, paint);
    }
    if (dynLevel != null) {
      dynLevel.onDraw(canvas, paint);
    }
    if (map != null) {
      map.drawUp(canvas, paint);
    }

    canvas.setMatrix(new Matrix());
  }
Example #3
0
  @Override
  protected void dispatchDraw(Canvas canvas) {
    if (showcaseX < 0 || showcaseY < 0 || isRedundant) {
      super.dispatchDraw(canvas);
      return;
    }

    // Draw the semi-transparent background
    canvas.drawColor(backColor);

    // Draw to the scale specified
    Matrix mm = new Matrix();
    mm.postScale(scaleMultiplier, scaleMultiplier, showcaseX, showcaseY);
    canvas.setMatrix(mm);

    // Erase the area for the ring
    canvas.drawCircle(showcaseX, showcaseY, showcaseRadius, mEraser);

    boolean recalculateText = makeVoidedRect() || mAlteredText;
    mAlteredText = false;

    showcase.setBounds(voidedArea);
    showcase.draw(canvas);

    canvas.setMatrix(new Matrix());

    if (!TextUtils.isEmpty(mTitleText) || !TextUtils.isEmpty(mSubText)) {
      if (recalculateText)
        mBestTextPosition = getBestTextPosition(canvas.getWidth(), canvas.getHeight());

      if (!TextUtils.isEmpty(mTitleText)) {
        // TODO: use a dynamic detail layout
        canvas.drawText(mTitleText, mBestTextPosition[0], mBestTextPosition[1], mPaintTitle);
      }

      if (!TextUtils.isEmpty(mSubText)) {
        canvas.save();
        if (recalculateText)
          mDynamicDetailLayout =
              new DynamicLayout(
                  mSubText,
                  mPaintDetail,
                  ((Number) mBestTextPosition[2]).intValue(),
                  Layout.Alignment.ALIGN_NORMAL,
                  1.2f,
                  1.0f,
                  true);
        canvas.translate(mBestTextPosition[0], mBestTextPosition[1] + 12 * metricScale);
        mDynamicDetailLayout.draw(canvas);
        canvas.restore();
      }
    }

    super.dispatchDraw(canvas);
  }
  @Override
  public void drawShowcase(Canvas canvas, float x, float y, float scaleMultiplier, float radius) {
    Matrix mm = new Matrix();
    mm.postScale(scaleMultiplier, scaleMultiplier, x, y);
    canvas.setMatrix(mm);

    canvas.drawCircle(x, y, radius, mEraser);

    mShowcaseDrawable.setBounds(mShowcaseRect);
    mShowcaseDrawable.draw(canvas);

    canvas.setMatrix(new Matrix());
  }
Example #5
0
 public void draw(Canvas canvas, CanvasPaints paints) {
   // Assume canvas has identity matrix on its matrix stack.
   canvas.setMatrix(this.getCascade());
   style.setPaints(paints);
   canvas.drawPath(path.path, paints.stroke());
   paints.reset();
 }
Example #6
0
    public byte[] getTileImageData(int x, int y, int zoom) {
      mStream.reset();

      Matrix matrix = new Matrix(mBaseMatrix);
      float scale = (float) (Math.pow(2, zoom) * mScale);
      matrix.postScale(scale, scale);
      matrix.postTranslate(-x * mDimension, -y * mDimension);

      mBitmap.eraseColor(Color.TRANSPARENT);
      Canvas c = new Canvas(mBitmap);
      c.setMatrix(matrix);

      // NOTE: Picture is not thread-safe.
      synchronized (mSvgPicture) {
        mSvgPicture.draw(c);
      }

      BufferedOutputStream stream = new BufferedOutputStream(mStream);
      mBitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);
      try {
        stream.close();
      } catch (IOException e) {
        Log.e(TAG, "Error while closing tile byte stream.");
        e.printStackTrace();
      }
      return mStream.toByteArray();
    }
  // ==============================================================================
  public final int[] renderGlyph(
      char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds) {
    Path p = new Path();
    paint.getTextPath(String.valueOf(glyph), 0, 1, 0.0f, 0.0f, p);

    RectF boundsF = new RectF();
    p.computeBounds(boundsF, true);
    matrix.mapRect(boundsF);

    boundsF.roundOut(bounds);
    bounds.left--;
    bounds.right++;

    final int w = bounds.width();
    final int h = bounds.height();

    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

    Canvas c = new Canvas(bm);
    matrix.postTranslate(-bounds.left, -bounds.top);
    c.setMatrix(matrix);
    c.drawPath(p, paint);

    final int sizeNeeded = w * h;
    if (cachedRenderArray.length < sizeNeeded) cachedRenderArray = new int[sizeNeeded];

    bm.getPixels(cachedRenderArray, 0, w, 0, 0, w, h);
    bm.recycle();
    return cachedRenderArray;
  }
 private void getScreenBitmap() {
   mView.getRootView().destroyDrawingCache();
   mView.getGlobalVisibleRect(mRect, point);
   realheight = mView.getHeight();
   realwidth = mView.getWidth();
   dst.set(0, 0, realwidth, realheight);
   int w = Math.round(realwidth * BITMAP_RATIO);
   int h = Math.round(realheight * BITMAP_RATIO);
   w = w & ~0x03;
   h = h & ~0x03;
   if (w <= 0 || h <= 0) return;
   if (bitmap == null || bitmap.getWidth() != w || bitmap.getHeight() != h) {
     bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
     mMatrix.setScale(BITMAP_RATIO, BITMAP_RATIO);
     mMatrix.invert(mDrawMatrix);
     src.set(0, 0, w, h);
   }
   float dx = -(Math.min(0, mView.getLeft()) + mRect.left);
   float dy = (-point.y);
   mCanvas.restoreToCount(1);
   mCanvas.setBitmap(bitmap);
   mCanvas.setMatrix(mMatrix);
   mCanvas.translate(dx, dy);
   mCanvas.save();
   mView.getRootView().draw(mCanvas);
 }
 @Override
 protected void dispatchDraw(Canvas canvas) {
   canvas.save();
   Matrix newMatrix = MatrixUtils.removeScale(matrix);
   canvas.setMatrix(newMatrix);
   super.dispatchDraw(canvas);
   canvas.restore();
 }
  @Override
  public void onDraw(Canvas canvas) {
    // zooming animation
    if (scalingInterpolator.isActive()) {
      setCurrentScaling(scalingInterpolator.getCurrentValue());
    }

    // translation animation
    if (translationXInterpolator.isActive() || translationYInterpolator.isActive()) {
      float transX = currentTranslation[0];
      float transY = currentTranslation[1];
      if (translationXInterpolator.isActive()) {
        transX = translationXInterpolator.getCurrentValue();
      }
      if (translationYInterpolator.isActive()) {
        transY = translationYInterpolator.getCurrentValue();
      }
      setCurrentTranslation(transX, transY);
    }

    // center rotation animation
    if (centerRotationInterpolator.isActive()) {
      setCurrentCenterRotation(centerRotationInterpolator.getCurrentValue());
    }

    // calculate current viewport matrix if necessary
    if (getAndClearViewportFlag()) {
      recalculateViewportTransformation();
      recalculateSizeScale();
    }

    // clear background
    canvas.drawColor(0xFF000000);

    // draw audio scene
    canvas.setMatrix(viewportTransformation);
    synchronized (GlobalData.audioScene) {
      GlobalData.audioScene.draw(canvas, currentInverseScaling);
    }

    // reset matrix
    canvas.setMatrix(null);

    // draw size scale
    sizeScalePicture.draw(canvas);
  }
  protected void drawCompass(final Canvas canvas, final float bearing) {
    final float centerX = mCompassCenterX * mScale;
    final float centerY = mCompassCenterY * mScale + (canvas.getHeight() - mMapView.getHeight());

    mCompassMatrix.setTranslate(-COMPASS_FRAME_CENTER_X, -COMPASS_FRAME_CENTER_Y);
    mCompassMatrix.postTranslate(centerX, centerY);

    canvas.save();
    canvas.setMatrix(mCompassMatrix);
    canvas.drawPicture(mCompassFrame);

    mCompassMatrix.setRotate(-bearing, COMPASS_ROSE_CENTER_X, COMPASS_ROSE_CENTER_Y);
    mCompassMatrix.postTranslate(-COMPASS_ROSE_CENTER_X, -COMPASS_ROSE_CENTER_Y);
    mCompassMatrix.postTranslate(centerX, centerY);

    canvas.setMatrix(mCompassMatrix);
    canvas.drawPicture(mCompassRose);
    canvas.restore();
  }
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    viewMatrix = canvas.getMatrix();

    canvas.concat(mapRelView);
    for (PanZoomDisplay display : displays) {
      if (display.isEnabled()) {
        display.draw(canvas);
      }
    }

    canvas.setMatrix(viewMatrix);
  }
  /** Private method for grabbing a "screenshot" of screen content */
  private void drawOffscreenBitmap() {
    // Grab global visible rect for later use
    // mView.getGlobalVisibleRect(mRectVisibleGlobal);

    // Calculate scaled off-screen bitmap width and height
    int width = Math.round(mView.getWidth() * BITMAP_SCALE_FACTOR);
    int height = Math.round(mView.getHeight() * BITMAP_SCALE_FACTOR);

    // Width and height must be > 0
    width = Math.max(width, 1);
    height = Math.max(height, 1);

    // Allocate new off-screen bitmap only when needed
    if (mBitmap == null || mBitmap.getWidth() != width || mBitmap.getHeight() != height) {
      mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
      mAllocationBitmap = Allocation.createFromBitmap(mRS, mBitmap);
      mAllocationBitmapTmp = Allocation.createFromBitmap(mRS, mBitmap);
      mSizeStruct.width = width;
      mSizeStruct.height = height;
      // Due to adjusting width into multiple of 4 calculate scale matrix
      // only here
      mMatrixScale.setScale((float) width / mView.getWidth(), (float) height / mView.getHeight());
      mMatrixScale.invert(mMatrixScaleInv);
    }

    // Translate values for off-screen drawing
    // int dx = -(Math.min(0, mView.getLeft()) + mRectVisibleGlobal.left);
    // int dy = -(Math.min(0, mView.getTop()) + mRectVisibleGlobal.top);
    //
    // Replaced dx and dy with View.getLocationInWindow() coordinates
    // because translate was bad for using BlurLinearLayout and
    // BlurRelativeLayout as children for other Views than root View.
    mView.getLocationInWindow(mLocationInWindow);
    // Restore canvas to its original state
    mCanvas.restoreToCount(1);
    mCanvas.setBitmap(mBitmap);
    // Using scale matrix will make draw call to match
    // resized off-screen bitmap size
    mCanvas.setMatrix(mMatrixScale);
    // Off-screen bitmap does not cover the whole screen
    // Use canvas translate to match its position on screen
    mCanvas.translate(-mLocationInWindow[0], -mLocationInWindow[1]);
    // Clip rect is the same as we have
    // TODO: Why does this not work on API 18?
    // mCanvas.clipRect(mRectVisibleGlobal);
    // Save current canvas state
    mCanvas.save();
    // Start drawing from the root view
    mView.getRootView().draw(mCanvas);
  }
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (bmp != null) {
      //				paint.setColor(Color.BLUE);
      clip = canvas.getClipBounds();
      float w = clip.width(), w2 = w / 2.0f, h = clip.height(), h2 = h / 2.0f;
      //				canvas.drawRect(0,0,w-1,h-1, paint);
      //				canvas.drawCircle(w2, h2, 10, paint);

      matrixLock.lock();
      Matrix m = new Matrix();
      m.reset();
      m.postTranslate(0, 80);
      m.postConcat(matrix);
      canvas.setMatrix(m);
      matrixLock.unlock();

      clip = canvas.getClipBounds();
      w = clip.width();
      w2 = w / 2.0f;
      h = clip.height();
      h2 = h / 2.0f;
      //				paint.setColor(Color.GREEN);
      //				canvas.drawRect(0,0,w-1,h-1, paint);

      bmpLock.lock();
      float left = scale * (w2 - (float) bmp.getWidth() / 2.0f);
      float top = scale * (h2 - (float) bmp.getHeight() / 2.0f);

      Bitmap _bmp = bmp;
      // check if rotated, and set the matrix accordingly
      if (!mLookingRight) {
        Matrix _m = new Matrix();
        _m.preScale(-1.0f, 1.0f);
        _bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), _m, false);
      }

      canvas.drawBitmap(_bmp, left, top, paint);
      //				paint.setColor(Color.RED);
      //				canvas.drawRect(left, top, left + bmp.getWidth(), top + bmp.getHeight(), paint);
      bmpLock.unlock();
    }
  }
    @Override
    public void run() {
      while (fRun) {
        try {
          fInstance.fDrawLock.lock();
          if (fRun) {
            while (!fInstance.fDrawFlag && !fInstance.fZoomFlag) {
              fInstance.fDrawCondition.await();
            }
            if (fInstance.fZoomFlag) {
              fInstance.fZoomManager.setViewMatrix(fInstance.fViewMatrix);
              fInstance.fZoomManager.hadZoomed();
            }
            Canvas canvas = fInstance.fHolder.lockCanvas(fInstance.fHolder.getSurfaceFrame());

            if (canvas != null) {
              fInstance.fCorners[0] = 0;
              fInstance.fCorners[1] = 0;
              fInstance.fCorners[2] = fInstance.fWidth;
              fInstance.fCorners[3] = fInstance.fHeight;
              fInstance.fViewMatrix.mapPoints(fInstance.fCorners);
              canvas.drawColor(Color.GRAY);
              canvas.clipRect(
                  fInstance.fCorners[2],
                  fInstance.fCorners[3],
                  fInstance.fCorners[0],
                  fInstance.fCorners[1]);
              canvas.save();
              canvas.setMatrix(fInstance.fViewMatrix);
              fInstance.fCanvasManager.draw(canvas);
              fInstance.fDrawListener.hadRedraw();
              canvas.restore();
              fInstance.paintOver(canvas);
              fInstance.fHolder.unlockCanvasAndPost(canvas);
            }
          }
        } catch (InterruptedException e) {

        } finally {
          fInstance.fDrawLock.unlock();
        }
      }
      fInstance = null;
    }
Example #16
0
  void canfirt(int i, Canvas canvas) {
    Bitmap canvasbitmap = Bitmap.createBitmap(getWidth(), rectheight, Config.ARGB_4444);
    Canvas sCanvas = new Canvas(canvasbitmap);
    float y0 = floats.get(i);
    y0 = disy + y0;
    if (y0 >= -rectheight / 2 && y0 <= rectheight / 2) {
      // y0 = y0 ;
    } else if (y0 < -rectheight / 2) {
      y0 = rectheight / 2;
      index++;
      index = index % (list.size());
    } else {
      index--;
      if (index < 0) {
        index = list.size() - 1;
      }

      y0 = -rectheight / 2;
    }
    floats.set(i, y0);

    matrix = new Matrix();

    int e = (index + 1) % list.size();
    y0 = (float) (rectheight + y0);

    sCanvas.drawText(list.get(e), getWidth() - getPaddingRight(), y0 + baseline, paint_LTGRAY);
    y0 = (float) (y0 - rectheight);
    float scroe = y0 / rectheight / 2;
    matrix.postScale(1f, scroe + 0.6f, getWidth() - getPaddingRight(), y0 + +baseline);
    matrix.postSkew(0f, 0.2f, getWidth() - getPaddingRight(), (y0 + +baseline));
    if (y0 != rectheight / 2) {
      sCanvas.setMatrix(matrix);
    }
    e = (index) % list.size();
    sCanvas.drawText(
        list.get(e), getWidth() - getPaddingRight(), (int) (y0 + baseline), paint_LTGRAY);

    canvas.drawBitmap(
        canvasbitmap, getWidth() / 2 - canvasbitmap.getWidth() / 2, (int) rectheight * i + 1, null);
  }
Example #17
0
  void canend(int i, Canvas canvas) {
    Bitmap canvasbitmap = Bitmap.createBitmap(getWidth(), rectheight, Config.ARGB_4444);
    Canvas sCanvas = new Canvas(canvasbitmap);

    // sCanvas.drawColor(Color.LTGRAY);
    float y0 = floats.get(i);
    y0 = disy + y0;

    if (y0 >= -rectheight / 2 && y0 <= rectheight / 2) {
      // y0 = y0 ;
    } else if (y0 < -rectheight / 2) {
      y0 = rectheight / 2 + 1;
    } else {
      y0 = -rectheight / 2;
    }
    floats.set(i, y0);
    int e = (index + 2) % list.size();
    matrix = new Matrix();
    // matrix.postSkew(0.0f, 0.2f, getWidth() - getPaddingRight(),
    // (y0 + +baseline / 2));
    sCanvas.drawText(
        list.get(e), getWidth() - getPaddingRight(), (int) (y0 + +baseline), paint_LTGRAY);

    y0 = (float) (rectheight + y0);

    e = (index + 3) % list.size();
    float scroe = 1 - y0 / rectheight;
    matrix.setScale(1f, scroe + 0.6f, getWidth() - getPaddingRight(), y0 + +baseline / 2);
    matrix.postSkew(0.1f, 0f, getWidth() - getPaddingRight(), (y0 + +baseline));
    if (y0 != rectheight / 2) {
      sCanvas.setMatrix(matrix);
    }

    sCanvas.drawText(list.get(e), getWidth() - getPaddingRight(), y0 + baseline, paint_LTGRAY);

    canvas.drawBitmap(
        canvasbitmap, getWidth() / 2 - canvasbitmap.getWidth() / 2, (int) rectheight * i + 1, null);
  }
Example #18
0
    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);

      if (Build.VERSION.SDK_INT < 11) {
        mTransform.set(canvas.getMatrix());
        mTransform.preRotate(mRotation, mPivot.x, mPivot.y);
        canvas.setMatrix(mTransform);
      }

      for (Item it : mData) {
        mPiePaint.setShader(it.mItemShader);
        cSlicePaint.setShader(it.cSliceShader);
        //                Log.d(TAG, "mBounds: " +mBounds);
        canvas.drawArc(mBounds, 360 - it.mEndAngle, it.mEndAngle - it.mStartAngle, true, mPiePaint);
        Log.d(TAG, "Item Being Built: " + it.mLabel);
        Log.d(TAG, "RectF: " + it.cSliceBounds);
        Log.d(TAG, "StartAngle> " + it.mStartAngle + " EndAngle> " + it.mEndAngle);
        canvas.drawArc(
            it.cSliceBounds, 360 - it.mEndAngle, it.mEndAngle - it.mStartAngle, true, cSlicePaint);
        //                Log.d(TAG, "StartAngle> "+it.mStartAngle+" EndAngle> "+it.mEndAngle);
      }
    }
Example #19
0
  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);

    if (mSelectedView != null) {
      getGlobalVisibleRect(mSelectedRect);

      int offsetTop = mSelectedRect.top;
      int offsetLeft = mSelectedRect.left;

      mSelectedView.getGlobalVisibleRect(mSelectedRect);

      if (offsetTop > 0 || offsetLeft > 0) {
        int saveCount = canvas.save();
        Matrix matrix = canvas.getMatrix();
        matrix.postTranslate(offsetLeft, offsetTop);
        canvas.setMatrix(matrix);
        canvas.drawRect(mSelectedRect, mPaint);
        canvas.restoreToCount(saveCount);
      } else {
        canvas.drawRect(mSelectedRect, mPaint);
      }
    }
  }
Example #20
0
 // JBG:  I found this method of overwriting the Matrix to have problems
 // on a Galaxy S3 (but worked fine on an older device) - the metrics were off, and strange things
 // were happening to the
 // clip bounds.  So don't use this, use canvas.save/restore while setting the scale/translate and
 // drawing
 // in between.  The Android docs don't recommend messing with the Matrix directly, and have
 // deprecated the getMatrix api
 protected void prepareCanvasZoom(Canvas canvasToPrepare) {
   Matrix zoomMatrix = getCanvasCamera().getTransformMatrix();
   canvasToPrepare.setMatrix(zoomMatrix);
 }
Example #21
0
    public void drawRB(Canvas canvas) {
      double dx = scrollX, dy = contentHeight - scrollY;
      double len = Math.sqrt(dx * dx + dy * dy);
      if (len > contentWidth) {
        scrollX = (float) (contentWidth * dx / len);
        scrollY = (float) (contentHeight - contentWidth * dy / len);
      }

      double px = contentWidth - scrollX;
      double py = contentHeight - scrollY;
      double arc = 2 * Math.atan(py / px) * 180 / Math.PI;

      // 三角
      ps.reset();
      ps.setColor(Color.WHITE);
      ps.setAntiAlias(true);
      canvas.save();
      m.reset();
      m.postTranslate(scrollX, scrollY - contentHeight);
      m.postRotate((float) (arc), scrollX, scrollY);
      canvas.setMatrix(m);
      canvas.drawRect(0, 0, contentWidth, contentHeight, ps);
      canvas.restore();

      // 下一页
      arc = arc * Math.PI / 360;
      angelPath.reset();
      double r = Math.sqrt(px * px + py * py);
      double p1 = contentWidth - r / (2 * Math.cos(arc));
      double p2 = r / (2 * Math.sin(arc));
      if (arc == 0) {
        angelPath.moveTo(contentWidth, 0);
        angelPath.lineTo((float) p1, 0);
        angelPath.lineTo((float) p1, contentHeight);
        angelPath.lineTo(contentWidth, contentHeight);
        angelPath.close();
      } else if (p2 > contentHeight || p2 < 0) {
        double p3 = contentWidth - (p2 - contentHeight) * Math.tan(arc);
        angelPath.moveTo(contentWidth, 0);
        angelPath.lineTo((float) p3, 0);
        angelPath.lineTo((float) p1, contentHeight);
        angelPath.lineTo(contentWidth, contentHeight);
        angelPath.close();
      } else {
        angelPath.moveTo(contentWidth, contentHeight);
        angelPath.lineTo(contentWidth, contentHeight - (float) p2);
        angelPath.lineTo((float) p1, contentHeight);
        angelPath.close();
      }
      canvas.save();
      // canvas.
      canvas.clipPath(angelPath);
      canvas.setDrawFilter(
          new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
      nextPage.draw(canvas);
      canvas.restore();

      ps.reset();
      Shader lg2 =
          new LinearGradient(
              scrollX,
              scrollY,
              contentWidth,
              contentHeight,
              new int[] {0x00000000, 0x33000000, 0x00000000},
              new float[] {0.35f, 0.5f, 0.65f},
              Shader.TileMode.CLAMP);
      ps.setShader(lg2);
      canvas.drawRect(0, 0, contentWidth, contentHeight, ps);
    }
  @Override
  protected void dispatchDraw(Canvas canvas) {
    if (showcaseX < 0 || showcaseY < 0 || isRedundant) {
      super.dispatchDraw(canvas);
      return;
    }

    Bitmap b =
        Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);

    // Draw the semi-transparent background
    c.drawColor(backColor);

    // Draw to the scale specified
    Matrix mm = new Matrix();
    mm.postScale(scaleMultiplier, scaleMultiplier, showcaseX, showcaseY);
    c.setMatrix(mm);

    // Erase the area for the ring
    c.drawCircle(showcaseX, showcaseY, showcaseRadius, mEraser);

    boolean recalculateText = makeVoidedRect() || mAlteredText;
    mAlteredText = false;

    showcase.setBounds(voidedArea);
    showcase.draw(c);

    canvas.drawBitmap(b, 0, 0, null);

    // Clean up, as we no longer require these items.
    try {
      c.setBitmap(null);
    } catch (NullPointerException npe) {
      // TODO why does this NPE happen?
      npe.printStackTrace();
    }
    b.recycle();
    b = null;

    if (!TextUtils.isEmpty(mTitleText) || !TextUtils.isEmpty(mSubText)) {
      if (recalculateText) {
        mBestTextPosition = getBestTextPosition(canvas.getWidth(), canvas.getHeight());
      }

      if (!TextUtils.isEmpty(mTitleText)) {
        // TODO: use a dynamic detail layout
        canvas.save();
        float width = mPaintTitle.measureText(mTitleText);
        canvas.rotate(
            mOrientation,
            mBestTextPosition[0] + width / 2.0f,
            mBestTextPosition[1] + mPaintTitle.getTextSize() / 2.0f);
        canvas.drawText(mTitleText, mBestTextPosition[0], mBestTextPosition[1], mPaintTitle);
        canvas.restore();
      }

      if (!TextUtils.isEmpty(mSubText)) {
        canvas.save();
        if (recalculateText)
          mDynamicDetailLayout =
              new DynamicLayout(
                  mSubText,
                  mPaintDetail,
                  ((Number) mBestTextPosition[2]).intValue(),
                  Layout.Alignment.ALIGN_NORMAL,
                  1.2f,
                  1.0f,
                  true);

        if (mOrientation % 180 == 0) {
          canvas.translate(mBestTextPosition[0], mBestTextPosition[1]);
        } else {
          canvas.rotate(
              mOrientation,
              mDynamicDetailLayout.getWidth() / 2,
              mDynamicDetailLayout.getHeight() / 2);
        }

        mDynamicDetailLayout.draw(canvas);
        canvas.restore();
      }
    }

    super.dispatchDraw(canvas);
  }
  @Override
  public void Render(Canvas canvas) {

    Paint paint;
    paint = new Paint();
    paint.setColor(Color.WHITE);
    canvas.drawColor(0, PorterDuff.Mode.CLEAR);
    canvas.save();
    canvas.setMatrix(matrix);
    canvas.translate(m_diffX, m_diffY);
    // 타일 한번 깔아준다.
    GraphicManager.getInstance().background.Draw(canvas, -750, -450);
    for (int i = 0; i < 50; i++) {
      for (int j = 0; j < 50; j++) {
        switch (UnitValue.m_dmap[i][j]) {
          case UnitValue.M_GRASS1:
            GraphicManager.getInstance()
                .temptile1
                .Draw(canvas, 750 + 50 / 2 * (j - i), -300 + 25 / 2 * (j + i));
            break;
          case UnitValue.M_GRASS2:
            GraphicManager.getInstance()
                .temptile2
                .Draw(canvas, 750 + 50 / 2 * (j - i), -300 + 25 / 2 * (j + i));
            break;
          case UnitValue.M_EMPTY:
            GraphicManager.getInstance()
                .temptitle3
                .Draw(canvas, 750 + 50 / 2 * (j - i), -300 + 25 / 2 * (j + i));
            break;
          case UnitValue.M_NOTMOVE:
            GraphicManager.getInstance()
                .temptile5
                .Draw(canvas, 750 + 50 / 2 * (j - i), -300 + 25 / 2 * (j + i));
            break;
        }
      }
    }
    // 나무가 타일에 겹쳐지지 않게 그려주기 위해 한번더 연산해 주었다.
    for (int i = 0; i < 50; i++) {
      for (int j = 0; j < 50; j++) {
        if (UnitValue.m_dmap[i][j] == 4) {
          GraphicManager.getInstance()
              .temptile2
              .Draw(canvas, 750 + 50 / 2 * (j - i), -300 + 25 / 2 * (j + i));
          GraphicManager.getInstance()
              .temptitle4
              .Draw(canvas, 750 + 50 / 2 * (j - i), -300 + 25 / 2 * (j + i) - 25);
        }
      }
    }

    Units.RenderUnit(canvas);
    canvas.restore();
    GraphicManager.getInstance()
        .ButtonView_Image
        .Draw(canvas, 0, (int) m_Height - (int) m_Height / 6);
    for (int i = 0; i < UI.Button.size(); i++) {
      UI.Button.get(i).Draw(canvas);
      canvas.drawText(
          "" + i, (int) (UI.Button.get(i).GetX()), (int) (UI.Button.get(i).GetY()), paint);
    }

    canvas.drawRect(m_Width / 20 * 18, 0, m_Width, m_Height / 20, paint);
  }