/** * Grow by. * * @param dx the dx * @param dy the dy */ void growBy(float dx, float dy) { if (mMaintainAspectRatio) { if (dx != 0) { dy = dx / mInitialAspectRatio; } else if (dy != 0) { dx = dy * mInitialAspectRatio; } } // Don't let the cropping rectangle grow too fast. // Grow at most half of the difference between the image rectangle and // the cropping rectangle. RectF r = new RectF(mCropRect); if (dx > 0F && r.width() + 2 * dx > mImageRect.width()) { float adjustment = (mImageRect.width() - r.width()) / 2F; dx = adjustment; if (mMaintainAspectRatio) { dy = dx / mInitialAspectRatio; } } if (dy > 0F && r.height() + 2 * dy > mImageRect.height()) { float adjustment = (mImageRect.height() - r.height()) / 2F; dy = adjustment; if (mMaintainAspectRatio) { dx = dy * mInitialAspectRatio; } } r.inset(-dx, -dy); // Don't let the cropping rectangle shrink too fast. final float widthCap = 25F; if (r.width() < widthCap) { return; // r.inset(-(widthCap - r.width()) / 2F, 0F); } float heightCap = mMaintainAspectRatio ? (widthCap / mInitialAspectRatio) : widthCap; if (r.height() < heightCap) { return; // r.inset(0F, -(heightCap - r.height()) / 2F); } // Put the cropping rectangle inside the image rectangle. if (r.left < mImageRect.left) { r.offset(mImageRect.left - r.left, 0F); } else if (r.right > mImageRect.right) { r.offset(-(r.right - mImageRect.right), 0); } if (r.top < mImageRect.top) { r.offset(0F, mImageRect.top - r.top); } else if (r.bottom > mImageRect.bottom) { r.offset(0F, -(r.bottom - mImageRect.bottom)); } mCropRect.set(r); mDrawRect = computeLayout(); mContext.invalidate(); }
/** * Adjust left and right edges by current crop window height and the given aspect ratio, both * right and left edges adjusts equally relative to center to keep aspect ratio to the height. */ private void adjustLeftRightByAspectRatio(RectF rect, RectF bounds, float aspectRatio) { rect.inset((rect.width() - rect.height() * aspectRatio) / 2, 0); if (rect.left < bounds.left) { rect.offset(bounds.left - rect.left, 0); } if (rect.right > bounds.right) { rect.offset(bounds.right - rect.right, 0); } }
/** * Adjust top and bottom edges by current crop window width and the given aspect ratio, both top * and bottom edges adjusts equally relative to center to keep aspect ratio to the width. */ private void adjustTopBottomByAspectRatio(RectF rect, RectF bounds, float aspectRatio) { rect.inset(0, (rect.height() - rect.width() / aspectRatio) / 2); if (rect.top < bounds.top) { rect.offset(0, bounds.top - rect.top); } if (rect.bottom > bounds.bottom) { rect.offset(0, bounds.bottom - rect.bottom); } }
// Grows the cropping rectangle by (dx, dy) in image space. void growBy(float dx, float dy) { if (maintainAspectRatio) { if (dx != 0) { dy = dx / initialAspectRatio; } else if (dy != 0) { dx = dy * initialAspectRatio; } } // Don't let the cropping rectangle grow too fast. // Grow at most half of the difference between the image rectangle and // the cropping rectangle. RectF r = new RectF(cropRect); if (dx > 0F && r.width() + 2 * dx > imageRect.width()) { dx = (imageRect.width() - r.width()) / 2F; if (maintainAspectRatio) { dy = dx / initialAspectRatio; } } if (dy > 0F && r.height() + 2 * dy > imageRect.height()) { dy = (imageRect.height() - r.height()) / 2F; if (maintainAspectRatio) { dx = dy * initialAspectRatio; } } r.inset(-dx, -dy); // Don't let the cropping rectangle shrink too fast final float widthCap = 25F; if (r.width() < widthCap) { r.inset(-(widthCap - r.width()) / 2F, 0F); } float heightCap = maintainAspectRatio ? (widthCap / initialAspectRatio) : widthCap; if (r.height() < heightCap) { r.inset(0F, -(heightCap - r.height()) / 2F); } // Put the cropping rectangle inside the image rectangle if (r.left < imageRect.left) { r.offset(imageRect.left - r.left, 0F); } else if (r.right > imageRect.right) { r.offset(-(r.right - imageRect.right), 0F); } if (r.top < imageRect.top) { r.offset(0F, imageRect.top - r.top); } else if (r.bottom > imageRect.bottom) { r.offset(0F, -(r.bottom - imageRect.bottom)); } cropRect.set(r); drawRect = computeLayout(); viewContext.invalidate(); }
@Override public void draw(Canvas canvas) { // Draw the bounding boxes drawBoundingBoxes(canvas); // Set the right values for the paint operatorPaint.setColor(getColor()); operatorPaint.setTextSize(findTextSize()); // Get our operator bounding boxes Rect[] operatorBounding = this.getOperatorBoundingBoxes(); // Draws the operator canvas.save(); Rect textBounding = new Rect(); operatorPaint.getTextBounds(type.getName(), 0, type.getName().length(), textBounding); canvas.translate( (operatorBounding[0].width() - textBounding.width()) / 2, (operatorBounding[0].height() - textBounding.height()) / 2); canvas.drawText( type.getName(), operatorBounding[0].left - textBounding.left, operatorBounding[0].top - textBounding.top, operatorPaint); canvas.restore(); // Use stroke style for the parentheses operatorPaint.setStyle(Paint.Style.STROKE); // Draw the left bracket canvas.save(); canvas.clipRect(operatorBounding[1], Region.Op.INTERSECT); RectF bracket = new RectF(operatorBounding[1]); bracket.inset(0, -operatorPaint.getStrokeWidth()); bracket.offset(bracket.width() / 4, 0); canvas.drawArc(bracket, 100.0f, 160.0f, false, operatorPaint); canvas.restore(); // Draw the right bracket canvas.save(); canvas.clipRect(operatorBounding[2], Region.Op.INTERSECT); bracket = new RectF(operatorBounding[2]); bracket.inset(0, -operatorPaint.getStrokeWidth()); bracket.offset(-bracket.width() / 4, 0); canvas.drawArc(bracket, -80.0f, 160.0f, false, operatorPaint); canvas.restore(); // Set the paint back to fill style operatorPaint.setStyle(Paint.Style.FILL); // Draw the children drawChildren(canvas); }
/** Check if edges have gone out of bounds (including snap margin), and fix if needed. */ private void snapEdgesToBounds(RectF edges, RectF bounds, float margin) { if (edges.left < bounds.left + margin) { edges.offset(bounds.left - edges.left, 0); } if (edges.top < bounds.top + margin) { edges.offset(0, bounds.top - edges.top); } if (edges.right > bounds.right - margin) { edges.offset(bounds.right - edges.right, 0); } if (edges.bottom > bounds.bottom - margin) { edges.offset(0, bounds.bottom - edges.bottom); } }
private void computeRect(final RectF r, View view) { // compute current rectangle according to matrix transformation final float w = view.getWidth(); final float h = view.getHeight(); // use a rectangle at 0,0 to make sure we don't run into issues with scaling r.set(0, 0, w, h); final Matrix m = mTempMatrix; m.reset(); transformMatrix(m, view); mTempMatrix.mapRect(r); r.offset(view.getLeft(), view.getTop()); // Straighten coords if rotations flipped them if (r.right < r.left) { final float f = r.right; r.right = r.left; r.left = f; } if (r.bottom < r.top) { final float f = r.top; r.top = r.bottom; r.bottom = f; } }
/** * Configures the necessary {@link Matrix} transformation to `mTextureView`. This method should be * called after the camera preview size is determined in setUpCameraOutputs and also the size of * `mTextureView` is fixed. * * @param viewWidth The width of `mTextureView` * @param viewHeight The height of `mTextureView` */ private void configureTransform(int viewWidth, int viewHeight) { Activity activity = getActivity(); if (null == mTextureView || null == mPreviewSize || null == activity) { return; } int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); Matrix matrix = new Matrix(); RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth()); float centerX = viewRect.centerX(); float centerY = viewRect.centerY(); if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); float scale = Math.max( (float) viewHeight / mPreviewSize.getHeight(), (float) viewWidth / mPreviewSize.getWidth()); matrix.postScale(scale, scale, centerX, centerY); matrix.postRotate(90 * (rotation - 2), centerX, centerY); } else if (Surface.ROTATION_180 == rotation) { matrix.postRotate(180, centerX, centerY); } mTextureView.setTransform(matrix); }
/** Recalculates page rectangles. */ private void updatePageRects() { if (mViewRect.width() == 0 || mViewRect.height() == 0) { return; } else if (mViewMode == SHOW_ONE_PAGE) { mPageRectRight.set(mViewRect); mPageRectRight.left += mViewRect.width() * mMargins.left; mPageRectRight.right -= mViewRect.width() * mMargins.right; mPageRectRight.top += mViewRect.height() * mMargins.top; mPageRectRight.bottom -= mViewRect.height() * mMargins.bottom; mPageRectLeft.set(mPageRectRight); mPageRectLeft.offset(-mPageRectRight.width(), 0); int bitmapW = (int) ((mPageRectRight.width() * mViewportWidth) / mViewRect.width()); int bitmapH = (int) ((mPageRectRight.height() * mViewportHeight) / mViewRect.height()); mObserver.onPageSizeChanged(bitmapW, bitmapH); } else if (mViewMode == SHOW_TWO_PAGES) { mPageRectRight.set(mViewRect); mPageRectRight.left += mViewRect.width() * mMargins.left; mPageRectRight.right -= mViewRect.width() * mMargins.right; mPageRectRight.top += mViewRect.height() * mMargins.top; mPageRectRight.bottom -= mViewRect.height() * mMargins.bottom; mPageRectLeft.set(mPageRectRight); mPageRectLeft.right = (mPageRectLeft.right + mPageRectLeft.left) / 2; mPageRectRight.left = mPageRectLeft.right; int bitmapW = (int) ((mPageRectRight.width() * mViewportWidth) / mViewRect.width()); int bitmapH = (int) ((mPageRectRight.height() * mViewportHeight) / mViewRect.height()); mObserver.onPageSizeChanged(bitmapW, bitmapH); } }
@Override public void checkHit(@Nullable vector inDirection) { // System.out.println("MeleeAttack: checkHit() starting"); if (possibleVictum != null && owner.loc.distanceSquared(possibleVictum.loc) < Rpg.getMeleeAttackRangeSquared()) { possibleVictum.takeDamage(owner.getDamage(), owner); return; } if (inDirection != null) { checkHitHere.set(inDirection); checkHitHere.times(Rpg.getMeleeAttackRange()).add(owner.loc); // Log.d( "MeleeAttack" , "checkHit(): checkHitHere = " + checkHitHere); inThisArea.set(weaponStrikePercArea); inThisArea.offset(checkHitHere.x, checkHitHere.y); // Log.d( "MeleeAttack" , "inThisArea=" + inThisArea); // System.out.println("owner.getTeam()=" + owner.getTeam()); possibleVictum = cd.checkSingleHit(owner.getTeamName(), inThisArea); if (possibleVictum != null) { possibleVictum.takeDamage(owner.getDamage(), owner); if (weapon.wasDrawnThisFrame()) playHitSound(weaponType, owner.loc.x, owner.loc.y); } else { if (weapon.wasDrawnThisFrame()) playMissSound(weaponType, owner.loc.x, owner.loc.y); } } // System.out.println("MeleeAttack: checkHit() ending"); }
@TargetApi(10) private Bitmap decodeRegionCrop(Bitmap croppedImage, Rect rect) { // Release memory now clearImageView(); InputStream is = null; try { is = getContentResolver().openInputStream(sourceUri); BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false); final int width = decoder.getWidth(); final int height = decoder.getHeight(); if (exifRotation != 0) { // Adjust crop area to account for image rotation Matrix matrix = new Matrix(); matrix.setRotate(-exifRotation); RectF adjusted = new RectF(); matrix.mapRect(adjusted, new RectF(rect)); // Adjust to account for origin at 0,0 adjusted.offset(adjusted.left < 0 ? width : 0, adjusted.top < 0 ? height : 0); rect = new Rect( (int) adjusted.left, (int) adjusted.top, (int) adjusted.right, (int) adjusted.bottom); } try { croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options()); } catch (IllegalArgumentException e) { // Rethrow with some extra information throw new IllegalArgumentException( "Rectangle " + rect + " is outside of the image (" + width + "," + height + "," + exifRotation + ")", e); } } catch (IOException e) { Log.e("Error cropping image: " + e.getMessage(), e); finish(); } catch (OutOfMemoryError e) { Log.e("OOM cropping image: " + e.getMessage(), e); setResultException(e); } finally { CropUtil.closeSilently(is); } return croppedImage; }
// Draws the texture on to the specified rectangle. @Override public void draw(GLCanvas canvas, int x, int y, int width, int height) { RectF src = mSrcRect; RectF dest = mDestRect; float scaleX = (float) width / mWidth; float scaleY = (float) height / mHeight; synchronized (mTiles) { for (int i = 0, n = mTiles.length; i < n; ++i) { Tile t = mTiles[i]; src.set(0, 0, t.contentWidth, t.contentHeight); src.offset(t.offsetX, t.offsetY); mapRect(dest, src, 0, 0, x, y, scaleX, scaleY); src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY); canvas.drawTexture(t, mSrcRect, mDestRect); } } }
@NonNull RectF getAreaFromLoc(@NonNull vector v) { RectF r = new RectF(getPerceivedArea()); r.offset(v.x, v.y); return r; }
// Grows the cropping rectangle by (dx, dy) in image space void moveBy(float dx, float dy) { Rect invalRect = new Rect(drawRect); cropRect.offset(dx, dy); // Put the cropping rectangle inside image rectangle cropRect.offset( Math.max(0, imageRect.left - cropRect.left), Math.max(0, imageRect.top - cropRect.top)); cropRect.offset( Math.min(0, imageRect.right - cropRect.right), Math.min(0, imageRect.bottom - cropRect.bottom)); drawRect = computeLayout(); invalRect.union(drawRect); invalRect.inset(-(int) handleRadius, -(int) handleRadius); viewContext.invalidate(invalRect); }
// Draws a sub region of this texture on to the specified rectangle. public void draw(GLCanvas canvas, RectF source, RectF target) { RectF src = mSrcRect; RectF dest = mDestRect; float x0 = source.left; float y0 = source.top; float x = target.left; float y = target.top; float scaleX = target.width() / source.width(); float scaleY = target.height() / source.height(); synchronized (mTiles) { for (int i = 0, n = mTiles.length; i < n; ++i) { Tile t = mTiles[i]; src.set(0, 0, t.contentWidth, t.contentHeight); src.offset(t.offsetX, t.offsetY); if (!src.intersect(source)) continue; mapRect(dest, src, x0, y0, x, y, scaleX, scaleY); src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY); canvas.drawTexture(t, src, dest); } } }
@Override protected void onDraw(Canvas canvas) { Log.d( TAG, "[onDraw]mZoomInAnimaState:" + mZoomInAnimaState + ", mZoomOutAnimaState:" + mZoomOutAnimaState + ", mOrientation:" + mOrientation); if (mZoomOutAnimaState != ANIMATION_DONE || mZoomInAnimaState != ANIMATION_DONE) { return; } if (mFace != null) { if (mFace.score == OBJECT_TRACKING_SUCCEED) { mTrackIndicator = mTrackStatusIndicator[OBJECT_FOCUSED]; } else { Log.i(TAG, "[onDraw]mFace is null."); return; } // Prepare the matrix. Util.prepareMatrix(mMatrix, false, mDisplayOrientation, mUnCropWidth, mUnCropHeight); // OT indicator is directional. Rotate the matrix and the canvas // so it looks correctly in all orientations. float dx = (getWidth() - mUnCropWidth) / 2; float dy = (getHeight() - mUnCropHeight) / 2; Matrix pointMatrix = new Matrix(); float[] pointes = new float[] {dx, dy}; canvas.save(); mMatrix.postRotate(mOrientation); canvas.rotate(-mOrientation); pointMatrix.postRotate(mCompesation); pointMatrix.mapPoints(pointes); // Transform the coordinates. mRect.set(mFace.rect); mMatrix.mapRect(mRect); mRect.offset(pointes[0], pointes[1]); mTrackIndicator.setBounds( Math.round(mRect.left), Math.round(mRect.top), Math.round(mRect.right), Math.round(mRect.bottom)); if (needDraw()) { mTrackIndicator.draw(canvas); } canvas.restore(); } super.onDraw(canvas); }
private RectF getOval(Canvas canvas, float factor) { RectF oval; final int canvasWidth = canvas.getWidth() - getPaddingLeft() - getPaddingRight(); final int canvasHeight = canvas.getHeight() - getPaddingTop() - getPaddingBottom(); if (canvasHeight * 2 >= canvasWidth) { oval = new RectF(0, 0, canvasWidth * factor, canvasWidth * factor); } else { oval = new RectF(0, 0, canvasHeight * 2 * factor, canvasHeight * 2 * factor); } oval.offset( (canvasWidth - oval.width()) / 2 + getPaddingLeft(), (canvasHeight * 2 - oval.height()) / 2 + getPaddingTop()); return oval; }
private void drawInfoWindow(Canvas canvas, MapView mapView, boolean shadow) { if (mSelectedMapLocation != null) { if (shadow) { // Skip painting a shadow } else { // First we need to determine the screen coordinates of the selected MapLocation Point selDestinationOffset = new Point(); mapView .getProjection() .toPixels( new GeoPoint( mSelectedMapLocation.getLatitude(), mSelectedMapLocation.getLongitude()), selDestinationOffset); // Setup the info window int INFO_WINDOW_WIDTH = 175; int INFO_WINDOW_HEIGHT = 40; RectF infoWindowRect = new RectF(0, 0, INFO_WINDOW_WIDTH, INFO_WINDOW_HEIGHT); int infoWindowOffsetX = selDestinationOffset.x - INFO_WINDOW_WIDTH / 2; int infoWindowOffsetY = selDestinationOffset.y - INFO_WINDOW_HEIGHT - mBubbleIcon.getHeight(); infoWindowRect.offset(infoWindowOffsetX, infoWindowOffsetY); // Drawing the inner info window canvas.drawRoundRect(infoWindowRect, 5, 5, getmInnerPaint()); // Drawing the border for info window canvas.drawRoundRect(infoWindowRect, 5, 5, getmBorderPaint()); // Draw the MapLocation's name int TEXT_OFFSET_X = 10; int TEXT_OFFSET_Y = 15; canvas.drawText( mSelectedMapLocation.getName(), infoWindowOffsetX + TEXT_OFFSET_X, infoWindowOffsetY + TEXT_OFFSET_Y, getmTextPaint()); } } }
/** Center move only changes the position of the crop window without changing the size. */ private void moveCenter( RectF rect, float x, float y, RectF bounds, int viewWidth, int viewHeight, float snapRadius) { float dx = x - rect.centerX(); float dy = y - rect.centerY(); if (rect.left + dx < 0 || rect.right + dx > viewWidth || rect.left + dx < bounds.left || rect.right + dx > bounds.right) { dx /= 1.05f; mTouchOffset.x -= dx / 2; } if (rect.top + dy < 0 || rect.bottom + dy > viewHeight || rect.top + dy < bounds.top || rect.bottom + dy > bounds.bottom) { dy /= 1.05f; mTouchOffset.y -= dy / 2; } rect.offset(dx, dy); snapEdgesToBounds(rect, bounds, snapRadius); }
void a(int paramInt, float paramFloat1, float paramFloat2) { Rect localRect = d(); if (paramInt == 1); do { return; if (paramInt != 32) break; RectF localRectF = new RectF(localRect); localRectF.offset(paramFloat1, paramFloat2); Matrix localMatrix = new Matrix(); if (this.g.invert(localMatrix)) localMatrix.mapRect(localRectF); b(localRectF.left - this.f.left, localRectF.top - this.f.top); } while (!ImageViewTouchBase.a); if ((paramInt & 0x6) == 0) paramFloat1 = 0.0F; if ((paramInt & 0x18) == 0) paramFloat2 = 0.0F; float f1 = paramFloat1 * (this.f.width() / localRect.width()); float f2 = paramFloat2 * (this.f.height() / localRect.height()); int i1; label165: float f3; if ((paramInt & 0x2) != 0) { i1 = -1; f3 = f1 * i1; if ((paramInt & 0x8) == 0) break label205; } label205: for (int i2 = -1; ; i2 = 1) { c(f3, f2 * i2); break; i1 = 1; break label165; } }
@Override protected void onDraw(Canvas canvas) { if (!mBlocked && (mFaces != null) && (mFaces.length > 0)) { final CameraScreenNail sn = ((CameraActivity) getContext()).getCameraScreenNail(); int rw = sn.getUncroppedRenderWidth(); int rh = sn.getUncroppedRenderHeight(); // Prepare the matrix. if (((rh > rw) && ((mDisplayOrientation == 0) || (mDisplayOrientation == 180))) || ((rw > rh) && ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)))) { int temp = rw; rw = rh; rh = temp; } Util.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, rw, rh); int dx = (getWidth() - rw) / 2; int dy = (getHeight() - rh) / 2; // Focus indicator is directional. Rotate the matrix and the canvas // so it looks correctly in all orientations. canvas.save(); mMatrix.postRotate(mOrientation); // postRotate is clockwise canvas.rotate(-mOrientation); // rotate is counter-clockwise (for canvas) for (int i = 0; i < mFaces.length; i++) { // Filter out false positives. if (mFaces[i].score < 50) continue; // Transform the coordinates. mRect.set(mFaces[i].rect); if (LOGV) Util.dumpRect(mRect, "Original rect"); mMatrix.mapRect(mRect); if (LOGV) Util.dumpRect(mRect, "Transformed rect"); mPaint.setColor(mColor); mRect.offset(dx, dy); canvas.drawOval(mRect, mPaint); } canvas.restore(); } super.onDraw(canvas); }
@Override protected void onPostExecute(final RectF result) { if (progressDialog != null) { try { progressDialog.dismiss(); } catch (final Throwable th) { } } if (result != null) { final RectF newRect = new RectF(result); final SearchControls sc = getManagedComponent().getSearchControls(); final int controlsHeight = 3 + sc.getActualHeight(); final float pageHeight = targetPage.getBounds(getZoomModel().getZoom()).height(); newRect.offset(0, -(controlsHeight / pageHeight)); getDocumentController() .goToLink( targetPage.index.docIndex, newRect, AppSettings.current().storeSearchGotoHistory); } else { Toast.makeText(getManagedComponent(), R.string.msg_no_text_found, Toast.LENGTH_LONG).show(); } getDocumentController().redrawView(); }
/** Test whether an information balloon should be displayed or a prior balloon hidden. */ private MapLocation getHitMapLocation(MapView mapView, GeoPoint tapPoint) { /** Tracking the clicks on MapLocation */ MapLocation hitMapLocation = null; RectF hitTestRecr = new RectF(); Point screenCoords = new Point(); Iterator<MapLocation> iterator = mLocationViewers.getMapLocations().iterator(); while (iterator.hasNext()) { MapLocation testLocation = iterator.next(); Bitmap bubbleIcon = testLocation.isSpecial() ? mBubbleIconSpecial : mBubbleIcon; /** This is used to translate the map's lat/long coordinates to screen's coordinates */ mapView .getProjection() .toPixels( new GeoPoint(testLocation.getLatitude(), testLocation.getLongitude()), screenCoords); // Create a testing Rectangle with the size and coordinates of our icon // Set the testing Rectangle with the size and coordinates of our on screen icon hitTestRecr.set( -bubbleIcon.getWidth() / 2, -bubbleIcon.getHeight(), bubbleIcon.getWidth() / 2, 0); hitTestRecr.offset(screenCoords.x, screenCoords.y); // At last test for a match between our Rectangle and the location clicked by the user mapView.getProjection().toPixels(tapPoint, screenCoords); if (hitTestRecr.contains(screenCoords.x, screenCoords.y)) { hitMapLocation = testLocation; break; } } // Finally clear the new MouseSelection as its process finished tapPoint = null; return hitMapLocation; }
private void computeRect(final RectF r, View view) { final float w = view.getWidth(); final float h = view.getHeight(); r.set(0, 0, w, h); final Matrix m = mTempMatrix; m.reset(); transformMatrix(m, view); mTempMatrix.mapRect(r); r.offset(view.getLeft(), view.getTop()); if (r.right < r.left) { final float f = r.right; r.right = r.left; r.left = f; } if (r.bottom < r.top) { final float f = r.top; r.top = r.bottom; r.bottom = f; } }
private GeoTrack getHitMapLocation(MapView mapView, IGeoPoint tapPoint) { // Track which MapLocation was hit...if any GeoTrack result = null; RectF tapPointHitTestRect = new RectF(); Point tapPointTestScreenCoords = new Point(); int zoonLevel = mapView.getZoomLevel(); int selectRadius = zoonLevel + 6; Projection pj = mapView.getProjection(); for (GeoTrack testLocation : geoTracks) { if (!seletedRangeActivated || (testLocation.time >= seletedRangeBeginTimeInMs && testLocation.time <= seletedRangeEndTimeInMs)) { // Translate the MapLocation's lat/long coordinates to screen // coordinates pj.toPixels(testLocation.asGeoPoint(), tapPointTestScreenCoords); // Create a 'hit' testing Rectangle w/size and coordinates of // our // icon // Set the 'hit' testing Rectangle with the size and coordinates // of // our on screen icon tapPointHitTestRect.set(-selectRadius, -selectRadius, selectRadius, selectRadius); tapPointHitTestRect.offset(tapPointTestScreenCoords.x, tapPointTestScreenCoords.y); // Finally test for a match between our 'hit' Rectangle and the // location clicked by the user pj.toPixels(tapPoint, tapPointTestScreenCoords); if (tapPointHitTestRect.contains(tapPointTestScreenCoords.x, tapPointTestScreenCoords.y)) { result = testLocation; // break; } } } return result; }
public void recomputeBoundsLocked() { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); final int screenWidth = mTempPoint.x; final int screenHeight = mTempPoint.y; Region magnifiedBounds = mMagnifiedBounds; magnifiedBounds.set(0, 0, 0, 0); Region availableBounds = mTempRegion1; availableBounds.set(0, 0, screenWidth, screenHeight); Region nonMagnifiedBounds = mTempRegion4; nonMagnifiedBounds.set(0, 0, 0, 0); SparseArray<WindowStateInfo> visibleWindows = mTempWindowStateInfos; visibleWindows.clear(); getWindowsOnScreenLocked(visibleWindows); final int visibleWindowCount = visibleWindows.size(); for (int i = visibleWindowCount - 1; i >= 0; i--) { WindowStateInfo info = visibleWindows.valueAt(i); if (info.mWindowState.mAttrs.type == WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY) { continue; } Region windowBounds = mTempRegion2; Matrix matrix = mTempMatrix; populateTransformationMatrix(info.mWindowState, matrix); RectF windowFrame = mTempRectF; if (mWindowManagerService.mPolicy.canMagnifyWindow(info.mWindowState.mAttrs.type)) { windowFrame.set(info.mWindowState.mFrame); windowFrame.offset(-windowFrame.left, -windowFrame.top); matrix.mapRect(windowFrame); windowBounds.set( (int) windowFrame.left, (int) windowFrame.top, (int) windowFrame.right, (int) windowFrame.bottom); magnifiedBounds.op(windowBounds, Region.Op.UNION); magnifiedBounds.op(availableBounds, Region.Op.INTERSECT); } else { windowFrame.set(info.mTouchableRegion); windowFrame.offset(-info.mWindowState.mFrame.left, -info.mWindowState.mFrame.top); matrix.mapRect(windowFrame); windowBounds.set( (int) windowFrame.left, (int) windowFrame.top, (int) windowFrame.right, (int) windowFrame.bottom); nonMagnifiedBounds.op(windowBounds, Region.Op.UNION); windowBounds.op(magnifiedBounds, Region.Op.DIFFERENCE); availableBounds.op(windowBounds, Region.Op.DIFFERENCE); } Region accountedBounds = mTempRegion2; accountedBounds.set(magnifiedBounds); accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION); accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT); if (accountedBounds.isRect()) { Rect accountedFrame = mTempRect1; accountedBounds.getBounds(accountedFrame); if (accountedFrame.width() == screenWidth && accountedFrame.height() == screenHeight) { break; } } } for (int i = visibleWindowCount - 1; i >= 0; i--) { WindowStateInfo info = visibleWindows.valueAt(i); info.recycle(); visibleWindows.removeAt(i); } magnifiedBounds.op( mHalfBorderWidth, mHalfBorderWidth, screenWidth - mHalfBorderWidth, screenHeight - mHalfBorderWidth, Region.Op.INTERSECT); if (!mOldMagnifiedBounds.equals(magnifiedBounds)) { Region bounds = Region.obtain(); bounds.set(magnifiedBounds); mHandler .obtainMessage(MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, bounds) .sendToTarget(); mWindow.setBounds(magnifiedBounds); Rect dirtyRect = mTempRect1; if (mFullRedrawNeeded) { mFullRedrawNeeded = false; dirtyRect.set( mHalfBorderWidth, mHalfBorderWidth, screenWidth - mHalfBorderWidth, screenHeight - mHalfBorderWidth); mWindow.invalidate(dirtyRect); } else { Region dirtyRegion = mTempRegion3; dirtyRegion.set(magnifiedBounds); dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION); dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT); dirtyRegion.getBounds(dirtyRect); mWindow.invalidate(dirtyRect); } mOldMagnifiedBounds.set(magnifiedBounds); } }
/** * Update preview TextureView rotation to accommodate discrepancy between preview buffer and the * view window orientation. * * <p>Assumptions: - Aspect ratio for the sensor buffers is in landscape orientation, - Dimensions * of buffers received are rotated to the natural device orientation. - The contents of each * buffer are rotated by the inverse of the display rotation. - Surface scales the buffer to fit * the current view bounds. TODO: Make this method works for all orientations */ protected void updatePreviewDisplayRotation(Size previewSize, TextureView textureView) { int rotationDegrees = 0; Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext; int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); Configuration config = activity.getResources().getConfiguration(); // Get UI display rotation switch (displayRotation) { case Surface.ROTATION_0: rotationDegrees = 0; break; case Surface.ROTATION_90: rotationDegrees = 90; break; case Surface.ROTATION_180: rotationDegrees = 180; break; case Surface.ROTATION_270: rotationDegrees = 270; break; } // Get device natural orientation int deviceOrientation = Configuration.ORIENTATION_PORTRAIT; if ((rotationDegrees % 180 == 0 && config.orientation == Configuration.ORIENTATION_LANDSCAPE) || ((rotationDegrees % 180 != 0 && config.orientation == Configuration.ORIENTATION_PORTRAIT))) { deviceOrientation = Configuration.ORIENTATION_LANDSCAPE; } // Rotate the buffer dimensions if device orientation is portrait. int effectiveWidth = previewSize.getWidth(); int effectiveHeight = previewSize.getHeight(); if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) { effectiveWidth = previewSize.getHeight(); effectiveHeight = previewSize.getWidth(); } // Find and center view rect and buffer rect Matrix transformMatrix = textureView.getTransform(null); int viewWidth = textureView.getWidth(); int viewHeight = textureView.getHeight(); RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); RectF bufRect = new RectF(0, 0, effectiveWidth, effectiveHeight); float centerX = viewRect.centerX(); float centerY = viewRect.centerY(); bufRect.offset(centerX - bufRect.centerX(), centerY - bufRect.centerY()); // Undo ScaleToFit.FILL done by the surface transformMatrix.setRectToRect(viewRect, bufRect, Matrix.ScaleToFit.FILL); // Rotate buffer contents to proper orientation transformMatrix.postRotate((360 - rotationDegrees) % 360, centerX, centerY); if ((rotationDegrees % 180) == 90) { int temp = effectiveWidth; effectiveWidth = effectiveHeight; effectiveHeight = temp; } // Scale to fit view, cropping the longest dimension float scale = Math.max(viewWidth / (float) effectiveWidth, viewHeight / (float) effectiveHeight); transformMatrix.postScale(scale, scale, centerX, centerY); Handler handler = new Handler(Looper.getMainLooper()); class TransformUpdater implements Runnable { TextureView mView; Matrix mTransformMatrix; TransformUpdater(TextureView view, Matrix matrix) { mView = view; mTransformMatrix = matrix; } @Override public void run() { mView.setTransform(mTransformMatrix); } } handler.post(new TransformUpdater(textureView, transformMatrix)); }
@Override public void onDraw(Canvas c, BatteryTracker tracker) { if (mDisposed) return; final int level = tracker.level; if (level == BatteryTracker.UNKNOWN_LEVEL) return; float drawFrac = (float) level / 100f; final int pt = getPaddingTop() + (mHorizontal ? (int) (mHeight * 0.20f) : 0); final int pl = getPaddingLeft(); final int pr = getPaddingRight(); final int pb = getPaddingBottom(); int height = mHeight - pt - pb; int width = mWidth - pl - pr; mButtonHeight = (int) ((mHorizontal ? width : height) * 0.12f); mFrame.set(0, 0, width, height); mFrame.offset(pl, pt); if (mHorizontal) { mButtonFrame.set( /*cover frame border of intersecting area*/ width - (mButtonHeight + 5) - mFrame.left, mFrame.top + height * 0.25f, mFrame.right, mFrame.bottom - height * 0.25f); mButtonFrame.top += SUBPIXEL; mButtonFrame.bottom -= SUBPIXEL; mButtonFrame.right -= SUBPIXEL; } else { mButtonFrame.set( mFrame.left + width * 0.25f, mFrame.top, mFrame.right - width * 0.25f, mFrame.top + mButtonHeight + 5 /*cover frame border of intersecting area*/); mButtonFrame.top += SUBPIXEL; mButtonFrame.left += SUBPIXEL; mButtonFrame.right -= SUBPIXEL; } if (mHorizontal) { mFrame.right -= mButtonHeight; } else { mFrame.top += mButtonHeight; } mFrame.left += SUBPIXEL; mFrame.top += SUBPIXEL; mFrame.right -= SUBPIXEL; mFrame.bottom -= SUBPIXEL; // first, draw the battery shape c.drawRect(mFrame, mFramePaint); // fill 'er up final int color = tracker.plugged ? mChargeColor : getColorForLevel(level); mBatteryPaint.setColor(color); if (level >= FULL) { drawFrac = 1f; } else if (level <= EMPTY) { drawFrac = 0f; } c.drawRect(mButtonFrame, drawFrac == 1f ? mBatteryPaint : mFramePaint); mClipFrame.set(mFrame); if (mHorizontal) { mClipFrame.right -= (mFrame.width() * (1f - drawFrac)); } else { mClipFrame.top += (mFrame.height() * (1f - drawFrac)); } c.save(Canvas.CLIP_SAVE_FLAG); c.clipRect(mClipFrame); c.drawRect(mFrame, mBatteryPaint); c.restore(); if (tracker.shouldIndicateCharging()) { // draw the bolt final float bl = (int) (mFrame.left + mFrame.width() / (mHorizontal ? 9f : 4.5f)); final float bt = (int) (mFrame.top + mFrame.height() / (mHorizontal ? 4.5f : 6f)); final float br = (int) (mFrame.right - mFrame.width() / (mHorizontal ? 6f : 7f)); final float bb = (int) (mFrame.bottom - mFrame.height() / (mHorizontal ? 7f : 10f)); if (mBoltFrame.left != bl || mBoltFrame.top != bt || mBoltFrame.right != br || mBoltFrame.bottom != bb) { mBoltFrame.set(bl, bt, br, bb); mBoltPath.reset(); mBoltPath.moveTo( mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); for (int i = 2; i < mBoltPoints.length; i += 2) { mBoltPath.lineTo( mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height()); } mBoltPath.lineTo( mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); } c.drawPath(mBoltPath, mBoltPaint); } else if (level <= EMPTY) { final float x = mHorizontal ? pt + (height * 0.5f) : mWidth * 0.5f; final float y = mHorizontal ? (mWidth - mWarningTextHeight) * -0.48f : (mHeight + mWarningTextHeight) * 0.48f; if (mHorizontal) { c.save(); c.rotate(90); } c.drawText(mWarningString, x, y, mWarningTextPaint); if (mHorizontal) { c.restore(); } } else if (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT)) { final float full = mHorizontal ? 0.60f : 0.45f; final float nofull = mHorizontal ? 0.75f : 0.6f; final float single = mHorizontal ? 0.86f : 0.75f; mTextPaint.setTextSize( height * (SINGLE_DIGIT_PERCENT ? single : (tracker.level == 100 ? full : nofull))); mTextHeight = -mTextPaint.getFontMetrics().ascent; final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (level / 10) : level); final float x = mWidth * 0.5f; final float y = pt + (height + mTextHeight) * 0.47f; c.drawText(str, x, y, mTextPaint); } }
@Override protected void onDraw(Canvas canvas) { if (!mBlocked && (mFaces != null) && (mFaces.length > 0)) { int rw, rh; rw = mUncroppedWidth; rh = mUncroppedHeight; // Prepare the matrix. if (((rh > rw) && ((mDisplayOrientation == 0) || (mDisplayOrientation == 180))) || ((rw > rh) && ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)))) { int temp = rw; rw = rh; rh = temp; } CameraUtil.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, rw, rh); int dx = (getWidth() - rw) / 2; ; int dy = (getHeight() - rh) / 2; // Focus indicator is directional. Rotate the matrix and the canvas // so it looks correctly in all orientations. canvas.save(); mMatrix.postRotate(mOrientation); // postRotate is clockwise canvas.rotate(-mOrientation); // rotate is counter-clockwise (for canvas) for (int i = 0; i < mFaces.length; i++) { // Filter out false positives. if (mFaces[i].score < 50) continue; // Transform the coordinates. mRect.set(mFaces[i].rect); if (LOGV) CameraUtil.dumpRect(mRect, "Original rect"); mMatrix.mapRect(mRect); if (LOGV) CameraUtil.dumpRect(mRect, "Transformed rect"); mPaint.setColor(mColor); mRect.offset(dx, dy); canvas.drawOval(mRect, mPaint); if (mFaces[i] instanceof ExtendedFace) { ExtendedFace face = (ExtendedFace) mFaces[i]; float[] point = new float[4]; int delta_x = mFaces[i].rect.width() / 12; int delta_y = mFaces[i].rect.height() / 12; Log.e( TAG, "blink: (" + face.getLeftEyeBlinkDegree() + ", " + face.getRightEyeBlinkDegree() + ")"); if (face.leftEye != null) { if ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)) { point[0] = face.leftEye.x; point[1] = face.leftEye.y - delta_y / 2; point[2] = face.leftEye.x; point[3] = face.leftEye.y + delta_y / 2; } else { point[0] = face.leftEye.x - delta_x / 2; point[1] = face.leftEye.y; point[2] = face.leftEye.x + delta_x / 2; point[3] = face.leftEye.y; } mMatrix.mapPoints(point); if (face.getLeftEyeBlinkDegree() >= blink_threshold) { canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + dx, point[3] + dy, mPaint); } } if (face.rightEye != null) { if ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)) { point[0] = face.rightEye.x; point[1] = face.rightEye.y - delta_y / 2; point[2] = face.rightEye.x; point[3] = face.rightEye.y + delta_y / 2; } else { point[0] = face.rightEye.x - delta_x / 2; point[1] = face.rightEye.y; point[2] = face.rightEye.x + delta_x / 2; point[3] = face.rightEye.y; } mMatrix.mapPoints(point); if (face.getRightEyeBlinkDegree() >= blink_threshold) { // Add offset to the points if the rect has an offset canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + dx, point[3] + dy, mPaint); } } if (face.getLeftRightGazeDegree() != 0 || face.getTopBottomGazeDegree() != 0) { double length = Math.sqrt( (face.leftEye.x - face.rightEye.x) * (face.leftEye.x - face.rightEye.x) + (face.leftEye.y - face.rightEye.y) * (face.leftEye.y - face.rightEye.y)) / 2.0; double nGazeYaw = -face.getLeftRightGazeDegree(); double nGazePitch = -face.getTopBottomGazeDegree(); float gazeRollX = (float) ((-Math.sin(nGazeYaw / 180.0 * Math.PI) * Math.cos(-face.getRollDirection() / 180.0 * Math.PI) + Math.sin(nGazePitch / 180.0 * Math.PI) * Math.cos(nGazeYaw / 180.0 * Math.PI) * Math.sin(-face.getRollDirection() / 180.0 * Math.PI)) * (-length) + 0.5); float gazeRollY = (float) ((Math.sin(-nGazeYaw / 180.0 * Math.PI) * Math.sin(-face.getRollDirection() / 180.0 * Math.PI) - Math.sin(nGazePitch / 180.0 * Math.PI) * Math.cos(nGazeYaw / 180.0 * Math.PI) * Math.cos(-face.getRollDirection() / 180.0 * Math.PI)) * (-length) + 0.5); if (face.getLeftEyeBlinkDegree() < blink_threshold) { if ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)) { point[0] = face.leftEye.x; point[1] = face.leftEye.y; point[2] = face.leftEye.x + gazeRollX; point[3] = face.leftEye.y + gazeRollY; } else { point[0] = face.leftEye.x; point[1] = face.leftEye.y; point[2] = face.leftEye.x + gazeRollY; point[3] = face.leftEye.y + gazeRollX; } mMatrix.mapPoints(point); canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + dx, point[3] + dy, mPaint); } if (face.getRightEyeBlinkDegree() < blink_threshold) { if ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)) { point[0] = face.rightEye.x; point[1] = face.rightEye.y; point[2] = face.rightEye.x + gazeRollX; point[3] = face.rightEye.y + gazeRollY; } else { point[0] = face.rightEye.x; point[1] = face.rightEye.y; point[2] = face.rightEye.x + gazeRollY; point[3] = face.rightEye.y + gazeRollX; } mMatrix.mapPoints(point); canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + dx, point[3] + dy, mPaint); } } if (face.mouth != null) { Log.e(TAG, "smile: " + face.getSmileDegree() + "," + face.getSmileScore()); if (face.getSmileDegree() < smile_threashold_no_smile) { point[0] = face.mouth.x - delta_x; point[1] = face.mouth.y; point[2] = face.mouth.x + delta_x; point[3] = face.mouth.y; Matrix faceMatrix = new Matrix(mMatrix); faceMatrix.preRotate(face.getRollDirection(), face.mouth.x, face.mouth.y); faceMatrix.mapPoints(point); canvas.drawLine(point[0] + dx, point[1] + dy, point[2] + dx, point[3] + dy, mPaint); } else if (face.getSmileDegree() < smile_threashold_small_smile) { int rotation_mouth = mDisplayOrientation - face.getRollDirection(); if (0 > rotation_mouth) { rotation_mouth = 360 + rotation_mouth; } mRect.set( face.mouth.x - delta_x, face.mouth.y - delta_y, face.mouth.x + delta_x, face.mouth.y + delta_y); mMatrix.mapRect(mRect); mRect.offset(dx, dy); canvas.drawArc(mRect, rotation_mouth, 180, true, mPaint); } else { mRect.set( face.mouth.x - delta_x, face.mouth.y - delta_y, face.mouth.x + delta_x, face.mouth.y + delta_y); mMatrix.mapRect(mRect); mRect.offset(dx, dy); canvas.drawOval(mRect, mPaint); } } } } canvas.restore(); } super.onDraw(canvas); }
public synchronized void DrawOnCanvas( TReflectionWindowStruc RW, double VisibleFactor, Canvas canvas) { double RW_SqrScale = Math.pow(RW.Scale(), 2); // . calculate max item number depends on image square int SquareOrderHintList_Size = 5 * 4; // . prepare square ordered item list TSpaceHintItem SquareOrderHintList = null; TSpaceHint Item = Items; while (Item != null) { if (RW.Container_IsNodeVisible(Item.BindingPointX, Item.BindingPointY)) { if ((Item.BaseSquare * RW_SqrScale) >= VisibleFactor) { TXYCoord P = RW.ConvertToScreen(Item.BindingPointX, Item.BindingPointY); if (((RW.Xmn <= P.X) && (P.X <= RW.Xmx)) && ((RW.Ymn <= P.Y) && (P.Y <= RW.Ymx))) { int Size = SquareOrderHintList_Size; TSpaceHintItem LastHintItem = null; TSpaceHintItem HintItem = SquareOrderHintList; while (HintItem != null) { if (HintItem.Item.BaseSquare < Item.BaseSquare) break; // . > // . Size--; if (Size <= 0) break; // . > // . LastHintItem = HintItem; HintItem = HintItem.Next; } if (Size > 0) if (LastHintItem != null) LastHintItem.Next = new TSpaceHintItem(Item, LastHintItem.Next); else SquareOrderHintList = new TSpaceHintItem(Item, SquareOrderHintList); } } } // . Item = Item.Next; } // . re-order item list and prepare a draw list TSpaceHint[] DrawItemList = new TSpaceHint[SquareOrderHintList_Size]; TSpaceHintItem HintItem = SquareOrderHintList; for (int I = SquareOrderHintList_Size - 1; I >= 0; I--) if (HintItem != null) { DrawItemList[I] = HintItem.Item; HintItem = HintItem.Next; } else break; // . > // . draw list for (int I = 0; I < DrawItemList.length; I++) { Item = DrawItemList[I]; if (Item != null) { TXYCoord P = RW.ConvertToScreen(Item.BindingPointX, Item.BindingPointY); // . draw image float Left = (float) P.X; boolean flImage = false; synchronized (ItemsImageDataFiles) { TSpaceHintImageDataFile ImageDataFile = ItemsImageDataFiles.ItemsTable.get(Item.InfoImageDATAFileID); if ((ImageDataFile != null) && (ImageDataFile.Data != null)) { RectF ImageRect = ImageDataFile.Data_GetDestinationRect(ItemImageMinSize); ImageRect.offset(Left, (float) (P.Y - ImageRect.height())); // . canvas.drawBitmap( ImageDataFile.Data, ImageDataFile.Data_GetOriginalRect(), ImageRect, DrawPointItemImagePaint); // . Left += ImageRect.width() + 1.0F; flImage = true; } } // . draw selection if it exists if (Item.flSelected) { Rect TR = new Rect(); Item.paint.getTextBounds(Item.InfoString, 0, Item.InfoString.length(), TR); float X0, Y0, X1, Y1; X0 = Left - ItemSpacing; Y0 = (float) P.Y - (TR.bottom - TR.top) - ItemSpacing; X1 = Left + (TR.right - TR.left) + ItemSpacing; Y1 = (float) P.Y + ItemSpacing; // . SelectedPaint.setColor(Color.argb(127, 255, 0, 0)); canvas.drawRect(X0, Y0, X1, Y1, SelectedPaint); float[] Points = {X0, Y0, X1, Y0, X1, Y0, X1, Y1, X1, Y1, X0, Y1, X0, Y1, X0, Y0}; SelectedPaint.setColor(Color.argb(255, 255, 0, 0)); canvas.drawLines(Points, SelectedPaint); } // . draw image if (!flImage) canvas.drawCircle((float) P.X, (float) P.Y, 3.0F, DrawPointPaint); // . draw text Paint ShadowPaint = new Paint(Item.paint); ShadowPaint.setColor(Color.BLACK); canvas.drawText(Item.InfoString, Left + 1, (float) P.Y + 1, ShadowPaint); canvas.drawText(Item.InfoString, Left, (float) P.Y, Item.paint); } } }