private void init() { if (mPaint == null) { mPaint = new Paint(); mPaint.setColor(Color.WHITE); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); } int count = (mPoints - 1) * 4; posX = new float[count]; posY = new float[count]; Rect bounds = new Rect(); bounds.set(getBounds()); bounds.inset(mPadding, mPadding); // circumference float circ = (float) (Math.PI * (float) Math.min(bounds.width(), bounds.height())); float arcLength = circ / count; mSize = (float) ((arcLength) / (2 * Math.PI)); double degrees = Math.toRadians((float) 360 / (float) count); for (int i = 0; i < count; i++) { posX[i] = (float) (bounds.exactCenterX() - (bounds.width() / 2) * Math.sin(degrees * i)); posY[i] = (float) (bounds.exactCenterY() + (bounds.height() / 2) * Math.cos(degrees * i)); } }
private static void testProgressValues(ProgressValues progress, Rect bounds) { // Ensure that the percent progress is valid. assertTrue(progress.getPercent() >= 0); assertTrue(progress.getPercent() <= 100); // Ensure that the text rect is valid. final Rect textRect = progress.getCurrentRect(); assertTrue(textRect.left <= textRect.right); assertTrue(textRect.top <= textRect.bottom); // Text rect must match the bounds of the image or sub-rectangle used. assertEquals(textRect.height(), bounds.height()); assertEquals(textRect.width(), bounds.width()); // Ensure that the word rect is valid. final Rect wordRect = progress.getCurrentWordRect(); assertTrue(textRect.left <= textRect.right); assertTrue(textRect.top <= textRect.bottom); // Ensure the word rect falls within the text rect. final Rect absoluteWordRect = new Rect( textRect.left + wordRect.left, textRect.top + wordRect.top, textRect.left + wordRect.right, textRect.top + wordRect.bottom); assertTrue(textRect.contains(absoluteWordRect)); }
@Override public void draw(Canvas canvas) { Rect bounds = getBounds(); if (bounds.width() == 0 || bounds.height() == 0) { return; } if (mPaint == null) { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.BLACK); onPreparePaint(mPaint); } mPaint.setAlpha(mAlpha); ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter; mPaint.setColorFilter(colorFilter); int saveCount = canvas.save(); canvas.translate(bounds.left, bounds.top); if (needMirroring()) { canvas.translate(bounds.width(), 0); canvas.scale(-1, 1); } onDraw(canvas, bounds.width(), bounds.height(), mPaint); canvas.restoreToCount(saveCount); }
static Button load( Context context, int id, int resId, boolean landscape, boolean is565, Rect screen, Rect space, boolean forceLoad) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); final String prefLayoutBase = "Controls." + (landscape ? "Landscape." : "Portrait."); final String prefBase = prefLayoutBase + getButtonName(id) + "."; final Button template = landscape ? landscapeToDefault.get(id) : portraitToDefault.get(id); if (forceLoad || prefs.getBoolean(prefLayoutBase + "Draw", true)) { float controlxscale = (float) screen.width() / (float) space.width(); float controlyscale = (float) screen.height() / (float) space.height(); final Rect finalRect = new Rect( prefs.getInt(prefBase + "Left", (int) (template.position.left * controlxscale)), prefs.getInt(prefBase + "Top", (int) (template.position.top * controlyscale)), prefs.getInt(prefBase + "Right", (int) (template.position.right * controlxscale)), prefs.getInt(prefBase + "Bottom", (int) (template.position.bottom * controlyscale))); final BitmapFactory.Options controlOptions = new BitmapFactory.Options(); if (is565) controlOptions.inPreferredConfig = Bitmap.Config.RGB_565; final Bitmap originalControls = BitmapFactory.decodeResource(context.getResources(), resId, controlOptions); final Bitmap controls = Bitmap.createScaledBitmap(originalControls, finalRect.width(), finalRect.height(), true); return new Button(finalRect, id, controls); } else return new Button(template.position, id); }
@Override public Rect[] getOperatorBoundingBoxes() { // Get the sizes final Rect childRect = getChild(0).getBoundingBox(); final int parentheseWidth = (int) (childRect.height() * PARENTHESES_RATIO); Rect textBounding = sizeAddPadding(getSize(findTextSize())); // Make sure everything is aligned nicely final int childCenterY = getChild(0).getCenter().y; final int childTop = Math.max(textBounding.centerY() - childCenterY, 0); textBounding.offsetTo(0, Math.max(childCenterY - textBounding.centerY(), 0)); // Return the bounding boxes return new Rect[] { textBounding, new Rect( textBounding.width(), childTop, textBounding.width() + parentheseWidth, childTop + childRect.height()), new Rect( textBounding.width() + parentheseWidth + childRect.width(), childTop, textBounding.width() + childRect.width() + 2 * parentheseWidth, childTop + childRect.height()) }; }
// Handles motion (dx, dy) in screen space. // The "edge" parameter specifies which edges the user is dragging. void handleMotion(int edge, float dx, float dy) { Rect r = computeLayout(); if (edge == GROW_NONE) { return; } else if (edge == MOVE) { // Convert to image space before sending to moveBy(). moveBy(dx * (mCropRect.width() / r.width()), dy * (mCropRect.height() / r.height())); } else { if (((GROW_LEFT_EDGE | GROW_RIGHT_EDGE) & edge) == 0) { dx = 0; } if (((GROW_TOP_EDGE | GROW_BOTTOM_EDGE) & edge) == 0) { dy = 0; } // Convert to image space before sending to growBy(). float xDelta = dx * (mCropRect.width() / r.width()); float yDelta = dy * (mCropRect.height() / r.height()); growBy( (((edge & GROW_LEFT_EDGE) != 0) ? -1 : 1) * xDelta, (((edge & GROW_TOP_EDGE) != 0) ? -1 : 1) * yDelta); } }
/** * Changes the size of the framing rect. * * @param deltaWidth Number of pixels to adjust the width * @param deltaHeight Number of pixels to adjust the height */ public synchronized void adjustFramingRect(int deltaWidth, int deltaHeight) { if (initialized) { Point screenResolution = configManager.getScreenResolution(); // Set maximum and minimum sizes if ((framingRect.width() + deltaWidth > screenResolution.x - 4) || (framingRect.width() + deltaWidth < 50)) { deltaWidth = 0; } if ((framingRect.height() + deltaHeight > screenResolution.y - 4) || (framingRect.height() + deltaHeight < 50)) { deltaHeight = 0; } int newWidth = framingRect.width() + deltaWidth; int newHeight = framingRect.height() + deltaHeight; int leftOffset = (screenResolution.x - newWidth) / 2; int topOffset = (screenResolution.y - newHeight) / 2; framingRect = new Rect(leftOffset, topOffset, leftOffset + newWidth, topOffset + newHeight); framingRectInPreview = null; } else { requestedFramingRectWidth = deltaWidth; requestedFramingRectHeight = deltaHeight; } }
/** * Method that load the gles texture and apply to the requestor frame (which includes fix the * aspect ratio and/or effects and borders) * * @param requestor The requestor target * @param ti The original texture information (the one with the bitmap one) */ private void applyToRequestor(TextureRequestor requestor, GLESTextureInfo ti) { // Transform requestor dimensions to screen dimensions RectF dimens = requestor.getRequestorDimensions(); Rect pixels = new Rect( 0, 0, (int) (mScreenDimensions.width() * dimens.width() / 2), (int) (mScreenDimensions.height() * dimens.height() / 2)); final Disposition disposition = requestor.getDisposition(); synchronized (mEffectsSync) { if (disposition.hasFlag(Disposition.EFFECT_FLAG)) { ti.effect = mEffects.getNextEffect(); } if (disposition.hasFlag(Disposition.BORDER_FLAG)) { ti.border = mBorders.getNextBorder(); } } // Check if we have to apply any correction to the image GLESTextureInfo dst; if (ti.bitmap != null && Preferences.General.isFixAspectRatio(mContext)) { // Create a texture of power of two here to avoid scaling the bitmap twice int w = pixels.width(); int h = pixels.height(); if (!BitmapUtils.isPowerOfTwo(w, h) && PreferencesProvider.Preferences.General.isPowerOfTwo(mContext)) { w = h = BitmapUtils.calculateUpperPowerOfTwo(Math.min(w, h)); } // Create a thumbnail of the image Bitmap thumb = BitmapUtils.createScaledBitmap(ti.bitmap, w, h, BitmapUtils.ScalingLogic.CROP); if (!thumb.equals(ti.bitmap)) { ti.bitmap.recycle(); } dst = GLESUtil.loadTexture(mContext, thumb, ti.effect, ti.border, pixels); } else { // Load the texture without any correction dst = GLESUtil.loadTexture(mContext, ti.bitmap, ti.effect, ti.border, pixels); } // Swap references ti.bitmap = dst.bitmap; ti.handle = dst.handle; ti.effect = null; ti.border = null; dst.handle = 0; dst.bitmap = null; // And notify to the requestor requestor.setTextureHandle(ti); // Clean up memory if (ti.bitmap != null) { ti.bitmap.recycle(); ti.bitmap = null; } }
private Bitmap extentSnapshot(int doc, int gs, int spaceAround, boolean transparent) { final LogHelper log = new LogHelper(); final Rect extent = getDisplayExtent(); if (!extent.isEmpty()) { extent.inset(-spaceAround, -spaceAround); extent.intersect(0, 0, mView.getView().getWidth(), mView.getView().getHeight()); } if (extent.isEmpty()) { return null; } final Bitmap viewBitmap = mView.snapshot(doc, gs, transparent); if (viewBitmap == null) { return null; } if (extent.width() == mView.getView().getWidth() && extent.height() == mView.getView().getHeight()) { log.r(viewBitmap.getByteCount()); return viewBitmap; } final Bitmap realBitmap = Bitmap.createBitmap(viewBitmap, extent.left, extent.top, extent.width(), extent.height()); viewBitmap.recycle(); log.r(realBitmap.getByteCount()); return realBitmap; }
@Override public void draw(Canvas canvas, Rect chartArea) { int n = points.size(); scaledGap = barGap * (float) (chartArea.width() / (maxX - minX)); barWidth = (chartArea.width() - scaledGap * (n - 1)) / n; Point p; double scaledY; double yMax = chartArea.top; for (int i = 0; i < points.size(); i++) { y0 = chartArea.top + chartArea.height(); p = points.get(i); scaledY = (p.getY() - minY + barGap) * (chartArea.height()) / (maxY - minY + 2 * barGap); double scaledX = i * (barWidth + scaledGap); if (!areSum.get(i)) { y0 = yMax + scaledY; drawPoint(canvas, scaledX + chartArea.left, yMax, colors.get(i)); yMax += scaledY; } else { drawPoint( canvas, scaledX + chartArea.left, chartArea.top + chartArea.height() - scaledY, colors.get(i)); } } }
@Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: matrix.getValues(imageValues); selectedPoint[0] = (event.getX() - imageValues[2]) / imageValues[0]; selectedPoint[1] = (event.getY() - imageValues[5]) / imageValues[4]; Log.d("POINT_TOUCH", "IMAGE : " + selectedPoint[0] + " and " + selectedPoint[1]); if (selectedPoint[1] < bounds.height()) { marker.setX(event.getX() - markerBounds.width() / 2); marker.setY(event.getY() - markerBounds.height()); marker.setAlpha(VISIBLE); measureButton.setClickable(true); measureButton.setEnabled(true); } else { marker.setAlpha(TRANSPARENT); measureButton.setClickable(false); measureButton.setEnabled(false); } break; } return true; }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // draw progress bars canvas.drawRect(mProgressBar, mProgressPaint); mSecondaryProgressExt.draw(canvas, mProgressBar); canvas.drawRect(mPlayedBar, mPlayedPaint); // draw scrubber and timers if (mShowScrubber) { canvas.drawBitmap(mScrubber, mScrubberLeft, mScrubberTop, null); } if (mShowTimes) { canvas.drawText( stringForTime(mCurrentTime), mTimeBounds.width() / 2 + getPaddingLeft(), mTimeBounds.height() + mVPaddingInPx / 2 + mScrubberPadding + 1 + mLayoutExt.getTimeOffset(), mTimeTextPaint); canvas.drawText( stringForTime(mTotalTime), getWidth() - getPaddingRight() - mTimeBounds.width() / 2, mTimeBounds.height() + mVPaddingInPx / 2 + mScrubberPadding + 1 + mLayoutExt.getTimeOffset(), mTimeTextPaint); } mInfoExt.draw(canvas, mLayoutExt.getInfoBounds(this, mTimeBounds)); }
public static void getMultilineBounds(MultiLineTextMeasureInfo info) { info.widths = new float[info.lines.length]; info.heights = new float[info.lines.length]; Rect r = new Rect(); float tH = 0f; float tW = 0f; for (int i = 0; i < info.lines.length; i++) { if (info.lines[i].length() < 1) continue; info.paint.getTextBounds(info.lines[i], 0, info.lines[i].length(), r); info.widths[i] = r.width(); info.heights[i] = r.height(); if (r.width() > info.width) { info.width = r.width(); tW = r.width(); } info.height += r.height() + info.paint.getFontSpacing(); tH += r.height(); // + info.paint.getFontSpacing(); } if (r.width() > info.width) { info.width = r.width(); tW = r.width(); } info.height = (int) Math.ceil(tH); info.width = (int) Math.ceil(tW); /* * if (info.lines.length > 1) info.height -= * info.paint.getFontSpacing(); */ }
@Override public void draw(Canvas canvas) { super.draw(canvas); // draw progress bars canvas.drawRect(progressBar, progressPaint); canvas.drawRect(playedBar, playedPaint); // draw scrubber and timers if (showScrubber) { canvas.drawBitmap(scrubber, scrubberLeft, scrubberTop, null); } if (showTimes) { canvas.drawText( stringForTime(currentTime), timeBounds.width() / 2 + getPaddingLeft(), timeBounds.height() + vPaddingInPx / 2 + scrubberPadding + 1, timeTextPaint); canvas.drawText( stringForTime(totalTime), getWidth() - getPaddingRight() - timeBounds.width() / 2, timeBounds.height() + vPaddingInPx / 2 + scrubberPadding + 1, timeTextPaint); } }
@Override protected void dispatchDraw(Canvas canvas) { View childView = getChildAt(mCurrentSelection); TextView childTextView = null; if (childView instanceof TextView) { childTextView = (TextView) childView; } if (childTextView != null && !TextUtils.isEmpty(childTextView.getText()) && getVisibility() == View.VISIBLE && childTextView.getVisibility() == View.VISIBLE) { Rect childRect = new Rect(); childTextView.getLocalVisibleRect(childRect); float childViewX = childTextView.getX() + childTextView.getWidth() / 2; float childViewY = childTextView.getY() + childTextView.getHeight() / 2; int top = (int) (childViewY - mSelectedRect.height() / 2); int left = (int) (childViewX - mSelectedRect.width() / 2); mSelectedRect.set(left, top, left + mSelectedRect.width(), top + mSelectedRect.height()); if (isShowSelected && !mSelectedRect.isEmpty()) { final Drawable selectedBg = mSelectedBg; selectedBg.setBounds(mSelectedRect); selectedBg.draw(canvas); } } super.dispatchDraw(canvas); }
/** 计算出圆的半径 */ private void computeRadious() { Rect bounds = getBounds(); radious = bounds.width() < bounds.height() ? bounds.width() / 2f - mMargin : bounds.height() / 2f - mMargin; }
/** * Shrink the {@code shrinkTarget} rectangle to snugly fit inside of {@code reference}; the aspect * ratio of {@code shrinkTarget} will change to be the same aspect ratio as {@code reference}. * * <p>At most a single dimension will scale (down). Both dimensions will never be scaled. * * @param reference the rectangle whose aspect ratio will be used as the new aspect ratio * @param shrinkTarget the rectangle which will be scaled down to have a new aspect ratio * @return a new rectangle, a subset of {@code shrinkTarget}, whose aspect ratio will match that * of {@code reference} */ private static Rect shrinkToSameAspectRatioCentered(Rect reference, Rect shrinkTarget) { float aspectRatioReference = reference.width() * 1.0f / reference.height(); float aspectRatioShrinkTarget = shrinkTarget.width() * 1.0f / shrinkTarget.height(); float cropH, cropW; if (aspectRatioShrinkTarget < aspectRatioReference) { // The new width must be smaller than the height, so scale the width by AR cropH = reference.height(); cropW = cropH * aspectRatioShrinkTarget; } else { // The new height must be smaller (or equal) than the width, so scale the height by AR cropW = reference.width(); cropH = cropW / aspectRatioShrinkTarget; } Matrix translateMatrix = new Matrix(); RectF shrunkRect = new RectF(shrinkTarget); // Scale the rectangle down, but keep its center in the same place as before translateMatrix.setScale( cropW / reference.width(), cropH / reference.height(), shrinkTarget.exactCenterX(), shrinkTarget.exactCenterY()); translateMatrix.mapRect(/*inout*/ shrunkRect); return ParamsUtils.createRect(shrunkRect); }
private void drawLeftIndicator(Canvas canvas) { if (mLeftActiveView != null && isViewDescendant(mLeftActiveView)) { Integer position = (Integer) mLeftActiveView.getTag(R.id.tplActiveViewPosition); final int pos = position == null ? 0 : position; if (pos == mLeftActivePosition) { mLeftActiveView.getDrawingRect(mLeftActiveRect); offsetDescendantRectToMyCoords(mLeftActiveView, mLeftActiveRect); if (mLeftIndicatorAnimating) { final int indicatorFinalTop = mLeftActiveRect.top + ((mLeftActiveRect.height() - mLeftActiveIndicator.getHeight()) / 2); final int indicatorStartTop = mLeftIndicatorStartPos; final int diff = indicatorFinalTop - indicatorStartTop; final int startOffset = (int) (diff * mLeftIndicatorOffset); mLeftIndicatorTop = indicatorStartTop + startOffset; } else { mLeftIndicatorTop = mLeftActiveRect.top + ((mLeftActiveRect.height() - mLeftActiveIndicator.getHeight()) / 2); } final int right = (int) (mMiddlePane.getLeft() + Math.floor(mMiddlePane.getTranslationX())); final int left = right - mLeftActiveIndicator.getWidth(); canvas.save(); canvas.clipRect(left, 0, right, getHeight()); canvas.drawBitmap(mLeftActiveIndicator, left, mLeftIndicatorTop, null); canvas.restore(); } } }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { int desired = (int) (getPaddingLeft() + getPaddingRight() + rectDst.width() + bitmapBaseLine.getWidth()); width = desired; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { int desired; if (valueNode2 != null) { desired = (int) (getPaddingTop() + getPaddingBottom() + rectDst.height() * 3 / 2); height = desired; } else { desired = (int) (getPaddingTop() + getPaddingBottom() + rectDst.height()); height = desired; } } setMeasuredDimension(width, height); }
void updateDstRect() { if (mApplyGravity) { if (mIsCircular) { final int minDimen = Math.min(mBitmapWidth, mBitmapHeight); gravityCompatApply(mGravity, minDimen, minDimen, getBounds(), mDstRect); // inset the drawing rectangle to the largest contained square, // so that a circle will be drawn final int minDrawDimen = Math.min(mDstRect.width(), mDstRect.height()); final int insetX = Math.max(0, (mDstRect.width() - minDrawDimen) / 2); final int insetY = Math.max(0, (mDstRect.height() - minDrawDimen) / 2); mDstRect.inset(insetX, insetY); mCornerRadius = 0.5f * minDrawDimen; } else { gravityCompatApply(mGravity, mBitmapWidth, mBitmapHeight, getBounds(), mDstRect); } mDstRectF.set(mDstRect); if (mBitmapShader != null) { // setup shader matrix mShaderMatrix.setTranslate(mDstRectF.left, mDstRectF.top); mShaderMatrix.preScale( mDstRectF.width() / mBitmap.getWidth(), mDstRectF.height() / mBitmap.getHeight()); mBitmapShader.setLocalMatrix(mShaderMatrix); mPaint.setShader(mBitmapShader); } mApplyGravity = false; } }
/** * A factory method to build the appropriate LuminanceSource object based on the format of the * preview buffers, as described by Camera.Parameters. * * @param data A preview frame. * @param width The width of the image. * @param height The height of the image. * @return A PlanarYUVLuminanceSource instance. */ public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { Rect rect = getFramingRectInPreview(); int previewFormat = configManager.getPreviewFormat(); String previewFormatString = configManager.getPreviewFormatString(); switch (previewFormat) { // This is the standard Android format which all devices are REQUIRED to // support. // In theory, it's the only one we should ever care about. case PixelFormat.YCbCr_420_SP: // This format has never been seen in the wild, but is compatible as // we only care // about the Y channel, so allow it. case PixelFormat.YCbCr_422_SP: return new PlanarYUVLuminanceSource( data, width, height, rect.left, rect.top, rect.width(), rect.height()); default: // The Samsung Moment incorrectly uses this variant instead of the // 'sp' version. // Fortunately, it too has all the Y data up front, so we can read // it. if ("yuv420p".equals(previewFormatString)) { return new PlanarYUVLuminanceSource( data, width, height, rect.left, rect.top, rect.width(), rect.height()); } } throw new IllegalArgumentException( "Unsupported picture format: " + previewFormat + '/' + previewFormatString); }
@Override public void getItemOffsets(Rect outRect, View view, RecyclerView rv, RecyclerView.State state) { super.getItemOffsets(outRect, view, rv, state); debugLog("getItemOffsets"); debugLog("View top = " + view.getTop()); if (selectedDragItemPos != -1) { int itemPos = rv.getChildPosition(view); debugLog("itemPos =" + itemPos); if (!canDragOver(itemPos)) { return; } // Movement of finger float totalMovement = fingerY - fingerAnchorY; if (itemPos == selectedDragItemPos) { view.setVisibility(View.INVISIBLE); } else { // Make view visible incase invisible view.setVisibility(View.VISIBLE); // Find middle of the floatingItem float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height() / 2; // Moving down the list // These will auto-animate if the device continually sends touch motion events // if (totalMovment>0) { if ((itemPos > selectedDragItemPos) && (view.getTop() < floatMiddleY)) { float amountUp = (floatMiddleY - view.getTop()) / (float) view.getHeight(); // amountUp *= 0.5f; if (amountUp > 1) amountUp = 1; outRect.top = -(int) (floatingItemBounds.height() * amountUp); outRect.bottom = (int) (floatingItemBounds.height() * amountUp); } } // Moving up the list // else if (totalMovment < 0) { if ((itemPos < selectedDragItemPos) && (view.getBottom() > floatMiddleY)) { float amountDown = ((float) view.getBottom() - floatMiddleY) / (float) view.getHeight(); // amountDown *= 0.5f; if (amountDown > 1) amountDown = 1; outRect.top = (int) (floatingItemBounds.height() * amountDown); outRect.bottom = -(int) (floatingItemBounds.height() * amountDown); } } } } else { outRect.top = 0; outRect.bottom = 0; // Make view visible incase invisible view.setVisibility(View.VISIBLE); } }
private void calculateTextLocation() { if (mCenterPoint == null) return; double step = Math.PI / 6; double angle = -Math.PI / 3; float x, y; mPaint.setTextSize(mTextSize); mPaint.setTypeface(mTypeface); mPaint.setTextAlign(Paint.Align.CENTER); if (m24Hour) { for (int i = 0; i < 12; i++) { mPaint.getTextBounds(TICKS[i], 0, TICKS[i].length(), mRect); if (i == 0) mSecondInnerRadius = mInnerRadius - mSelectionRadius - mRect.height(); x = mCenterPoint.x + (float) Math.cos(angle) * mSecondInnerRadius; y = mCenterPoint.y + (float) Math.sin(angle) * mSecondInnerRadius; mLocations[i * 2] = x; mLocations[i * 2 + 1] = y + mRect.height() / 2f; angle += step; } for (int i = 12; i < TICKS.length; i++) { x = mCenterPoint.x + (float) Math.cos(angle) * mInnerRadius; y = mCenterPoint.y + (float) Math.sin(angle) * mInnerRadius; mPaint.getTextBounds(TICKS[i], 0, TICKS[i].length(), mRect); mLocations[i * 2] = x; mLocations[i * 2 + 1] = y + mRect.height() / 2f; angle += step; } } else { for (int i = 0; i < 12; i++) { x = mCenterPoint.x + (float) Math.cos(angle) * mInnerRadius; y = mCenterPoint.y + (float) Math.sin(angle) * mInnerRadius; mPaint.getTextBounds(TICKS[i], 0, TICKS[i].length(), mRect); mLocations[i * 2] = x; mLocations[i * 2 + 1] = y + mRect.height() / 2f; angle += step; } for (int i = 24; i < TICKS.length; i++) { x = mCenterPoint.x + (float) Math.cos(angle) * mInnerRadius; y = mCenterPoint.y + (float) Math.sin(angle) * mInnerRadius; mPaint.getTextBounds(TICKS[i], 0, TICKS[i].length(), mRect); mLocations[i * 2] = x; mLocations[i * 2 + 1] = y + mRect.height() / 2f; angle += step; } } }
/** 画面サイズから自位置を決定します。 */ private void updateViewLayout() { cancelAnimation(); // 前の画面座標を保存 final int oldScreenHeight = mMetrics.heightPixels; final int oldScreenWidth = mMetrics.widthPixels; final int oldPositionLimitWidth = mPositionLimitRect.width(); final int oldPositionLimitHeight = mPositionLimitRect.height(); // 新しい座標情報に切替 mWindowManager.getDefaultDisplay().getMetrics(mMetrics); final int width = getMeasuredWidth(); final int height = getMeasuredHeight(); final int newScreenWidth = mMetrics.widthPixels; final int newScreenHeight = mMetrics.heightPixels; // 移動範囲の設定 mMoveLimitRect.set(-width, -height * 2, newScreenWidth + width, newScreenHeight + height); mPositionLimitRect.set( -mOverMargin, 0, newScreenWidth - width + mOverMargin, newScreenHeight - mStatusBarHeight - height); // 縦横切替の場合 if (oldScreenWidth != newScreenWidth || oldScreenHeight != newScreenHeight) { // 画面端に移動する場合は現在の位置から左右端を設定 if (mMoveDirection == FloatingViewManager.MOVE_DIRECTION_DEFAULT) { // 右半分にある場合 if (mParams.x > (newScreenWidth - width) / 2) { mParams.x = mPositionLimitRect.right; } // 左半分にある場合 else { mParams.x = mPositionLimitRect.left; } } // 左端に移動 else if (mMoveDirection == FloatingViewManager.MOVE_DIRECTION_LEFT) { mParams.x = mPositionLimitRect.left; } // 右端に移動 else if (mMoveDirection == FloatingViewManager.MOVE_DIRECTION_RIGHT) { mParams.x = mPositionLimitRect.right; } // 画面端に移動しない場合は画面座標の比率から計算 else { final int newX = (int) (mParams.x * mPositionLimitRect.width() / (float) oldPositionLimitWidth + 0.5f); mParams.x = Math.min(Math.max(mPositionLimitRect.left, newX), mPositionLimitRect.right); } // スクリーン位置の比率からY座標を設定(四捨五入) final int newY = (int) (mParams.y * mPositionLimitRect.height() / (float) oldPositionLimitHeight + 0.5f); mParams.y = Math.min(Math.max(mPositionLimitRect.top, newY), mPositionLimitRect.bottom); mWindowManager.updateViewLayout(this, mParams); } }
/** * Compute the amount to scroll in the Y direction in order to get a rectangle completely on the * screen (or, if taller than the screen, at least the first screen size chunk of it). * * @param rect The rect. * @return The scroll delta. */ protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) { if (getChildCount() == 0) return 0; int height = getHeight(); int screenTop = getScrollY(); int screenBottom = screenTop + height; int fadingEdge = getVerticalFadingEdgeLength(); // leave room for top fading edge as long as rect isn't at very top if (rect.top > 0) { screenTop += fadingEdge; } // leave room for bottom fading edge as long as rect isn't at very // bottom if (rect.bottom < getChildAt(0).getHeight()) { screenBottom -= fadingEdge; } int scrollYDelta = 0; if (rect.bottom > screenBottom && rect.top > screenTop) { // need to move down to get it in view: move down just enough so // that the entire rectangle is in view (or at least the first // screen size chunk). if (rect.height() > height) { // just enough to get screen size chunk on scrollYDelta += (rect.top - screenTop); } else { // get entire rect at bottom of screen scrollYDelta += (rect.bottom - screenBottom); } // make sure we aren't scrolling beyond the end of our content int bottom = getChildAt(0).getBottom(); int distanceToBottom = bottom - screenBottom; scrollYDelta = Math.min(scrollYDelta, distanceToBottom); } else if (rect.top < screenTop && rect.bottom < screenBottom) { // need to move up to get it in view: move up just enough so that // entire rectangle is in view (or at least the first screen // size chunk of it). if (rect.height() > height) { // screen size chunk scrollYDelta -= (screenBottom - rect.bottom); } else { // entire rect at top scrollYDelta -= (screenTop - rect.top); } // make sure we aren't scrolling any further than the top our // content scrollYDelta = Math.max(scrollYDelta, -getScrollY()); } return scrollYDelta; }
// Rotates the bitmap by the specified degree. // If a new bitmap is created, the original bitmap is recycled. public static Bitmap rotateAndCrop(Bitmap b, int degrees, Rect crop) { if (b == null) return b; Bitmap b2 = null; int scale = Util.scalePow2(b.getHeight(), b.getWidth()); if (scale != 1 && crop != null) { crop.left *= scale; crop.right *= scale; crop.bottom *= scale; crop.top *= scale; } try { if (degrees != 0) { Matrix m = new Matrix(); m.setRotate(degrees, 0, 0); RectF r_rot = new RectF(0, 0, b.getWidth(), b.getHeight()); m.mapRect(r_rot); m.postTranslate(-r_rot.left, -r_rot.top); // r_rot.set(0,0,b.getWidth(),b.getHeight()); // m.mapRect(r_rot); // Log.d(TAG, "rotated bitmap = "+r_rot.toString()); if (crop == null) b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); else { Matrix minv = new Matrix(); m.invert(minv); // minv.postScale(scale, scale); RectF r = new RectF(); r.set(crop); minv.mapRect(r); Log.d(TAG, "crop = " + crop.toString()); r.round(crop); Log.d(TAG, "bitmap " + b.getDensity() + " " + b.getWidth() + " x " + b.getHeight()); Log.d(TAG, "inv rotated crop = " + crop.toString()); b2 = Bitmap.createBitmap(b, crop.left, crop.top, crop.width(), crop.height(), m, true); } } else { if (crop != null) { Log.d(TAG, "crop = " + crop.toString()); Log.d(TAG, "bitmap " + b.getDensity() + " " + b.getWidth() + " x " + b.getHeight()); b2 = Bitmap.createBitmap(b, crop.left, crop.top, crop.width(), crop.height()); // b2 = Bitmap.createBitmap(b, scale*crop.left, scale*crop.top, // scale*crop.width(), scale*crop.height()); } else b2 = b; } } catch (OutOfMemoryError ex) { // We have no memory to rotate. Return the original bitmap. b2 = b; } Assert.assertNotNull(b2); if (b == b2) { return b; } else { Log.d(TAG, "b != b2, recycling b"); b.recycle(); return b2; } }
private void drawQuery(Canvas canvas) { Rect bounds = getBounds(); int width = bounds.width(); float size = 0f; if (mRunState == RUN_STATE_STARTING) size = (float) mStrokeSize * Math.min(mInAnimationDuration, (SystemClock.uptimeMillis() - mLastRunStateTime)) / mInAnimationDuration; else if (mRunState == RUN_STATE_STOPPING) size = (float) mStrokeSize * Math.max( 0, (mOutAnimationDuration - SystemClock.uptimeMillis() + mLastRunStateTime)) / mOutAnimationDuration; else if (mRunState != RUN_STATE_STOPPED) size = mStrokeSize; if (size > 0) { float y = 0; switch (mVerticalAlign) { case ALIGN_TOP: y = size / 2; break; case ALIGN_CENTER: y = bounds.height() / 2f; break; case ALIGN_BOTTOM: y = bounds.height() - size / 2; break; } mPaint.setStrokeWidth(size); mPaint.setStyle(Paint.Style.STROKE); if (mProgressPercent != 1f) { mPaint.setColor(mStrokeSecondaryColor); canvas.drawLine(0, y, width, y, mPaint); if (mAnimTime < 1f) { float endLine = Math.max(0, Math.min(width, mStartLine + mLineWidth)); mPaint.setColor(getQueryStrokeColor()); drawLinePath(canvas, mStartLine, y, endLine, y, mPaint); } } if (mProgressPercent != 0f) { float lineWidth = width * mProgressPercent; mPaint.setColor(mStrokeColors[0]); if (mReverse) drawLinePath(canvas, width - lineWidth, y, width, y, mPaint); else drawLinePath(canvas, 0, y, lineWidth, y, mPaint); } } }
private void drawText(Canvas canvas, int i, String text, Paint p, boolean left) { Rect bounds = new Rect(); p.getTextBounds(text, 0, text.length(), bounds); float y = (float) (height / 2.0 - i * bounds.height() * 1.2) - (float) bounds.height() * 0.3f; if (left) canvas.drawText(text, (float) (-width / 2.0 + bounds.height() * .2f), y, p); else canvas.drawText(text, (float) (width / 2.0 - bounds.width() - bounds.height() * .2f), y, p); }
/** * 更新fouccusview的中心 * * @param x * @param y */ public void updateFouccusCenter(float x, float y, Rect rect) { // mFocus.setBackgroundColor(Color.WHITE); mFocus.setVisibility(View.VISIBLE); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); lp.width = rect.width(); lp.height = rect.height(); lp.leftMargin = (int) (x - rect.width() / 2); lp.topMargin = (int) (y - rect.height() / 2); setLayoutParams(lp); }
public void setWindowCaption(String caption) { windowCaption = caption; windowCaptionFrameCountdown = windowCaptionDelayFrames; captionPaint.setAlpha(255); captionPaint.getTextBounds(windowCaption, 0, windowCaption.length(), captionBounds); captionX = (surfaceWidth - captionBounds.width()) / 2f + captionBounds.left; captionY = (surfaceHeight - captionBounds.height()) / 2f + captionBounds.height() + captionBounds.top; }