зеркало из https://github.com/mozilla/gecko-dev.git
b=810274 include bounds with layer pixels as possible destinations to minimize subpixel scrolls r=roc
--HG-- extra : transplant_source : a%E1S%03%CBB%D3%DE%DDn%96r%BC%B2%D6%7D%82%AB%EBv
This commit is contained in:
Родитель
58df2705ce
Коммит
e26d21a276
|
@ -46,6 +46,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
#include "nsSMILKeySpline.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
|
@ -1789,39 +1790,65 @@ void nsGfxScrollFrameInner::ScrollVisual(nsPoint aOldScrolledFramePos)
|
|||
}
|
||||
|
||||
/**
|
||||
* Return an appunit value close to aDesired and between aLower and aUpper
|
||||
* such that (aDesired - aCurrent)*aRes/aAppUnitsPerPixel is an integer (or
|
||||
* as close as we can get modulo rounding to appunits). If that
|
||||
* can't be done, just returns aDesired.
|
||||
* Clamp desired scroll position aDesired and range [aDestLower, aDestUpper]
|
||||
* to [aBoundLower, aBoundUpper] and then select the appunit value from among
|
||||
* aBoundLower, aBoundUpper and those such that (aDesired - aCurrent) *
|
||||
* aRes/aAppUnitsPerPixel is an integer (or as close as we can get
|
||||
* modulo rounding to appunits) that is in [aDestLower, aDestUpper] and
|
||||
* closest to aDesired. If no such value exists, return the nearest in
|
||||
* [aDestLower, aDestUpper].
|
||||
*/
|
||||
static nscoord
|
||||
AlignWithLayerPixels(nscoord aDesired, nscoord aLower,
|
||||
nscoord aUpper, nscoord aAppUnitsPerPixel,
|
||||
double aRes, nscoord aCurrent)
|
||||
ClampAndAlignWithPixels(nscoord aDesired,
|
||||
nscoord aBoundLower, nscoord aBoundUpper,
|
||||
nscoord aDestLower, nscoord aDestUpper,
|
||||
nscoord aAppUnitsPerPixel, double aRes,
|
||||
nscoord aCurrent)
|
||||
{
|
||||
// Intersect scroll range with allowed range, by clamping the ends
|
||||
// of aRange to be within bounds
|
||||
nscoord destLower = clamped(aDestLower, aBoundLower, aBoundUpper);
|
||||
nscoord destUpper = clamped(aDestUpper, aBoundLower, aBoundUpper);
|
||||
|
||||
nscoord desired = clamped(aDesired, destLower, destUpper);
|
||||
|
||||
double currentLayerVal = (aRes*aCurrent)/aAppUnitsPerPixel;
|
||||
double desiredLayerVal = (aRes*aDesired)/aAppUnitsPerPixel;
|
||||
double desiredLayerVal = (aRes*desired)/aAppUnitsPerPixel;
|
||||
double delta = desiredLayerVal - currentLayerVal;
|
||||
double nearestVal = NS_round(delta) + currentLayerVal;
|
||||
double nearestLayerVal = NS_round(delta) + currentLayerVal;
|
||||
|
||||
// Convert back from ThebesLayer space to appunits relative to the top-left
|
||||
// of the scrolled frame.
|
||||
nscoord nearestAppUnitVal =
|
||||
NSToCoordRoundWithClamp(nearestVal*aAppUnitsPerPixel/aRes);
|
||||
nscoord aligned =
|
||||
NSToCoordRoundWithClamp(nearestLayerVal*aAppUnitsPerPixel/aRes);
|
||||
|
||||
// Check if nearest layer pixel result fit into allowed and scroll range
|
||||
if (nearestAppUnitVal >= aLower && nearestAppUnitVal <= aUpper) {
|
||||
return nearestAppUnitVal;
|
||||
} else if (nearestVal != desiredLayerVal) {
|
||||
// Check if opposite pixel boundary fit into scroll range
|
||||
double oppositeVal = nearestVal + ((nearestVal < desiredLayerVal) ? 1 : -1);
|
||||
nscoord oppositeAppUnitVal =
|
||||
NSToCoordRoundWithClamp(oppositeVal*aAppUnitsPerPixel/aRes);
|
||||
if (oppositeAppUnitVal >= aLower && oppositeAppUnitVal <= aUpper) {
|
||||
return oppositeAppUnitVal;
|
||||
}
|
||||
// Use a bound if it is within the allowed range and closer to desired than
|
||||
// the nearest pixel-aligned value.
|
||||
if (aBoundUpper == destUpper &&
|
||||
static_cast<typeof(Abs(desired))>(aBoundUpper - desired) <
|
||||
Abs(desired - aligned))
|
||||
return aBoundUpper;
|
||||
|
||||
if (aBoundLower == destLower &&
|
||||
static_cast<typeof(Abs(desired))>(desired - aBoundLower) <
|
||||
Abs(aligned - desired))
|
||||
return aBoundLower;
|
||||
|
||||
// Accept the nearest pixel-aligned value if it is within the allowed range.
|
||||
if (aligned >= destLower && aligned <= destUpper)
|
||||
return aligned;
|
||||
|
||||
// Check if opposite pixel boundary fits into allowed range.
|
||||
double oppositeLayerVal =
|
||||
nearestLayerVal + ((nearestLayerVal < desiredLayerVal) ? 1.0 : -1.0);
|
||||
nscoord opposite =
|
||||
NSToCoordRoundWithClamp(oppositeLayerVal*aAppUnitsPerPixel/aRes);
|
||||
if (opposite >= destLower && opposite <= destUpper) {
|
||||
return opposite;
|
||||
}
|
||||
return aDesired;
|
||||
|
||||
// No alignment available.
|
||||
return desired;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1837,16 +1864,14 @@ ClampAndAlignWithLayerPixels(const nsPoint& aPt,
|
|||
nscoord aAppUnitsPerPixel,
|
||||
const gfxSize& aScale)
|
||||
{
|
||||
nsPoint pt = aBounds.ClampPoint(aPt);
|
||||
// Intersect scroll range with allowed range, by clamping the corners
|
||||
// of aRange to be within bounds
|
||||
nsPoint rangeTopLeft = aBounds.ClampPoint(aRange.TopLeft());
|
||||
nsPoint rangeBottomRight = aBounds.ClampPoint(aRange.BottomRight());
|
||||
|
||||
return nsPoint(AlignWithLayerPixels(pt.x, rangeTopLeft.x, rangeBottomRight.x,
|
||||
aAppUnitsPerPixel, aScale.width, aCurrent.x),
|
||||
AlignWithLayerPixels(pt.y, rangeTopLeft.y, rangeBottomRight.y,
|
||||
aAppUnitsPerPixel, aScale.height, aCurrent.y));
|
||||
return nsPoint(ClampAndAlignWithPixels(aPt.x, aBounds.x, aBounds.XMost(),
|
||||
aRange.x, aRange.XMost(),
|
||||
aAppUnitsPerPixel, aScale.width,
|
||||
aCurrent.x),
|
||||
ClampAndAlignWithPixels(aPt.y, aBounds.y, aBounds.YMost(),
|
||||
aRange.y, aRange.YMost(),
|
||||
aAppUnitsPerPixel, aScale.height,
|
||||
aCurrent.y));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
|
Загрузка…
Ссылка в новой задаче