Bug 1652561 - Refactor nsLookAndFeel::GetFontImpl() to prepare for remoting r=jmathies

Currently, this code creates large and non-trivial classes that will be
difficult to remote. This change creates an intermediate stage where a simple
struct is returned from a function and then used to initialize these
more complex classes.

It is this simple struct that will be remoted across processes

Differential Revision: https://phabricator.services.mozilla.com/D83405
This commit is contained in:
Chris Martin 2020-07-31 17:32:57 +00:00
Родитель b5d010b7b8
Коммит 133b9692b1
4 изменённых файлов: 140 добавлений и 81 удалений

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

@ -12,11 +12,13 @@
#include "nsDebug.h"
#include "nsColor.h"
#include "nsString.h"
#include "nsTArray.h"
struct gfxFontStyle;
struct LookAndFeelInt;
struct LookAndFeelFontInfo;
namespace mozilla {
@ -556,6 +558,14 @@ struct LookAndFeelInt {
int32_t value;
};
struct LookAndFeelFontInfo {
bool haveFont;
nsString fontName;
float pixelHeight;
bool italic;
bool bold;
};
// On the Mac, GetColor(ColorID::TextSelectForeground, color) returns this
// constant to specify that the foreground color should not be changed
// (ie. a colored text keeps its colors when selected).

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

@ -9,6 +9,7 @@
#include "nsStyleConsts.h"
#include "nsUXThemeData.h"
#include "nsUXThemeConstants.h"
#include "nsWindowsHelpers.h"
#include "WinUtils.h"
#include "mozilla/FontPropertyTypes.h"
#include "mozilla/Telemetry.h"
@ -629,65 +630,11 @@ nsresult nsLookAndFeel::GetFloatImpl(FloatID aID, float& aResult) {
return res;
}
static bool GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
nsString& aFontName, gfxFontStyle& aFontStyle) {
const LOGFONTW* ptrLogFont = nullptr;
LOGFONTW logFont;
NONCLIENTMETRICSW ncm;
char16_t name[LF_FACESIZE];
bool useShellDlg = false;
LookAndFeelFontInfo nsLookAndFeel::GetLookAndFeelFontInfoInternal(
const LOGFONTW& aLogFont, bool aUseShellDlg) {
LookAndFeelFontInfo result{};
// Depending on which stock font we want, there are a couple of
// places we might have to look it up.
switch (anID) {
case LookAndFeel::FontID::Icon:
if (!::SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(logFont),
(PVOID)&logFont, 0))
return false;
ptrLogFont = &logFont;
break;
default:
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm),
(PVOID)&ncm, 0))
return false;
switch (anID) {
case LookAndFeel::FontID::Menu:
case LookAndFeel::FontID::PullDownMenu:
ptrLogFont = &ncm.lfMenuFont;
break;
case LookAndFeel::FontID::Caption:
ptrLogFont = &ncm.lfCaptionFont;
break;
case LookAndFeel::FontID::SmallCaption:
ptrLogFont = &ncm.lfSmCaptionFont;
break;
case LookAndFeel::FontID::StatusBar:
case LookAndFeel::FontID::Tooltips:
ptrLogFont = &ncm.lfStatusFont;
break;
case LookAndFeel::FontID::Widget:
case LookAndFeel::FontID::Dialog:
case LookAndFeel::FontID::Button:
case LookAndFeel::FontID::Field:
case LookAndFeel::FontID::List:
// XXX It's not clear to me whether this is exactly the right
// set of LookAndFeel values to map to the dialog font; we may
// want to add or remove cases here after reviewing the visual
// results under various Windows versions.
useShellDlg = true;
// Fall through so that we can get size from lfMessageFont;
// but later we'll use the (virtual) "MS Shell Dlg 2" font name
// instead of the LOGFONT's.
default:
ptrLogFont = &ncm.lfMessageFont;
break;
}
break;
}
result.haveFont = false;
// Get scaling factor from physical to logical pixels
double pixelScale = 1.0 / WinUtils::SystemScaleFactor();
@ -702,47 +649,129 @@ static bool GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
// scale factor is 125% or 150% or even more), and could be
// any value when going to a printer, for example pixelScale is
// 6.25 when going to a 600dpi printer.
float pixelHeight = -ptrLogFont->lfHeight;
float pixelHeight = -aLogFont.lfHeight;
if (pixelHeight < 0) {
HFONT hFont = ::CreateFontIndirectW(ptrLogFont);
if (!hFont) return false;
HGDIOBJ hObject = ::SelectObject(aHDC, hFont);
nsAutoFont hFont(::CreateFontIndirectW(&aLogFont));
if (!hFont) {
return result;
}
nsAutoHDC dc(::GetDC(nullptr));
HGDIOBJ hObject = ::SelectObject(dc, hFont);
TEXTMETRIC tm;
::GetTextMetrics(aHDC, &tm);
::SelectObject(aHDC, hObject);
::DeleteObject(hFont);
::GetTextMetrics(dc, &tm);
::SelectObject(dc, hObject);
pixelHeight = tm.tmAscent;
}
pixelHeight *= pixelScale;
// we have problem on Simplified Chinese system because the system
// report the default font size is 8 points. but if we use 8, the text
// display very ugly. force it to be at 9 points (12 pixels) on that
// system (cp936), but leave other sizes alone.
if (pixelHeight < 12 && ::GetACP() == 936) pixelHeight = 12;
if (pixelHeight < 12 && ::GetACP() == 936) {
pixelHeight = 12;
}
aFontStyle.size = pixelHeight;
result.haveFont = true;
if (aUseShellDlg) {
result.fontName = u"MS Shell Dlg 2"_ns;
} else {
result.fontName = aLogFont.lfFaceName;
}
result.pixelHeight = pixelHeight;
result.italic = !!aLogFont.lfItalic;
result.bold = (aLogFont.lfWeight == FW_BOLD);
return result;
}
LookAndFeelFontInfo nsLookAndFeel::GetLookAndFeelFontInfo(
LookAndFeel::FontID anID) {
LookAndFeelFontInfo result{};
result.haveFont = false;
// FontID::Icon is handled differently than the others
if (anID == LookAndFeel::FontID::Icon) {
LOGFONTW logFont;
if (::SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(logFont),
(PVOID)&logFont, 0)) {
result = GetLookAndFeelFontInfoInternal(logFont, false);
}
return result;
}
NONCLIENTMETRICSW ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm),
(PVOID)&ncm, 0)) {
return result;
}
switch (anID) {
case LookAndFeel::FontID::Menu:
case LookAndFeel::FontID::PullDownMenu:
result = GetLookAndFeelFontInfoInternal(ncm.lfMenuFont, false);
break;
case LookAndFeel::FontID::Caption:
result = GetLookAndFeelFontInfoInternal(ncm.lfCaptionFont, false);
break;
case LookAndFeel::FontID::SmallCaption:
result = GetLookAndFeelFontInfoInternal(ncm.lfSmCaptionFont, false);
break;
case LookAndFeel::FontID::StatusBar:
case LookAndFeel::FontID::Tooltips:
result = GetLookAndFeelFontInfoInternal(ncm.lfStatusFont, false);
break;
case LookAndFeel::FontID::Widget:
case LookAndFeel::FontID::Dialog:
case LookAndFeel::FontID::Button:
case LookAndFeel::FontID::Field:
case LookAndFeel::FontID::List:
// XXX It's not clear to me whether this is exactly the right
// set of LookAndFeel values to map to the dialog font; we may
// want to add or remove cases here after reviewing the visual
// results under various Windows versions.
result = GetLookAndFeelFontInfoInternal(ncm.lfMessageFont, true);
break;
default:
result = GetLookAndFeelFontInfoInternal(ncm.lfMessageFont, false);
break;
}
return result;
}
bool nsLookAndFeel::GetSysFontInfo(LookAndFeel::FontID anID,
nsString& aFontName,
gfxFontStyle& aFontStyle) {
LookAndFeelFontInfo fontInfo = GetLookAndFeelFontInfo(anID);
if (!fontInfo.haveFont) {
return false;
}
aFontName = std::move(fontInfo.fontName);
aFontStyle.size = fontInfo.pixelHeight;
// FIXME: What about oblique?
aFontStyle.style = (ptrLogFont->lfItalic) ? FontSlantStyle::Italic()
: FontSlantStyle::Normal();
aFontStyle.style =
fontInfo.italic ? FontSlantStyle::Italic() : FontSlantStyle::Normal();
// FIXME: Other weights?
aFontStyle.weight = (ptrLogFont->lfWeight == FW_BOLD ? FontWeight::Bold()
: FontWeight::Normal());
aFontStyle.weight = fontInfo.bold ? FontWeight::Bold() : FontWeight::Normal();
// FIXME: Set aFontStyle->stretch correctly!
aFontStyle.stretch = FontStretch::Normal();
aFontStyle.systemFont = true;
if (useShellDlg) {
aFontName = u"MS Shell Dlg 2"_ns;
} else {
memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE * sizeof(char16_t));
aFontName = name;
}
return true;
}
@ -758,9 +787,7 @@ bool nsLookAndFeel::GetFontImpl(FontID anID, nsString& aFontName,
aFontStyle = cacheSlot.mFontStyle;
}
} else {
HDC tdc = GetDC(nullptr);
status = GetSysFontInfo(tdc, anID, aFontName, aFontStyle);
ReleaseDC(nullptr, tdc);
status = GetSysFontInfo(anID, aFontName, aFontStyle);
cacheSlot.mCacheValid = true;
cacheSlot.mHaveFont = status;

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

@ -81,6 +81,14 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
nscolor GetColorForSysColorIndex(int index);
LookAndFeelFontInfo GetLookAndFeelFontInfoInternal(const LOGFONTW& aLogFont,
bool aUseShellDlg);
LookAndFeelFontInfo GetLookAndFeelFontInfo(LookAndFeel::FontID anID);
bool GetSysFontInfo(LookAndFeel::FontID anID, nsString& aFontName,
gfxFontStyle& aFontStyle);
// Content process cached values that get shipped over from the browser
// process.
int32_t mUseAccessibilityTheme;

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

@ -57,6 +57,19 @@ class nsAutoRefTraits<HDC> {
}
};
template <>
class nsAutoRefTraits<HFONT> {
public:
typedef HFONT RawRef;
static HFONT Void() { return nullptr; }
static void Release(RawRef aFD) {
if (aFD != Void()) {
::DeleteObject(aFD);
}
}
};
template <>
class nsAutoRefTraits<HBRUSH> {
public:
@ -214,6 +227,7 @@ class nsAutoRefTraits<nsHPRINTER> {
typedef nsAutoRef<HKEY> nsAutoRegKey;
typedef nsAutoRef<HDC> nsAutoHDC;
typedef nsAutoRef<HFONT> nsAutoFont;
typedef nsAutoRef<HBRUSH> nsAutoBrush;
typedef nsAutoRef<HRGN> nsAutoRegion;
typedef nsAutoRef<HBITMAP> nsAutoBitmap;