зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b5d010b7b8
Коммит
133b9692b1
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче