From 8fce66a029e046bbc34331c3aa5da993145ea2b0 Mon Sep 17 00:00:00 2001 From: Scott Johnson Date: Tue, 2 Jul 2013 09:04:27 -0500 Subject: [PATCH] Bug 878931: Add a FontSizeInflation() method to Element in order to retrieve font size inflation to use during reflow-on-zoom. [r=kats,mounir] The reflow-on-zoom behavior needs a more robust determination of the font size inflation, so that it can adjust its behavior depending on whether font size inflation has been enabled for a given element's text. This patch also modifies the behavior of reflow- on-zoom such that it will zoom in to piece of text, with reflow, if the minimum specified font size in the font size inflation preferences is greater than the current font size, with font size inflation, of the element. --- content/base/public/Element.h | 16 +++++++++++++ content/base/src/Element.cpp | 15 ++++++++++++ dom/webidl/Element.webidl | 14 ++++++++++++ mobile/android/chrome/content/browser.js | 29 +++++++++++------------- modules/libpref/src/init/all.js | 8 ------- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/content/base/public/Element.h b/content/base/public/Element.h index 632f6a6d9428..0ff599699d76 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -922,6 +922,22 @@ public: */ NS_HIDDEN_(nsresult) SetBoolAttr(nsIAtom* aAttr, bool aValue); + /** + * Retrieve the ratio of font-size-inflated text font size to computed font + * size for this element. This will query the element for its primary frame, + * and then use this to get font size inflation information about the frame. + * + * @returns The font size inflation ratio (inflated font size to uninflated + * font size) for the primary frame of this element. Returns 1.0 + * by default if font size inflation is not enabled. Returns -1 + * if the element does not have a primary frame. + * + * @note The font size inflation ratio that is returned is actually the + * font size inflation data for the element's _primary frame_, not the + * element itself, but for most purposes, this should be sufficient. + */ + float FontSizeInflation(); + protected: /* * Named-bools for use with SetAttrAndNotify to make call sites easier to diff --git a/content/base/src/Element.cpp b/content/base/src/Element.cpp index a6350f0cec8b..dd9bf54e791f 100644 --- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -3432,3 +3432,18 @@ Element::SetBoolAttr(nsIAtom* aAttr, bool aValue) return UnsetAttr(kNameSpaceID_None, aAttr, true); } + +float +Element::FontSizeInflation() +{ + nsIFrame* frame = mPrimaryFrame; + if (!frame) { + return -1.0; + } + + if (nsLayoutUtils::FontSizeInflationEnabled(frame->PresContext())) { + return nsLayoutUtils::FontSizeInflationFor(frame); + } + + return 1.0; +} diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl index 6b589c378395..c7ea13b50321 100644 --- a/dom/webidl/Element.webidl +++ b/dom/webidl/Element.webidl @@ -68,6 +68,20 @@ interface Element : Node { [Pure] readonly attribute unsigned long childElementCount; + /** + * The ratio of font-size-inflated text font size to computed font + * size for this element. This will query the element for its primary frame, + * and then use this to get font size inflation information about the frame. + * This will be 1.0 if font size inflation is not enabled, and -1.0 if an + * error occurred during the retrieval of the font size inflation. + * + * @note The font size inflation ratio that is returned is actually the + * font size inflation data for the element's _primary frame_, not the + * element itself, but for most purposes, this should be sufficient. + */ + [ChromeOnly] + readonly attribute float fontSizeInflation; + // Mozilla specific stuff [SetterThrows,LenientThis] diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 35f7b0309de8..a3912e17aa73 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -181,11 +181,11 @@ function fuzzyEquals(a, b) { } /** - * Convert a font size from CSS pixels (px) to twenteiths-of-a-point + * Convert a font size to CSS pixels (px) from twentieiths-of-a-point * (twips). */ -function convertFromPxToTwips(aSize) { - return (20.0 * 12.0 * (aSize/16.0)); +function convertFromTwipsToPx(aSize) { + return aSize/240 * 16.0; } #ifdef MOZ_CRASHREPORTER @@ -2635,12 +2635,11 @@ Tab.prototype = { /** * Retrieves the font size in twips for a given element. */ - getFontSizeInTwipsFor: function(aElement) { + getInflatedFontSizeFor: function(aElement) { // GetComputedStyle should always give us CSS pixels for a font size. let fontSizeStr = this.window.getComputedStyle(aElement)['fontSize']; let fontSize = fontSizeStr.slice(0, -2); - // This is in px, so we want to convert it to points then to twips. - return convertFromPxToTwips(fontSize); + return aElement.fontSizeInflation * fontSize; }, /** @@ -2649,14 +2648,12 @@ Tab.prototype = { * preference. */ getZoomToMinFontSize: function(aElement) { - let currentZoom = this._zoom; - let minFontSize = Services.prefs.getIntPref("browser.zoom.reflowZoom.minFontSizeTwips"); - let curFontSize = this.getFontSizeInTwipsFor(aElement); - if (!fuzzyEquals(curFontSize*(currentZoom), minFontSize)) { - return 1.0 + minFontSize / curFontSize; - } - - return 1.0; + // We only use the font.size.inflation.minTwips preference because this is + // the only one that is controlled by the user-interface in the 'Settings' + // menu. Thus, if font.size.inflation.emPerLine is changed, this does not + // effect reflow-on-zoom. + let minFontSize = convertFromTwipsToPx(Services.prefs.getIntPref("font.size.inflation.minTwips")); + return minFontSize / this.getInflatedFontSizeFor(aElement); }, performReflowOnZoom: function(aViewport) { @@ -4237,8 +4234,8 @@ var BrowserEventHandler = { if (BrowserEventHandler.mReflozPref) { let zoomFactor = BrowserApp.selectedTab.getZoomToMinFontSize(aElement); - bRect.width = zoomFactor == 1.0 ? bRect.width : gScreenWidth / zoomFactor; - bRect.height = zoomFactor == 1.0 ? bRect.height : bRect.height / zoomFactor; + bRect.width = zoomFactor <= 1.0 ? bRect.width : gScreenWidth / zoomFactor; + bRect.height = zoomFactor <= 1.0 ? bRect.height : bRect.height / zoomFactor; if (zoomFactor == 1.0 || this._isRectZoomedIn(bRect, viewport)) { if (aCanZoomOut) { this._zoomOut(); diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index a42d3299a9c5..c453ebc6029f 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3912,14 +3912,6 @@ pref("browser.zoom.reflowZoom.reflowTimeout", 500); */ pref("browser.zoom.reflowZoom.reflowTextOnPageLoad", true); - -/** - * The minimum font size to maintain when double-tap zooming into an element, in - * twips. The browser will attempt to make the frame large enough to enlarge the - * font size to this value. - */ -pref("browser.zoom.reflowZoom.minFontSizeTwips", 120); - // Image-related prefs // The maximum size, in bytes, of the decoded images we cache pref("image.cache.size", 5242880);