Bug 1138495 - pt 3 - Compute font inflation based on inline-axis dimensions rather than always using physical width. r=smontagu

This commit is contained in:
Jonathan Kew 2015-03-10 14:28:23 +00:00
parent b2818a1915
commit eda6f033e5
7 changed files with 57 additions and 50 deletions

View File

@ -3187,7 +3187,7 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugin
}
static void
MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
MaybeReflowForInflationScreenSizeChange(nsPresContext *aPresContext)
{
if (aPresContext) {
nsIPresShell* presShell = aPresContext->GetPresShell();
@ -3196,7 +3196,7 @@ MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
bool changed = false;
if (presShell && presShell->FontSizeInflationEnabled() &&
presShell->FontSizeInflationMinTwips() != 0) {
aPresContext->ScreenWidthInchesForFontInflation(&changed);
aPresContext->ScreenSizeInchesForFontInflation(&changed);
}
changed = changed ||
@ -3254,7 +3254,7 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
// size also changes, we hook in the needed updates here rather
// than adding a separate notification just for this change.
nsPresContext* presContext = GetPresContext();
MaybeReflowForInflationScreenWidthChange(presContext);
MaybeReflowForInflationScreenSizeChange(presContext);
return NS_OK;
}

View File

@ -7171,7 +7171,8 @@ nsUnsetAttrRunnable::Run()
* width of the device**, the fonts satisfy our minima.
*/
static nscoord
MinimumFontSizeFor(nsPresContext* aPresContext, nscoord aContainerWidth)
MinimumFontSizeFor(nsPresContext* aPresContext, WritingMode aWritingMode,
nscoord aContainerISize)
{
nsIPresShell* presShell = aPresContext->PresShell();
@ -7182,20 +7183,23 @@ MinimumFontSizeFor(nsPresContext* aPresContext, nscoord aContainerWidth)
}
// Clamp the container width to the device dimensions
nscoord iFrameWidth = aPresContext->GetVisibleArea().width;
nscoord effectiveContainerWidth = std::min(iFrameWidth, aContainerWidth);
nscoord iFrameISize = aWritingMode.IsVertical()
? aPresContext->GetVisibleArea().height
: aPresContext->GetVisibleArea().width;
nscoord effectiveContainerISize = std::min(iFrameISize, aContainerISize);
nscoord byLine = 0, byInch = 0;
if (emPerLine != 0) {
byLine = effectiveContainerWidth / emPerLine;
byLine = effectiveContainerISize / emPerLine;
}
if (minTwips != 0) {
// REVIEW: Is this giving us app units and sizes *not* counting
// viewport scaling?
float deviceWidthInches =
aPresContext->ScreenWidthInchesForFontInflation();
byInch = NSToCoordRound(effectiveContainerWidth /
(deviceWidthInches * 1440 /
gfxSize screenSize = aPresContext->ScreenSizeInchesForFontInflation();
float deviceISizeInches = aWritingMode.IsVertical()
? screenSize.height : screenSize.width;
byInch = NSToCoordRound(effectiveContainerISize /
(deviceISizeInches * 1440 /
minTwips ));
}
return std::max(byLine, byInch);
@ -7343,7 +7347,8 @@ nsLayoutUtils::InflationMinFontSizeFor(const nsIFrame *aFrame)
}
return MinimumFontSizeFor(aFrame->PresContext(),
data->EffectiveWidth());
aFrame->GetWritingMode(),
data->EffectiveISize());
}
}

View File

