Index: remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
index e6ae76baff7915e64059f84a2fa288be564d169e..20abd571d1fd58dc9c2c8a8109009da123ebba0f 100644 |
--- a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java |
@@ -11,36 +11,254 @@ import android.graphics.RectF; |
/** |
* This class is responsible for transforming the desktop image matrix. |
+ * |
+ * The transformation aspect is pretty simple, however the logic behind it is complex enough to |
+ * warrant a longer chunk of comments to explain how that is accomplished. |
+ * |
+ * ===== Coordinate Systems ===== |
+ * First, there are two coordinate spaces at play here, screen space and image space, which map to |
+ * coordinates on the device's screen and to the image used to display the remote desktop |
+ * respectively. We can convert from image coordinates to screen coordinates by using the transform |
+ * matrix held by |mRenderData| and convert from screen coordinates to image coordinates using the |
+ * inverse of that matrix. |
+ * |
+ * For consistency, position (viewport and cursor) member variables store padding in image space as |
+ * do the internal methods which modify them (unless otherwise noted). |
+ * |
+ * |
+ * ===== Viewport Concept ===== |
+ * Since the image used to display the remote desktop can be zoomed and panned such that only a |
+ * portion of it is displayed on screen, this class defines that viewable area as the "viewport". |
+ * A goal of this class is to ensure the viewport contains the maximum amount of image pixels as it |
+ * can. Thus it defines a subset of valid positions which map to the image, these are called |
+ * boundaries or bounds. When a caller shifts the viewport, the new coordinate is checked to ensure |
+ * it lies within the acceptable set of positions and is clamped to that viewable region if not. |
+ * The viewport is tracked and bound by its center position. |
+ * |
+ * As an example, let's say the image is height 1000px and the screen height is 800 (both in screen |
+ * coordinates). The viewport center would be located at 400px in this case and the viewport bounds |
+ * would range from 400px to 600px. At 400px, the top of the image would align with the top of the |
+ * screen and at 600px, the bottom of the image would align with the bottom of the screen. |
+ * |
+ * |
+ * ===== Cursor Position and Desired Viewport Concept ===== |
+ * Moving the viewport position is simple and works well for direct input methods, such as Touch, |
+ * however indirect methods, such as Trackpad mode, requires tracking of another position. This |
+ * second position can be thought of as the 'desired' viewport position and coincides with the |
+ * cursor position. It is called the desired position because it is the original position of the |
+ * viewport before the bounds are applied. This class attempts to keep the desired and actual |
+ * viewport centers at the same coordinate, however when the user can move the cursor to a position |
+ * which is outside of the allowed coordinates for the viewport (i.e. the edge of the screen). |
+ * We can't move the viewport center to that location without breaking our goal of maximizing the |
+ * viewable area of the screen, so instead we track the cursor position and begin shifting the |
+ * viewport again once the cursor moves back into the region of allowable viewport positions. |
+ * |
+ * |
+ * ===== Letterbox Padding ===== |
+ * One last note about the image and screen. When the image has been zoomed such that it is larger |
+ * than the screen, we are free to move the viewport around as described above. However once the |
+ * image is zoomed out such that one of the dimensions is smaller than the corresponding screen |
+ * dimension, we want to center the image within the viewport (and the screen). This is done by |
+ * adding conceptual padding to the edges of the screen. As an example, when the user zooms the |
+ * image out and the height of the image (say 799px) drops below the screen height (say 800px), we |
+ * will add 0.5px to the top and bottom edges of the image in our position calculations. As the |
+ * image height (in screen space) decreases (e.g. to 600px), the amount of padding will increase. |
+ * This ensures that the content is centered as the user zooms in and out. The same would occur |
+ * if the image width (in screen space) dropped below the screen width with padding being added to |
+ * the right and left edges of the image. This padding is referred to as "letterbox" padding. |
+ * Note that this padding is never applied to all four edges. The calculations used below allow one |
+ * image dimension to decrease below the screen dimension but it prevents additional attempts to |
+ * zoom out once the second image dimension matches the screen dimension. |
Lambros
2016/10/03 23:04:10
I'm still struggling to understand this exact conc
joedow
2016/10/04 20:47:47
Discussed offline. I've simplifed the code a bit
|
+ * |
+ * |
+ * ===== Viewport and System UI Concepts ===== |
+ * System UI is defined as pixels displayed by the operating system. For us this boils down to four |
+ * UI elements: status bar (located on the top edge of the screen), toolbar (located below the |
+ * status bar), navigation bar (located either at the bottom or right/left edge of the screen), and |
+ * the soft input method (docked to bottom of the screen, possibly above the navigation bar). |
+ * |
+ * Android has a mechanism to automatically resize the size of a UI View when System UI is displayed |
+ * or changes size however this causes a jarring repositioning effect. We use this mechanism in |
+ * Pre-KitKat versions of Android as there isn't much of a choice. On KitKat and later, we actually |
+ * position the desktop image in a layer below the System UI so we can display the image within the |
+ * viewport in a consistent fashion and avoid those jarring reposition effects that occur on older |
+ * OS versions. Though the experience is smoother, it also creates a new problem which is how do |
+ * users view and interact with remote UI elements on the image which are obscured by System UI. |
+ * |
+ * To address this problem, we allow the user to pan the remote image out from under the System UI. |
+ * Our goal is to keep the viewport location consistent regardless of the System UI state whenever |
+ * possible which leads to the following sections on padding and viewport position with System UI. |
+ * |
+ * |
+ * ===== System UI Padding ===== |
+ * In order to allow the user to pan the image out from under System UI, we need to know how much |
+ * space that UI occupies on the screen. This information is provided by the View whenever the size |
+ * changes. This information is applied to the viewport boundaries to allow the user to move the |
+ * viewport further in that direction than they could have previously. |
+ * |
+ * If we use the same sizes as before (image is 1000px and screen is 800px in screen coordinates), |
+ * the allowable viewport position values in the y axis are 400px through 600px. If System UI is |
+ * shown at the top and bottom of the screen (say 50px along both edges) then we need to adjust the |
+ * viewport to allow panning past that UI, the updated range of allowed values is 350px to 650px. |
+ * This adjustment allows the user to pan the desktop image out from under any System UI and fixes |
+ * the original problem. |
+ * |
+ * There are two caveats though. The first is how to handle the case when the System UI changes |
+ * size or disappears. The second is a complication due to letterbox padding. We'll address each |
+ * in their own sections. |
+ * |
+ * |
+ * ===== System UI and Letterbox Padding Overlap ===== |
+ * If we did not account for letterbox padding when adjusting the viewport bounds, the behavior |
+ * described in the System UI Padding section would fall apart when the image size (in screen space) |
+ * decreased below the screen size. The effect would be that the user could pan the desktop image |
+ * out from under the System UI (good) and then continue panning a distance defined by the amount of |
+ * letterbox padding added to that edge. Functionally this is OK, but visually it looks broken. We |
+ * address this problem by accounting for the overlap between the System UI and Letterbox padding. |
+ * |
+ * For this example, we will consider a single dimension (e.g. height) and assume a screen size of |
+ * 800px, an image size (once again in screen space) of 600px, letterbox padding on top and bottom |
+ * edges of 100px, and System UI at the top and bottom of the screen at 50px each. |
+ * |
+ * Without the System UI, the viewport center would be locked to 400px (the actual center of the |
+ * image + letterbox padding). When the System UI was displayed, the range would be changed by 50px |
+ * to 350px to 450px. This would allow the user to pan the image canvas by 50 px in either |
+ * direction. The problem here is that this panning is not useful as none of the image is obscured |
+ * by the System UI. Therefore we account for the letterbox padding and see that no scrolling is |
+ * required and keep the viewport locked at 400px. |
+ * |
+ * The previous example showed an example interaction between a small System UI and the viewport |
+ * bounds with letterbox padding, now let's consider a large System UI. In this example let's use |
+ * a Soft Input Method UI which is 400 px tall and anchored to the bottom of the screen. Using the |
+ * previous values (without letterboxing), the viewport range would be adjusted to 400px - 800px. |
+ * This allows the image to be fully seen by the user, but includes a 100px black edge between the |
+ * content and the System UI. What is needed is to account for the letterbox padding here as well. |
+ * We subtract the padding (100px) from the allowable range and end up with 400px - 700px. The |
Lambros
2016/10/03 23:04:10
Shouldn't this be 500px - 700px ?
joedow
2016/10/04 20:47:47
Comment block removed.
|
+ * image is fully visible and no letterbox padding is displayed. |
Lambros
2016/10/03 23:04:10
But the image isn't fully visible? It's 600px tall
joedow
2016/10/04 20:47:47
Comment block removed.
|
+ * |
+ * |
+ * ===== Image Padding and Ratcheting ===== |
+ * On to the problem of consistency. The sections above have solved the visibility problem, with |
+ * the methods described above, the image can always be viewed and all coordinates on the image can |
+ * be interacted with using the cursor or touch. So now we move on to the problem of handling the |
+ * boundaries when the System UI changes. |
+ * |
+ * First a description of the behavior we desire in this scenario. Let's say the user has panned |
+ * their image out from under the status and toolbar (~150px). When those UI elements are dismissed |
+ * we have two options, immediately trim the padding used for it and snap the viewport back to its |
+ * normal position or allow the viewport to remain until the extra padding is no longer required. |
Lambros
2016/10/03 23:04:10
"extra padding"? The amount of padding is *less* w
joedow
2016/10/04 20:47:47
N/A Comment block removed.
|
+ * We have chosen the second approach. |
+ * |
+ * The idea is that after the System UI has been dismissed, we allow the viewport to remain as-is, |
+ * but we don't want to keep this padding forever. The compromise is to 'eat' the unneeded padding |
+ * as the user pans the canvas, effectively creating a ratcheting effect. |
+ * |
+ * We accomplish this goal using a concept of image padding which tracks the actual amount of |
+ * padding in use for viewport calculations. In order to determine how much padding to use, we look |
+ * at the adjusted System UI padding, current image padding, and the number of visible pixels. |
Lambros
2016/10/03 23:04:10
I don't understand "visible pixels" or the differe
joedow
2016/10/04 20:47:47
Comment block removed.
|
+ * |
+ * More examples would be useful here. Instead of talking about a dimension, let's focus on a |
+ * single edge for this set of example scenarios. Everything starts with System UI being displayed, |
+ * otherwise there is no need for padding. The System UI for this example has already been adjusted |
Lambros
2016/10/03 23:04:10
"otherwise there is no need for padding"
But lette
joedow
2016/10/04 20:47:47
Comment block removed.
|
+ * to account for letterbox padding and totals 50px. |
+ * Note: The Visible Pixels are also adjusted to account for letterbox padding. |
+ * |
+ * Example: No padding is ever used in viewport calculations. |
+ * The user pans the image but never moves the image out from under the System UI. |
+ * Edge Calculation: System UI: 50px, Image Padding: 0px, Visible Pixels 0px |
+ * Edge Padding result: 0px |
+ * The System UI then disappears: |
+ * Edge Calculation: System UI: 0px, Image Padding: 0px, Visible Pixels 0px |
+ * Edge Padding result: 0px |
+ * |
+ * Example: Some padding is used in viewport calculations. |
+ * The user pans the image halfway out from under the System UI. |
+ * Edge Calculation: System UI: 50px, Image Padding: 0px, Visible Pixels 25px |
+ * Edge Padding result: 25px |
+ * The System UI then disappears (the viewport remains stationary): |
+ * Edge Calculation: System UI: 0px, Image Padding: 25px, Visible Pixels 25px |
+ * Edge Padding result: 25px |
+ * The user pans away from the edge a bit (say 10px): |
+ * Edge Calculation: System UI: 0px, Image Padding: 25px, Visible Pixels 15px |
+ * Edge Padding result: 15px |
+ * The user attempts to pan back toward the edge but cannot go past the 15px padding. |
+ * The user then pans 75px away from the edge: |
+ * Edge Calculation: System UI: 0px, Image Padding: 15px, Visible Pixels -75px |
+ * Edge Padding result: 0px |
+ * |
+ * |
+ * ===== Image Padding and Zooming ===== |
+ * In the previous section, the ratcheting mechanism was discussed which reduces the padding when |
+ * the user pans away from the edge of the screen. However what happens when a user zooms when |
+ * padding is applied? If the user is zooming in, then nothing is required as the image will be |
+ * expanded and the padding will be 'absorbed' by the ratcheting effect described previously. The |
+ * problem occurs when the user is zooming out. In that case, the edge of the image is not changed |
+ * and the effect looks odd (but is functionally OK). |
+ * |
+ * The solution to this problem is to reduce the amount of padding by a constant factor. This |
+ * reduction creates an easing effect as the position of the image slides toward the edge as the |
+ * padding is reduced. |
+ * |
+ * |
+ * ===== Image Padding and Cursors ===== |
+ * All of the problems and solutions above apply equally to Touch and Trackpad modes. However |
+ * Trackpad mode has two additional problems. |
+ * |
+ * The first is the problem of newly displayed System UI obscurring the cursor. Imagine you move |
+ * the cursor to the upper corner of the screen and then display the toolbar. The toolbar will be |
+ * displayed over the top of the cursor which is not a good idea. Our goal is to minimize screen |
+ * translations, but in this case, it is more important that the user does not lose sight of the |
+ * cursor. Thus we automatically move the viewport so the cursor is guaranteed to be visible. If |
+ * the cursor is centered on the screen, then no translation is needed. |
+ * |
+ * The second is also related to visibility but is not solved by the solution above. For this case, |
+ * let's assume the cursor is centered in the viewport. Next the user brings up the Soft Keyboard. |
+ * The Keyboard's height is near that of the screen center so the cursor is obscured. The user is |
+ * not able to see what they are interacting with and selecting a text box is impossible. For this |
+ * scenario, we artificially shift the 'screen center' position by viewport_size / 2. This ensures |
+ * the cursor is visible and the user can view and interact with any element on the remote desktop. |
+ * |
*/ |
public class DesktopCanvas { |
/** |
- * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}. |
+ * Maximum allowed zoom level - see {@link #scaleAndRepositionImage()}. |
*/ |
private static final float MAX_ZOOM_FACTOR = 100.0f; |
+ /** |
+ * Used to smoothly reduce the amount of padding while the user is zooming. |
+ */ |
+ private static final float PADDING_REDUCTION_FACTOR = 0.85f; |
+ |
private final RenderStub mRenderStub; |
private final RenderData mRenderData; |
/** |
- * Represents the actual center of the viewport. This value needs to be a pair of floats so the |
- * desktop image can be positioned with sub-pixel accuracy for smoother panning animations at |
- * high zoom levels. |
+ * Represents the actual center of the viewport in image space. This value needs to be a pair |
+ * of floats so the desktop image can be positioned with sub-pixel accuracy for smoother panning |
+ * animations at high zoom levels. |
*/ |
private PointF mViewportPosition = new PointF(); |
/** |
- * Represents the desired center of the viewport. This value may not represent the actual |
- * center of the viewport as adjustments are made to ensure as much of the desktop is visible as |
- * possible. This value needs to be a pair of floats so the desktop image can be positioned |
- * with sub-pixel accuracy for smoother panning animations at high zoom levels. |
+ * Represents the desired center of the viewport in image space. This value may not represent |
+ * the actual center of the viewport as adjustments are made to ensure as much of the desktop is |
+ * visible as possible. This value needs to be a pair of floats so the desktop image can be |
+ * positioned with sub-pixel accuracy for smoother panning animations at high zoom levels. |
*/ |
private PointF mCursorPosition = new PointF(); |
/** |
- * Represents the amount of space, in pixels, used by System UI. |
+ * Represents the amount of space, in screen pixels, used by System UI. |
*/ |
private Rect mSystemUiOffsetPixels = new Rect(); |
+ /** |
+ * Represents the additional space, in screen pixels, for each edge of the desktop image. |
+ * Used to allow the user to position the image canvas out from under any visible System UI. |
+ */ |
+ private RectF mImagePadding = new RectF(); |
+ |
public DesktopCanvas(RenderStub renderStub, RenderData renderData) { |
mRenderStub = renderStub; |
mRenderData = renderData; |
@@ -169,6 +387,16 @@ public class DesktopCanvas { |
mRenderData.transform.setScale(scale, scale); |
} |
+ // Trim the image padding if the user is zooming out. This prevents cases where the image |
+ // pops to the center when it reaches its minimum size. Note that we do not need to do |
+ // anything when the user is zooming in as the canvas will expand and absorb the padding. |
+ if (scaleFactor < 1.0f) { |
+ mImagePadding.set(mImagePadding.left * PADDING_REDUCTION_FACTOR, |
+ mImagePadding.top * PADDING_REDUCTION_FACTOR, |
+ mImagePadding.right * PADDING_REDUCTION_FACTOR, |
+ mImagePadding.bottom * PADDING_REDUCTION_FACTOR); |
+ } |
+ |
if (centerOnCursor) { |
setCursorPosition(mCursorPosition.x, mCursorPosition.y); |
} else { |
@@ -198,6 +426,8 @@ public class DesktopCanvas { |
// Translate the image so the viewport center is displayed in the middle of the screen. |
mRenderData.transform.postTranslate(viewportTransX, viewportTransY); |
+ adjustImagePadding(); |
+ |
mRenderStub.setTransformation(mRenderData.transform); |
} |
@@ -221,9 +451,24 @@ public class DesktopCanvas { |
} |
} |
- /** Returns a region which defines the set of valid cursor values in image space. */ |
+ /** Returns a region used to constrain the cursor position in image space. */ |
private RectF getImageBounds() { |
- return new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight); |
+ // Expand the allowable cursor positions to include any applicable padding (includes both |
+ // unused System UI padding and currently used image padding). Doing this allows the user |
+ // to move their cursor into this space to indicate they want to scroll it into the viewable |
+ // area. |
+ RectF systemUiOffsetPixels = getAdjustedSystemUiOffsets(); |
+ float[] paddingBuffer = {Math.max(mImagePadding.left, systemUiOffsetPixels.left), |
+ Math.max(mImagePadding.top, systemUiOffsetPixels.top), |
+ Math.max(mImagePadding.right, systemUiOffsetPixels.right), |
+ Math.max(mImagePadding.bottom, systemUiOffsetPixels.bottom)}; |
+ Matrix screenToImage = new Matrix(); |
+ mRenderData.transform.invert(screenToImage); |
+ screenToImage.mapVectors(paddingBuffer); |
+ |
+ return new RectF(-paddingBuffer[0], -paddingBuffer[1], |
+ mRenderData.imageWidth + paddingBuffer[2], |
+ mRenderData.imageHeight + paddingBuffer[3]); |
} |
/** Returns a region which defines the set of valid viewport center values in image space. */ |
@@ -233,23 +478,98 @@ public class DesktopCanvas { |
mRenderData.transform.invert(screenToImage); |
screenToImage.mapVectors(screenVectors); |
- float xAdjust = 0.0f; |
- if (mRenderData.imageWidth < screenVectors[0]) { |
- // Image is narrower than the screen, so adjust the bounds to center it. |
- xAdjust = (screenVectors[0] - mRenderData.imageWidth) / 2.0f; |
- } |
- |
- float yAdjust = 0.0f; |
- if (mRenderData.imageHeight < screenVectors[1]) { |
- // Image is shorter than the screen, so adjust the bounds to center it. |
- yAdjust = (screenVectors[1] - mRenderData.imageHeight) / 2.0f; |
- } |
+ PointF letterBoxPadding = getLetterboxPaddingOnScreen(); |
+ float[] letterBoxPaddingVectors = {letterBoxPadding.x, letterBoxPadding.y}; |
+ screenToImage.mapVectors(letterBoxPaddingVectors); |
// screenCenter values are 1/2 of a particular screen dimension mapped to image space. |
- float screenCenterX = screenVectors[0] / 2.0f; |
- float screenCenterY = screenVectors[1] / 2.0f; |
- return new RectF(screenCenterX - xAdjust, screenCenterY - yAdjust, |
- mRenderData.imageWidth - screenCenterX + xAdjust, |
- mRenderData.imageHeight - screenCenterY + yAdjust); |
+ float screenCenterX = (screenVectors[0] / 2.0f) - letterBoxPaddingVectors[0]; |
+ float screenCenterY = (screenVectors[1] / 2.0f) - letterBoxPaddingVectors[1]; |
+ RectF imageBounds = getImageBounds(); |
+ imageBounds.inset(screenCenterX, screenCenterY); |
+ return imageBounds; |
+ } |
+ |
+ /** Returns the letterbox padding needed in each dimension (x and y) in screen coordinates. */ |
+ private PointF getLetterboxPaddingOnScreen() { |
+ float[] imageVectors = {mRenderData.imageWidth, mRenderData.imageHeight}; |
+ mRenderData.transform.mapVectors(imageVectors); |
+ |
+ // We want to letterbox when the image is smaller than the screen in a specific dimension. |
+ // Since we center the image, split the difference so it is equally distributed. |
+ float widthAdjust = |
+ Math.max(0.0f, ((float) mRenderData.screenWidth - imageVectors[0]) / 2.0f); |
+ float heightAdjust = |
+ Math.max(0.0f, ((float) mRenderData.screenHeight - imageVectors[1]) / 2.0f); |
+ |
+ return new PointF(widthAdjust, heightAdjust); |
+ } |
+ |
+ /** |
+ * Returns the amount of System UI, adjusted for letterbox padding overlap, to use for padding. |
+ */ |
+ private RectF getAdjustedSystemUiOffsets() { |
+ // Ignore negative padding since that means no adjustment is necessary. We use a floor of |
+ // 0.0f to simplify calculations using the returned values. |
+ PointF letterBoxPadding = getLetterboxPaddingOnScreen(); |
+ return new RectF(Math.max(mSystemUiOffsetPixels.left - letterBoxPadding.x, 0.0f), |
+ Math.max(mSystemUiOffsetPixels.top - letterBoxPadding.y, 0.0f), |
+ Math.max(mSystemUiOffsetPixels.right - letterBoxPadding.x, 0.0f), |
+ Math.max(mSystemUiOffsetPixels.bottom - letterBoxPadding.y, 0.0f)); |
+ } |
+ |
+ /** |
+ * Updates the padding used to allow the user to scroll the image out from under System UI. |
+ * This is done by taking the adjusted System UI size, current padding, and visible pixels for |
+ * each edge of the screen. |
+ */ |
+ private void adjustImagePadding() { |
+ PointF letterBoxPadding = getLetterboxPaddingOnScreen(); |
+ RectF systemUiOffsetPixels = getAdjustedSystemUiOffsets(); |
+ float[] imagePoints = {0.0f, 0.0f, mRenderData.imageWidth, mRenderData.imageHeight}; |
+ mRenderData.transform.mapPoints(imagePoints); |
+ |
+ mImagePadding.set( |
+ adjustEdgePadding(systemUiOffsetPixels.left, mImagePadding.left, |
+ imagePoints[0] - letterBoxPadding.x), |
+ adjustEdgePadding(systemUiOffsetPixels.top, mImagePadding.top, |
+ imagePoints[1] - letterBoxPadding.y), |
+ adjustEdgePadding(systemUiOffsetPixels.right, mImagePadding.right, |
+ mRenderData.screenWidth - imagePoints[2] - letterBoxPadding.x), |
+ adjustEdgePadding(systemUiOffsetPixels.bottom, mImagePadding.bottom, |
+ mRenderData.screenHeight - imagePoints[3] - letterBoxPadding.y)); |
+ } |
+ |
+ /** |
+ * Update the current edge padding based on the current System UI and image position state. |
+ * |
+ * @param systemUiPadding Amount of visible System UI in pixels. |
+ * @param currentPadding Amount of padding used, in pixels, for position calculations. |
+ * @param visiblePixels Amount of padding actually visible, in pixels. |
+ * @return The new value, in pixels, to be used for positioning. |
+ */ |
+ private float adjustEdgePadding( |
+ float systemUiPadding, float currentPadding, float visiblePixels) { |
+ float edgeValue; |
+ visiblePixels = Math.max(visiblePixels, 0.0f); |
+ if (systemUiPadding > 0.0f) { |
+ if (systemUiPadding > currentPadding) { |
+ // Add enough padding to allow scrolling the desktop out from under the System UI. |
+ edgeValue = Math.min(systemUiPadding, visiblePixels); |
+ } else if (systemUiPadding < currentPadding) { |
+ // Remove unneeded padding from the canvas. |
+ edgeValue = Math.max(systemUiPadding, Math.min(currentPadding, visiblePixels)); |
+ } else { |
+ // If current and system padding sizes are the same, then keep the visible portion. |
+ edgeValue = Math.min(currentPadding, visiblePixels); |
+ } |
+ } else if (currentPadding > 0.0f) { |
+ // If we have existing padding, then trim if possible, otherwise keep the same value. |
+ edgeValue = Math.min(currentPadding, visiblePixels); |
+ } else { |
+ // Use zero padding if there is no system or current padding specified. |
+ edgeValue = 0.0f; |
+ } |
+ return edgeValue; |
} |
} |