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:
Karl Tomlinson 2013-05-02 15:04:20 +12:00
Родитель 58df2705ce
Коммит e26d21a276
1 изменённых файлов: 58 добавлений и 33 удалений

Просмотреть файл

@ -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