@ -191,7 +191,8 @@ IsVisualCharset(const nsCString& aCharset)
nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
: mType(aType), mDocument(aDocument), mBaseMinFontSize(0),
mTextZoom(1.0), mFullZoom(1.0), mLastFontInflationScreenWidth(-1.0),
mTextZoom(1.0), mFullZoom(1.0),
mLastFontInflationScreenSize(gfxSize(-1.0, -1.0)),
mPageSize(-1, -1), mPPScale(1.0f),
mViewportStyleScrollbar(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
mImageAnimationModePref(imgIContainer::kNormalAnimMode),
@ -1505,8 +1506,8 @@ nsPresContext::SetFullZoom(float aZoom)
mSupressResizeReflow = false;
}
float
nsPresContext::ScreenWidthInchesForFontInflation(bool* aChanged)
gfxSize
nsPresContext::ScreenSizeInchesForFontInflation(bool* aChanged)
{
if (aChanged) {
*aChanged = false;
@ -1515,19 +1516,20 @@ nsPresContext::ScreenWidthInchesForFontInflation(bool* aChanged)
nsDeviceContext *dx = DeviceContext();
nsRect clientRect;
dx->GetClientRect(clientRect); // FIXME: GetClientRect looks expensive
float deviceWidthInches =
float(clientRect.width) / float(dx->AppUnitsPerPhysicalInch());
float unitsPerInch = dx->AppUnitsPerPhysicalInch();
gfxSize deviceSizeInches(float(clientRect.width) / unitsPerInch,
float(clientRect.height) / unitsPerInch);
if (mLastFontInflationScreenWidth == -1.0) {
mLastFontInflationScreenWidth = deviceWidthInches;
if (mLastFontInflationScreenSize == gfxSize(-1.0, -1.0)) {
mLastFontInflationScreenSize = deviceSizeInches;
}
if (deviceWidthInches != mLastFontInflationScreenWidth && aChanged) {
if (deviceSizeInches != mLastFontInflationScreenSize && aChanged) {
*aChanged = true;
mLastFontInflationScreenWidth = deviceWidthInches;
mLastFontInflationScreenSize = deviceSizeInches;
}
return deviceWidthInches;
return deviceSizeInches;
}
void

View File

@ -592,15 +592,15 @@ public:
}
/**
* Return the device's screen width in inches, for font size
* Return the device's screen size in inches, for font size
* inflation.
*
* If |aChanged| is non-null, then aChanged is filled in with whether
* the return value has changed since either:
* the screen size value has changed since either:
* a. the last time the function was called with non-null aChanged, or
* b. the first time the function was called.
*/
float ScreenWidthInchesForFontInflation(bool* aChanged = nullptr);
gfxSize ScreenSizeInchesForFontInflation(bool* aChanged = nullptr);
static int32_t AppUnitsPerCSSPixel() { return mozilla::AppUnitsPerCSSPixel(); }
int32_t AppUnitsPerDevPixel() const;
@ -1259,7 +1259,7 @@ protected:
float mTextZoom; // Text zoom, defaults to 1.0
float mFullZoom; // Page zoom, defaults to 1.0
float mLastFontInflationScreenWidth;
gfxSize mLastFontInflationScreenSize;
int32_t mCurAppUnitsPerDevPixel;
int32_t mAutoQualityMinFontSizePixelsPref;

View File

@ -32,7 +32,7 @@ nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame)
}
/* static */ bool
nsFontInflationData::UpdateFontInflationDataWidthFor(const nsHTMLReflowState& aReflowState)
nsFontInflationData::UpdateFontInflationDataISizeFor(const nsHTMLReflowState& aReflowState)
{
nsIFrame *bfc = aReflowState.frame;
NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
@ -41,24 +41,24 @@ nsFontInflationData::UpdateFontInflationDataWidthFor(const nsHTMLReflowState& aR
nsFontInflationData *data = static_cast<nsFontInflationData*>(
bfcProps.Get(FontInflationDataProperty()));
bool oldInflationEnabled;
nscoord oldNCAWidth;
nscoord oldNCAISize;
if (data) {
oldNCAWidth = data->mNCAWidth;
oldNCAISize = data->mNCAISize;
oldInflationEnabled = data->mInflationEnabled;
} else {
data = new nsFontInflationData(bfc);
bfcProps.Set(FontInflationDataProperty(), data);
oldNCAWidth = -1;
oldNCAISize = -1;
oldInflationEnabled = true; /* not relevant */
}
data->UpdateWidth(aReflowState);
data->UpdateISize(aReflowState);
if (oldInflationEnabled != data->mInflationEnabled)
return true;
return oldInflationEnabled &&
oldNCAWidth != data->mNCAWidth;
oldNCAISize != data->mNCAISize;
}
/* static */ void
@ -77,7 +77,7 @@ nsFontInflationData::MarkFontInflationDataTextDirty(nsIFrame *aBFCFrame)
nsFontInflationData::nsFontInflationData(nsIFrame *aBFCFrame)
: mBFCFrame(aBFCFrame)
, mNCAWidth(0)
, mNCAISize(0)
, mTextAmount(0)
, mTextThreshold(0)
, mInflationEnabled(false)
@ -124,12 +124,12 @@ NearestCommonAncestorFirstInFlow(nsIFrame *aFrame1, nsIFrame *aFrame2,
}
static nscoord
ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState,
ComputeDescendantISize(const nsHTMLReflowState& aAncestorReflowState,
nsIFrame *aDescendantFrame)
{
nsIFrame *ancestorFrame = aAncestorReflowState.frame->FirstInFlow();
if (aDescendantFrame == ancestorFrame) {
return aAncestorReflowState.ComputedWidth();
return aAncestorReflowState.ComputedISize();
}
AutoInfallibleTArray<nsIFrame*, 16> frames;
@ -138,7 +138,7 @@ ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState,
frames.AppendElement(f);
}
// This ignores the width contributions made by scrollbars, though in
// This ignores the inline-size contributions made by scrollbars, though in
// reality we don't have any scrollbars on the sorts of devices on
// which we use font inflation, so it's not a problem. But it may
// occasionally cause problems when writing tests on desktop.
@ -163,7 +163,7 @@ ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState,
MOZ_ASSERT(reflowStates[len - 1].frame == aDescendantFrame,
"bad logic in this function");
nscoord result = reflowStates[len - 1].ComputedWidth();
nscoord result = reflowStates[len - 1].ComputedISize();
for (uint32_t i = len; i-- != 0; ) {
reflowStates[i].~nsHTMLReflowState();
@ -174,7 +174,7 @@ ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState,
}
void
nsFontInflationData::UpdateWidth(const nsHTMLReflowState &aReflowState)
nsFontInflationData::UpdateISize(const nsHTMLReflowState &aReflowState)
{
nsIFrame *bfc = aReflowState.frame;
NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
@ -195,8 +195,8 @@ nsFontInflationData::UpdateWidth(const nsHTMLReflowState &aReflowState)
"null-ness should match; NearestCommonAncestorFirstInFlow"
" will crash when passed null");
// Particularly when we're computing for the root BFC, the width of
// nca might differ significantly for the width of bfc.
// Particularly when we're computing for the root BFC, the inline-size of
// nca might differ significantly for the inline-size of bfc.
nsIFrame *nca = NearestCommonAncestorFirstInFlow(firstInflatableDescendant,
lastInflatableDescendant,
bfc);
@ -204,13 +204,13 @@ nsFontInflationData::UpdateWidth(const nsHTMLReflowState &aReflowState)
nca = nca->GetParent()->FirstInFlow();
}
nscoord newNCAWidth = ComputeDescendantWidth(aReflowState, nca);
nscoord newNCAISize = ComputeDescendantISize(aReflowState, nca);
// See comment above "font.size.inflation.lineThreshold" in
// modules/libpref/src/init/all.js .
nsIPresShell* presShell = bfc->PresContext()->PresShell();
uint32_t lineThreshold = presShell->FontSizeInflationLineThreshold();
nscoord newTextThreshold = (newNCAWidth * lineThreshold) / 100;
nscoord newTextThreshold = (newNCAISize * lineThreshold) / 100;
if (mTextThreshold <= mTextAmount && mTextAmount < newTextThreshold) {
// Because we truncate our scan when we hit sufficient text, we now
@ -218,7 +218,7 @@ nsFontInflationData::UpdateWidth(const nsHTMLReflowState &aReflowState)
mTextDirty = true;
}
mNCAWidth = newNCAWidth;
mNCAISize = newNCAISize;
mTextThreshold = newTextThreshold;
mInflationEnabled = mTextAmount >= mTextThreshold;
}

