mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
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:
parent
b2818a1915
commit
eda6f033e5
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user