View File

@ -21,7 +21,7 @@ public:
// Returns whether the effective width changed (which requires the
// caller to mark its descendants dirty
static bool
UpdateFontInflationDataWidthFor(const nsHTMLReflowState& aReflowState);
UpdateFontInflationDataISizeFor(const nsHTMLReflowState& aReflowState);
static void MarkFontInflationDataTextDirty(nsIFrame *aFrame);
@ -32,8 +32,8 @@ public:
return mInflationEnabled;
}
nscoord EffectiveWidth() const {
return mNCAWidth;
nscoord EffectiveISize() const {
return mNCAISize;
}
private:
@ -43,7 +43,7 @@ private:
nsFontInflationData(const nsFontInflationData&) = delete;
void operator=(const nsFontInflationData&) = delete;
void UpdateWidth(const nsHTMLReflowState &aReflowState);
void UpdateISize(const nsHTMLReflowState &aReflowState);
enum SearchDirection { eFromStart, eFromEnd };
static nsIFrame* FindEdgeInflatableFrameIn(nsIFrame *aFrame,
SearchDirection aDirection);
@ -52,7 +52,7 @@ private:
void ScanText();
// Scan text in the subtree rooted at aFrame. Increment mTextAmount
// by multiplying the number of characters found by the font size
// (yielding the width that would be occupied by the characters if
// (yielding the inline-size that would be occupied by the characters if
// they were all em squares). But stop scanning if mTextAmount
// crosses mTextThreshold.
void ScanTextIn(nsIFrame *aFrame);
@ -66,7 +66,7 @@ private:
}
nsIFrame *mBFCFrame;
nscoord mNCAWidth;
nscoord mNCAISize;
nscoord mTextAmount, mTextThreshold;
bool mInflationEnabled; // for this BFC
bool mTextDirty;

View File

@ -505,7 +505,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) {
// Create our font inflation data if we don't have it already, and
// give it our current width information.
bool dirty = nsFontInflationData::UpdateFontInflationDataWidthFor(*this) &&
bool dirty = nsFontInflationData::UpdateFontInflationDataISizeFor(*this) &&
// Avoid running this at the box-to-block interface
// (where we shouldn't be inflating anyway, and where
// reflow state construction is probably to construct a