gecko-dev/gfx/thebes/gfxGDIFontList.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1094 строки
36 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2012-05-21 15:12:37 +04:00
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/DebugOnly.h"
#include <algorithm>
#include "mozilla/Logging.h"
#include "mozilla/Sprintf.h"
#include "gfxGDIFontList.h"
#include "gfxWindowsPlatform.h"
#include "gfxUserFontSet.h"
#include "gfxFontUtils.h"
#include "gfxGDIFont.h"
#include "nsServiceManagerUtils.h"
#include "nsTArray.h"
#include "nsUnicharUtils.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsISimpleEnumerator.h"
#include "nsIWindowsRegKey.h"
#include "gfxFontConstants.h"
#include "GeckoProfiler.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Telemetry.h"
#include <usp10.h>
using namespace mozilla;
using namespace mozilla::gfx;
#define ROUND(x) floor((x) + 0.5)
#define LOG_FONTLIST(args) \
MOZ_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), LogLevel::Debug, args)
#define LOG_FONTLIST_ENABLED() \
MOZ_LOG_TEST(gfxPlatform::GetLog(eGfxLog_fontlist), LogLevel::Debug)
#define LOG_CMAPDATA_ENABLED() \
MOZ_LOG_TEST(gfxPlatform::GetLog(eGfxLog_cmapdata), LogLevel::Debug)
static __inline void BuildKeyNameFromFontName(nsAString& aName) {
if (aName.Length() >= LF_FACESIZE) aName.Truncate(LF_FACESIZE - 1);
ToLowerCase(aName);
}
// Implementation of gfxPlatformFontList for Win32 GDI,
// using GDI font enumeration APIs to get the list of fonts
class WinUserFontData : public gfxUserFontData {
public:
explicit WinUserFontData(HANDLE aFontRef) : mFontRef(aFontRef) {}
virtual ~WinUserFontData() {
DebugOnly<BOOL> success;
success = RemoveFontMemResourceEx(mFontRef);
#if DEBUG
if (!success) {
char buf[256];
SprintfLiteral(
buf,
"error deleting font handle (%p) - RemoveFontMemResourceEx failed",
mFontRef);
NS_ASSERTION(success, buf);
}
#endif
}
HANDLE mFontRef;
};
BYTE FontTypeToOutPrecision(uint8_t fontType) {
BYTE ret;
switch (fontType) {
case GFX_FONT_TYPE_TT_OPENTYPE:
case GFX_FONT_TYPE_TRUETYPE:
ret = OUT_TT_ONLY_PRECIS;
break;
case GFX_FONT_TYPE_PS_OPENTYPE:
ret = OUT_PS_ONLY_PRECIS;
break;
case GFX_FONT_TYPE_TYPE1:
ret = OUT_OUTLINE_PRECIS;
break;
case GFX_FONT_TYPE_RASTER:
ret = OUT_RASTER_PRECIS;
break;
case GFX_FONT_TYPE_DEVICE:
ret = OUT_DEVICE_PRECIS;
break;
default:
ret = OUT_DEFAULT_PRECIS;
}
return ret;
}
/***************************************************************
*
* GDIFontEntry
*
*/
GDIFontEntry::GDIFontEntry(const nsACString& aFaceName,
gfxWindowsFontType aFontType, SlantStyleRange aStyle,
WeightRange aWeight, StretchRange aStretch,
gfxUserFontData* aUserFontData)
: gfxFontEntry(aFaceName),
mFontType(aFontType),
mForceGDI(false),
mUnicodeRanges() {
mUserFontData.reset(aUserFontData);
mStyleRange = aStyle;
mWeightRange = aWeight;
mStretchRange = aStretch;
if (IsType1()) mForceGDI = true;
mIsDataUserFont = aUserFontData != nullptr;
InitLogFont(aFaceName, aFontType);
}
gfxFontEntry* GDIFontEntry::Clone() const {
MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!");
return new GDIFontEntry(Name(), mFontType, SlantStyle(), Weight(), Stretch(),
nullptr);
}
nsresult GDIFontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
AUTO_PROFILER_LABEL("GDIFontEntry::ReadCMAP", OTHER);
// attempt this once, if errors occur leave a blank cmap
if (mCharacterMap) {
return NS_OK;
}
// skip non-SFNT fonts completely
if (mFontType != GFX_FONT_TYPE_PS_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TT_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TRUETYPE) {
mCharacterMap = new gfxCharacterMap();
mCharacterMap->mBuildOnTheFly = true;
return NS_ERROR_FAILURE;
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<gfxCharacterMap> charmap;
nsresult rv;
if (aFontInfoData &&
(charmap = GetCMAPFromFontInfo(aFontInfoData, mUVSOffset))) {
rv = NS_OK;
} else {
uint32_t kCMAP = TRUETYPE_TAG('c', 'm', 'a', 'p');
charmap = new gfxCharacterMap();
AutoTArray<uint8_t, 16384> cmap;
rv = CopyFontTable(kCMAP, cmap);
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(), *charmap,
mUVSOffset);
}
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
// For fonts where we failed to read the character map,
// we can take a slow path to look up glyphs character by character
mCharacterMap->mBuildOnTheFly = true;
}
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
mName.get(), charmap->SizeOfIncludingThis(moz_malloc_size_of),
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
SprintfLiteral(prefix, "(cmapdata) name: %.220s", mName.get());
charmap->Dump(prefix, eGfxLog_cmapdata);
}
return rv;
}
Bug 1449605 - part 1 - Rearrange thebes font code so that the decision whether to apply synthetic-bold is deferred until actually instantiating a font, not made during the font-matching process. r=jwatt This rearranges how synthetic-bold use is determined in the font selection & rendering code. Previously, we would decide during the font-selection algorithm whether we need to apply synthetic-bold to the chosen face, and then pass that decision through the fontgroup (storing it in the FamilyFace entries of the mFonts array there) down to the actual rendering code that instantiates fonts from the faces (font entries) we've selected. That became a problem for variation fonts because in the case of a user font, we may not have downloaded the resource yet, so we just have a "user font container" entry, which carries the descriptors from the @font-face rule and will fetch the actual resource when needed. But in the case of a @font-face rule without a weight descriptor, we don't actually know at font-selection time whether the face will support "true" bold (via a variation axis) or not, so we can't reliably make the right decision about applying synthetic bold. So we now defer that decision until we actually instantiate a platform font object to shape/measure/draw text. At that point, we have the requested style and we also have the real font resource, so we can easily determine whether fake-bold is required. (This patch should not result in any visible behavior change; that will come in a second patch now that the architecture supports it.)
2018-05-01 12:30:50 +03:00
gfxFont* GDIFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle) {
return new gfxGDIFont(this, aFontStyle);
}
nsresult GDIFontEntry::CopyFontTable(uint32_t aTableTag,
nsTArray<uint8_t>& aBuffer) {
if (!IsTrueType()) {
return NS_ERROR_FAILURE;
}
AutoDC dc;
AutoSelectFont font(dc.GetDC(), &mLogFont);
if (font.IsValid()) {
uint32_t tableSize = ::GetFontData(
dc.GetDC(), NativeEndian::swapToBigEndian(aTableTag), 0, nullptr, 0);
if (tableSize != GDI_ERROR) {
if (aBuffer.SetLength(tableSize, fallible)) {
::GetFontData(dc.GetDC(), NativeEndian::swapToBigEndian(aTableTag), 0,
aBuffer.Elements(), tableSize);
return NS_OK;
}
return NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_ERROR_FAILURE;
}
already_AddRefed<UnscaledFontGDI> GDIFontEntry::LookupUnscaledFont(
HFONT aFont) {
RefPtr<UnscaledFontGDI> unscaledFont(mUnscaledFont);
if (!unscaledFont) {
LOGFONT lf;
GetObject(aFont, sizeof(LOGFONT), &lf);
unscaledFont = new UnscaledFontGDI(lf);
mUnscaledFont = unscaledFont;
}
return unscaledFont.forget();
}
void GDIFontEntry::FillLogFont(LOGFONTW* aLogFont, LONG aWeight,
gfxFloat aSize) {
memcpy(aLogFont, &mLogFont, sizeof(LOGFONTW));
aLogFont->lfHeight = (LONG)-ROUND(aSize);
if (aLogFont->lfHeight == 0) {
aLogFont->lfHeight = -1;
}
// If a non-zero weight is passed in, use this to override the original
// weight in the entry's logfont. This is used to control synthetic bolding
// for installed families with no bold face, and for downloaded fonts
// (but NOT for local user fonts, because it could cause a different,
// glyph-incompatible face to be used)
if (aWeight != 0) {
aLogFont->lfWeight = aWeight;
}
// for non-local() user fonts, we never want to apply italics here;
// if the face is described as italic, we should use it as-is,
// and if it's not, but then the element is styled italic, we'll use
// a cairo transform to create fake italic (oblique)
if (mIsDataUserFont) {
aLogFont->lfItalic = 0;
}
}
#define MISSING_GLYPH \
0x1F // glyph index returned for missing characters
// on WinXP with .fon fonts, but not Type1 (.pfb)
bool GDIFontEntry::TestCharacterMap(uint32_t aCh) {
if (!mCharacterMap) {
ReadCMAP();
NS_ASSERTION(mCharacterMap, "failed to initialize a character map");
}
if (mCharacterMap->mBuildOnTheFly) {
if (aCh > 0xFFFF) return false;
// previous code was using the group style
gfxFontStyle fakeStyle;
if (!IsUpright()) {
fakeStyle.style = FontSlantStyle::Italic();
}
fakeStyle.weight = Weight().Min();
RefPtr<gfxFont> tempFont = FindOrMakeFont(&fakeStyle, nullptr);
if (!tempFont || !tempFont->Valid()) return false;
gfxGDIFont* font = static_cast<gfxGDIFont*>(tempFont.get());
HDC dc = GetDC((HWND) nullptr);
SetGraphicsMode(dc, GM_ADVANCED);
HFONT hfont = font->GetHFONT();
HFONT oldFont = (HFONT)SelectObject(dc, hfont);
wchar_t str[1] = {(wchar_t)aCh};
WORD glyph[1];
bool hasGlyph = false;
// Bug 573038 - in some cases GetGlyphIndicesW returns 0xFFFF for a
// missing glyph or 0x1F in other cases to indicate the "invalid"
// glyph. Map both cases to "not found"
if (IsType1() || mForceGDI) {
// Type1 fonts and uniscribe APIs don't get along.
// ScriptGetCMap will return E_HANDLE
DWORD ret =
GetGlyphIndicesW(dc, str, 1, glyph, GGI_MARK_NONEXISTING_GLYPHS);
if (ret != GDI_ERROR && glyph[0] != 0xFFFF &&
(IsType1() || glyph[0] != MISSING_GLYPH)) {
hasGlyph = true;
}
} else {
// ScriptGetCMap works better than GetGlyphIndicesW
// for things like bitmap/vector fonts
SCRIPT_CACHE sc = nullptr;
HRESULT rv = ScriptGetCMap(dc, &sc, str, 1, 0, glyph);
if (rv == S_OK) hasGlyph = true;
}
SelectObject(dc, oldFont);
ReleaseDC(nullptr, dc);
if (hasGlyph) {
mCharacterMap->set(aCh);
return true;
}
} else {
// font had a cmap so simply check that
return mCharacterMap->test(aCh);
}
return false;
}
void GDIFontEntry::InitLogFont(const nsACString& aName,
gfxWindowsFontType aFontType) {
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
mLogFont.lfHeight = -1;
// Fill in logFont structure
mLogFont.lfWidth = 0;
mLogFont.lfEscapement = 0;
mLogFont.lfOrientation = 0;
mLogFont.lfUnderline = FALSE;
mLogFont.lfStrikeOut = FALSE;
mLogFont.lfCharSet = DEFAULT_CHARSET;
mLogFont.lfOutPrecision = FontTypeToOutPrecision(aFontType);
mLogFont.lfClipPrecision = CLIP_TURNOFF_FONTASSOCIATION;
mLogFont.lfQuality = DEFAULT_QUALITY;
mLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
// always force lfItalic if we want it. Font selection code will
// do its best to give us an italic font entry, but if no face exists
// it may give us a regular one based on weight. Windows should
// do fake italic for us in that case.
mLogFont.lfItalic = !IsUpright();
mLogFont.lfWeight = Weight().Min().ToIntRounded();
NS_ConvertUTF8toUTF16 name(aName);
int len = std::min<int>(name.Length(), LF_FACESIZE - 1);
memcpy(&mLogFont.lfFaceName, name.BeginReading(), len * sizeof(char16_t));
mLogFont.lfFaceName[len] = '\0';
}
GDIFontEntry* GDIFontEntry::CreateFontEntry(const nsACString& aName,
gfxWindowsFontType aFontType,
SlantStyleRange aStyle,
WeightRange aWeight,
StretchRange aStretch,
gfxUserFontData* aUserFontData) {
// jtdfix - need to set charset, unicode ranges, pitch/family
GDIFontEntry* fe = new GDIFontEntry(aName, aFontType, aStyle, aWeight,
aStretch, aUserFontData);
return fe;
}
void GDIFontEntry::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
aSizes->mFontListSize += aMallocSizeOf(this);
AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
}
/***************************************************************
*
* GDIFontFamily
*
*/
static bool ShouldIgnoreItalicStyle(const nsACString& aName) {
// Ignore italic style's "Meiryo" because "Meiryo (Bold) Italic" has
// non-italic style glyphs as Japanese characters. However, using it
// causes serious problem if web pages wants some elements to be
// different style from others only with font-style. For example,
// <em> and <i> should be rendered as italic in the default style.
return aName.EqualsLiteral("Meiryo") ||
aName.EqualsLiteral(
"\xe3\x83\xa1\xe3\x82\xa4\xe3\x83\xaa\xe3\x82\xaa");
}
int CALLBACK GDIFontFamily::FamilyAddStylesProc(
const ENUMLOGFONTEXW* lpelfe, const NEWTEXTMETRICEXW* nmetrics,
DWORD fontType, LPARAM data) {
const NEWTEXTMETRICW& metrics = nmetrics->ntmTm;
LOGFONTW logFont = lpelfe->elfLogFont;
GDIFontFamily* ff = reinterpret_cast<GDIFontFamily*>(data);
if (logFont.lfItalic && ShouldIgnoreItalicStyle(ff->mName)) {
return 1;
}
// Some fonts claim to support things > 900, but we don't so clamp the sizes
logFont.lfWeight = clamped(logFont.lfWeight, LONG(100), LONG(900));
gfxWindowsFontType feType =
GDIFontEntry::DetermineFontType(metrics, fontType);
GDIFontEntry* fe = nullptr;
for (uint32_t i = 0; i < ff->mAvailableFonts.Length(); ++i) {
fe = static_cast<GDIFontEntry*>(ff->mAvailableFonts[i].get());
if (feType > fe->mFontType) {
// if the new type is better than the old one, remove the old entries
ff->mAvailableFonts.RemoveElementAt(i);
--i;
} else if (feType < fe->mFontType) {
// otherwise if the new type is worse, skip it
return 1;
}
}
for (uint32_t i = 0; i < ff->mAvailableFonts.Length(); ++i) {
fe = static_cast<GDIFontEntry*>(ff->mAvailableFonts[i].get());
// check if we already know about this face
if (fe->Weight().Min() == FontWeight(int32_t(logFont.lfWeight)) &&
fe->IsItalic() == (logFont.lfItalic == 0xFF)) {
// update the charset bit here since this could be different
// XXX Can we still do this now that we store mCharset
// on the font family rather than the font entry?
ff->mCharset.set(metrics.tmCharSet);
return 1;
}
}
// We can't set the hasItalicFace flag correctly here,
// because we might not have seen the family's italic face(s) yet.
// So we'll set that flag for all members after loading all the faces.
auto italicStyle = (logFont.lfItalic == 0xFF ? FontSlantStyle::Italic()
: FontSlantStyle::Normal());
fe = GDIFontEntry::CreateFontEntry(
NS_ConvertUTF16toUTF8(lpelfe->elfFullName), feType,
SlantStyleRange(italicStyle),
WeightRange(FontWeight(int32_t(logFont.lfWeight))),
StretchRange(FontStretch::Normal()), nullptr);
if (!fe) return 1;
ff->AddFontEntry(fe);
if (nmetrics->ntmFontSig.fsUsb[0] != 0x00000000 &&
nmetrics->ntmFontSig.fsUsb[1] != 0x00000000 &&
nmetrics->ntmFontSig.fsUsb[2] != 0x00000000 &&
nmetrics->ntmFontSig.fsUsb[3] != 0x00000000) {
// set the unicode ranges
uint32_t x = 0;
for (uint32_t i = 0; i < 4; ++i) {
DWORD range = nmetrics->ntmFontSig.fsUsb[i];
for (uint32_t k = 0; k < 32; ++k) {
fe->mUnicodeRanges.set(x++, (range & (1 << k)) != 0);
}
}
}
if (LOG_FONTLIST_ENABLED()) {
LOG_FONTLIST(
("(fontlist) added (%s) to family (%s)"
" with style: %s weight: %d stretch: normal",
fe->Name().get(), ff->Name().get(),
(logFont.lfItalic == 0xff) ? "italic" : "normal", logFont.lfWeight));
}
return 1;
}
void GDIFontFamily::FindStyleVariations(FontInfoData* aFontInfoData) {
if (mHasStyles) return;
mHasStyles = true;
HDC hdc = GetDC(nullptr);
SetGraphicsMode(hdc, GM_ADVANCED);
LOGFONTW logFont;
memset(&logFont, 0, sizeof(LOGFONTW));
logFont.lfCharSet = DEFAULT_CHARSET;
logFont.lfPitchAndFamily = 0;
NS_ConvertUTF8toUTF16 name(mName);
uint32_t l = std::min<uint32_t>(name.Length(), LF_FACESIZE - 1);
memcpy(logFont.lfFaceName, name.get(), l * sizeof(char16_t));
EnumFontFamiliesExW(hdc, &logFont,
(FONTENUMPROCW)GDIFontFamily::FamilyAddStylesProc,
(LPARAM)this, 0);
if (LOG_FONTLIST_ENABLED() && mAvailableFonts.Length() == 0) {
LOG_FONTLIST(
("(fontlist) no styles available in family \"%s\"", mName.get()));
}
ReleaseDC(nullptr, hdc);
if (mIsBadUnderlineFamily) {
SetBadUnderlineFonts();
}
}
/***************************************************************
*
* gfxGDIFontList
*
*/
gfxGDIFontList::gfxGDIFontList() : mFontSubstitutes(32) {
#ifdef MOZ_BUNDLED_FONTS
ActivateBundledFonts();
#endif
}
static void RemoveCharsetFromFontSubstitute(nsAString& aName) {
int32_t comma = aName.FindChar(char16_t(','));
if (comma >= 0) aName.Truncate(comma);
}
#define MAX_VALUE_NAME 512
#define MAX_VALUE_DATA 512
nsresult gfxGDIFontList::GetFontSubstitutes() {
HKEY hKey;
DWORD i, rv, lenAlias, lenActual, valueType;
WCHAR aliasName[MAX_VALUE_NAME];
WCHAR actualName[MAX_VALUE_DATA];
if (RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes",
0, KEY_READ, &hKey) != ERROR_SUCCESS) {
return NS_ERROR_FAILURE;
}
for (i = 0, rv = ERROR_SUCCESS; rv != ERROR_NO_MORE_ITEMS; i++) {
aliasName[0] = 0;
lenAlias = ArrayLength(aliasName);
actualName[0] = 0;
lenActual = sizeof(actualName);
rv = RegEnumValueW(hKey, i, aliasName, &lenAlias, nullptr, &valueType,
(LPBYTE)actualName, &lenActual);
if (rv != ERROR_SUCCESS || valueType != REG_SZ || lenAlias == 0) {
continue;
}
if (aliasName[0] == WCHAR('@')) {
continue;
}
nsAutoString substituteName((char16_t*)aliasName);
nsAutoString actualFontName((char16_t*)actualName);
RemoveCharsetFromFontSubstitute(substituteName);
BuildKeyNameFromFontName(substituteName);
RemoveCharsetFromFontSubstitute(actualFontName);
BuildKeyNameFromFontName(actualFontName);
gfxFontFamily* ff;
NS_ConvertUTF16toUTF8 substitute(substituteName);
NS_ConvertUTF16toUTF8 actual(actualFontName);
if (!actual.IsEmpty() && (ff = mFontFamilies.GetWeak(actual))) {
mFontSubstitutes.Put(substitute, ff);
} else {
mNonExistingFonts.AppendElement(substitute);
}
}
// "Courier" on a default Windows install is an ugly bitmap font.
// If there is no substitution for Courier in the registry
// substitute "Courier" with "Courier New".
nsAutoString substituteName;
substituteName.AssignLiteral("Courier");
BuildKeyNameFromFontName(substituteName);
NS_ConvertUTF16toUTF8 substitute(substituteName);
if (!mFontSubstitutes.GetWeak(substitute)) {
gfxFontFamily* ff;
nsAutoString actualFontName;
actualFontName.AssignLiteral("Courier New");
BuildKeyNameFromFontName(actualFontName);
NS_ConvertUTF16toUTF8 actual(actualFontName);
ff = mFontFamilies.GetWeak(actual);
if (ff) {
mFontSubstitutes.Put(substitute, ff);
}
}
return NS_OK;
}
nsresult gfxGDIFontList::InitFontListForPlatform() {
Telemetry::AutoTimer<Telemetry::GDI_INITFONTLIST_TOTAL> timer;
mFontSubstitutes.Clear();
mNonExistingFonts.Clear();
// iterate over available families
LOGFONTW logfont;
memset(&logfont, 0, sizeof(logfont));
logfont.lfCharSet = DEFAULT_CHARSET;
AutoDC hdc;
(void)EnumFontFamiliesExW(hdc.GetDC(), &logfont,
(FONTENUMPROCW)&EnumFontFamExProc, 0, 0);
GetFontSubstitutes();
GetPrefsAndStartLoader();
return NS_OK;
}
int CALLBACK gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW* lpntme,
DWORD fontType, LPARAM lParam) {
const NEWTEXTMETRICW& metrics = lpntme->ntmTm;
const LOGFONTW& lf = lpelfe->elfLogFont;
if (lf.lfFaceName[0] == '@') {
return 1;
}
nsAutoString name(lf.lfFaceName);
BuildKeyNameFromFontName(name);
NS_ConvertUTF16toUTF8 key(name);
gfxGDIFontList* fontList = PlatformFontList();
if (!fontList->mFontFamilies.GetWeak(key)) {
NS_ConvertUTF16toUTF8 faceName(lf.lfFaceName);
RefPtr<GDIFontFamily> family = new GDIFontFamily(faceName);
fontList->mFontFamilies.Put(key, family);
// if locale is such that CJK font names are the default coming from
// GDI, then if a family name is non-ASCII immediately read in other
// family names. This assures that MS Gothic, MS Mincho are all found
// before lookups begin.
if (!IsASCII(faceName)) {
family->ReadOtherFamilyNames(gfxPlatformFontList::PlatformFontList());
}
if (fontList->mBadUnderlineFamilyNames.ContainsSorted(key)) {
family->SetBadUnderlineFamily();
}
family->mWindowsFamily = lf.lfPitchAndFamily & 0xF0;
family->mWindowsPitch = lf.lfPitchAndFamily & 0x0F;
// mark the charset bit
family->mCharset.set(metrics.tmCharSet);
}
return 1;
}
gfxFontEntry* gfxGDIFontList::LookupLocalFont(const nsACString& aFontName,
WeightRange aWeightForEntry,
StretchRange aStretchForEntry,
SlantStyleRange aStyleForEntry) {
gfxFontEntry* lookup;
lookup = LookupInFaceNameLists(aFontName);
if (!lookup) {
return nullptr;
}
bool isCFF = false; // jtdfix -- need to determine this
// use the face name from the lookup font entry, which will be the localized
// face name which GDI mapping tables use (e.g. with the system locale set to
// Dutch, a fullname of 'Arial Bold' will find a font entry with the face name
// 'Arial Vet' which can be used as a key in GDI font lookups).
GDIFontEntry* fe = GDIFontEntry::CreateFontEntry(
lookup->Name(),
gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE
: GFX_FONT_TYPE_TRUETYPE) /*type*/,
lookup->SlantStyle(), lookup->Weight(), aStretchForEntry, nullptr);
if (!fe) return nullptr;
fe->mIsLocalUserFont = true;
// make the new font entry match the userfont entry style characteristics
fe->mWeightRange = aWeightForEntry;
fe->mStyleRange = aStyleForEntry;
fe->mStretchRange = aStretchForEntry;
return fe;
}
// If aFontData contains only a MS/Symbol cmap subtable, not MS/Unicode,
// we modify the subtable header to mark it as Unicode instead, because
// otherwise GDI will refuse to load the font.
// NOTE that this function does not bounds-check every access to the font data.
// This is OK because we only use it on data that has already been validated
// by OTS, and therefore we will not hit out-of-bounds accesses here.
static bool FixupSymbolEncodedFont(uint8_t* aFontData, uint32_t aLength) {
struct CmapHeader {
AutoSwap_PRUint16 version;
AutoSwap_PRUint16 numTables;
};
struct CmapEncodingRecord {
AutoSwap_PRUint16 platformID;
AutoSwap_PRUint16 encodingID;
AutoSwap_PRUint32 offset;
};
const uint32_t kCMAP = TRUETYPE_TAG('c', 'm', 'a', 'p');
const TableDirEntry* dir = gfxFontUtils::FindTableDirEntry(aFontData, kCMAP);
if (dir && uint32_t(dir->length) >= sizeof(CmapHeader)) {
CmapHeader* cmap =
reinterpret_cast<CmapHeader*>(aFontData + uint32_t(dir->offset));
CmapEncodingRecord* encRec =
reinterpret_cast<CmapEncodingRecord*>(cmap + 1);
int32_t symbolSubtable = -1;
for (uint32_t i = 0; i < (uint16_t)cmap->numTables; ++i) {
if (uint16_t(encRec[i].platformID) !=
gfxFontUtils::PLATFORM_ID_MICROSOFT) {
continue; // only interested in MS platform
}
if (uint16_t(encRec[i].encodingID) ==
gfxFontUtils::ENCODING_ID_MICROSOFT_UNICODEBMP) {
// We've got a Microsoft/Unicode table, so don't interfere.
symbolSubtable = -1;
break;
}
if (uint16_t(encRec[i].encodingID) ==
gfxFontUtils::ENCODING_ID_MICROSOFT_SYMBOL) {
// Found a symbol subtable; remember it for possible fixup,
// but if we subsequently find a Microsoft/Unicode subtable,
// we'll cancel this.
symbolSubtable = i;
}
}
if (symbolSubtable != -1) {
// We found a windows/symbol cmap table, and no windows/unicode one;
// change the encoding ID so that AddFontMemResourceEx will accept it
encRec[symbolSubtable].encodingID =
gfxFontUtils::ENCODING_ID_MICROSOFT_UNICODEBMP;
return true;
}
}
return false;
}
gfxFontEntry* gfxGDIFontList::MakePlatformFont(const nsACString& aFontName,
WeightRange aWeightForEntry,
StretchRange aStretchForEntry,
SlantStyleRange aStyleForEntry,
const uint8_t* aFontData,
uint32_t aLength) {
// MakePlatformFont is responsible for deleting the font data with free
// so we set up a stack object to ensure it is freed even if we take an
// early exit
struct FontDataDeleter {
explicit FontDataDeleter(const uint8_t* aFontData) : mFontData(aFontData) {}
~FontDataDeleter() { free((void*)mFontData); }
const uint8_t* mFontData;
};
FontDataDeleter autoDelete(aFontData);
bool isCFF = gfxFontUtils::IsCffFont(aFontData);
nsresult rv;
HANDLE fontRef = nullptr;
nsAutoString uniqueName;
rv = gfxFontUtils::MakeUniqueUserFontName(uniqueName);
if (NS_FAILED(rv)) return nullptr;
FallibleTArray<uint8_t> newFontData;
rv = gfxFontUtils::RenameFont(uniqueName, aFontData, aLength, &newFontData);
if (NS_FAILED(rv)) return nullptr;
DWORD numFonts = 0;
uint8_t* fontData = reinterpret_cast<uint8_t*>(newFontData.Elements());
uint32_t fontLength = newFontData.Length();
NS_ASSERTION(fontData, "null font data after renaming");
// http://msdn.microsoft.com/en-us/library/ms533942(VS.85).aspx
// "A font that is added by AddFontMemResourceEx is always private
// to the process that made the call and is not enumerable."
fontRef =
AddFontMemResourceEx(fontData, fontLength, 0 /* reserved */, &numFonts);
if (!fontRef) {
if (FixupSymbolEncodedFont(fontData, fontLength)) {
fontRef = AddFontMemResourceEx(fontData, fontLength, 0, &numFonts);
}
}
if (!fontRef) {
return nullptr;
}
// only load fonts with a single face contained in the data
// AddFontMemResourceEx generates an additional face name for
// vertical text if the font supports vertical writing but since
// the font is referenced via the name this can be ignored
if (fontRef && numFonts > 2) {
RemoveFontMemResourceEx(fontRef);
return nullptr;
}
// make a new font entry using the unique name
WinUserFontData* winUserFontData = new WinUserFontData(fontRef);
GDIFontEntry* fe = GDIFontEntry::CreateFontEntry(
NS_ConvertUTF16toUTF8(uniqueName),
gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE
: GFX_FONT_TYPE_TRUETYPE) /*type*/,
aStyleForEntry, aWeightForEntry, aStretchForEntry, winUserFontData);
if (fe) {
fe->mIsDataUserFont = true;
}
return fe;
}
bool gfxGDIFontList::FindAndAddFamilies(StyleGenericFontFamily aGeneric,
const nsACString& aFamily,
nsTArray<FamilyAndGeneric>* aOutput,
FindFamiliesFlags aFlags,
gfxFontStyle* aStyle,
gfxFloat aDevToCssSize) {
NS_ConvertUTF8toUTF16 key16(aFamily);
BuildKeyNameFromFontName(key16);
NS_ConvertUTF16toUTF8 keyName(key16);
gfxFontFamily* ff = mFontSubstitutes.GetWeak(keyName);
if (ff) {
aOutput->AppendElement(FamilyAndGeneric(ff, aGeneric));
return true;
}
if (mNonExistingFonts.Contains(keyName)) {
return false;
}
return gfxPlatformFontList::FindAndAddFamilies(aGeneric, aFamily, aOutput,
aFlags, aStyle, aDevToCssSize);
}
FontFamily gfxGDIFontList::GetDefaultFontForPlatform(
const gfxFontStyle* aStyle) {
FontFamily ff;
// this really shouldn't fail to find a font....
NONCLIENTMETRICSW ncm;
ncm.cbSize = sizeof(ncm);
BOOL status =
::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
if (status) {
ff = FindFamily(NS_ConvertUTF16toUTF8(ncm.lfMessageFont.lfFaceName));
if (!ff.IsNull()) {
return ff;
}
}
// ...but just in case, try another (long-deprecated) approach as well
HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
LOGFONTW logFont;
if (hGDI && ::GetObjectW(hGDI, sizeof(logFont), &logFont)) {
ff = FindFamily(NS_ConvertUTF16toUTF8(logFont.lfFaceName));
}
return ff;
}
void gfxGDIFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
gfxPlatformFontList::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
aSizes->mFontListSize +=
SizeOfFontFamilyTableExcludingThis(mFontSubstitutes, aMallocSizeOf);
aSizes->mFontListSize +=
mNonExistingFonts.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (uint32_t i = 0; i < mNonExistingFonts.Length(); ++i) {
aSizes->mFontListSize +=
mNonExistingFonts[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
}
void gfxGDIFontList::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const {
aSizes->mFontListSize += aMallocSizeOf(this);
AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
}
// used to load system-wide font info on off-main thread
class GDIFontInfo : public FontInfoData {
public:
GDIFontInfo(bool aLoadOtherNames, bool aLoadFaceNames, bool aLoadCmaps)
: FontInfoData(aLoadOtherNames, aLoadFaceNames, aLoadCmaps) {}
virtual ~GDIFontInfo() = default;
virtual void Load() {
mHdc = GetDC(nullptr);
SetGraphicsMode(mHdc, GM_ADVANCED);
FontInfoData::Load();
ReleaseDC(nullptr, mHdc);
}
// loads font data for all members of a given family
virtual void LoadFontFamilyData(const nsACString& aFamilyName);
// callback for GDI EnumFontFamiliesExW call
static int CALLBACK EnumerateFontsForFamily(const ENUMLOGFONTEXW* lpelfe,
const NEWTEXTMETRICEXW* nmetrics,
DWORD fontType, LPARAM data);
HDC mHdc;
};
struct EnumerateFontsForFamilyData {
EnumerateFontsForFamilyData(const nsACString& aFamilyName,
GDIFontInfo& aFontInfo)
: mFamilyName(aFamilyName), mFontInfo(aFontInfo) {}
nsCString mFamilyName;
nsTArray<nsCString> mOtherFamilyNames;
GDIFontInfo& mFontInfo;
nsCString mPreviousFontName;
};
int CALLBACK GDIFontInfo::EnumerateFontsForFamily(
const ENUMLOGFONTEXW* lpelfe, const NEWTEXTMETRICEXW* nmetrics,
DWORD fontType, LPARAM data) {
EnumerateFontsForFamilyData* famData =
reinterpret_cast<EnumerateFontsForFamilyData*>(data);
HDC hdc = famData->mFontInfo.mHdc;
LOGFONTW logFont = lpelfe->elfLogFont;
const NEWTEXTMETRICW& metrics = nmetrics->ntmTm;
AutoSelectFont font(hdc, &logFont);
if (!font.IsValid()) {
return 1;
}
FontFaceData fontData;
NS_ConvertUTF16toUTF8 fontName(lpelfe->elfFullName);
// callback called for each style-charset so return if style already seen
if (fontName.Equals(famData->mPreviousFontName)) {
return 1;
}
famData->mPreviousFontName = fontName;
famData->mFontInfo.mLoadStats.fonts++;
// read name table info
bool nameDataLoaded = false;
if (famData->mFontInfo.mLoadFaceNames || famData->mFontInfo.mLoadOtherNames) {
uint32_t kNAME =
NativeEndian::swapToBigEndian(TRUETYPE_TAG('n', 'a', 'm', 'e'));
uint32_t nameSize;
AutoTArray<uint8_t, 1024> nameData;
nameSize = ::GetFontData(hdc, kNAME, 0, nullptr, 0);
if (nameSize != GDI_ERROR && nameSize > 0 &&
nameData.SetLength(nameSize, fallible)) {
::GetFontData(hdc, kNAME, 0, nameData.Elements(), nameSize);
// face names
if (famData->mFontInfo.mLoadFaceNames) {
gfxFontUtils::ReadCanonicalName((const char*)(nameData.Elements()),
nameSize, gfxFontUtils::NAME_ID_FULL,
fontData.mFullName);
gfxFontUtils::ReadCanonicalName(
(const char*)(nameData.Elements()), nameSize,
gfxFontUtils::NAME_ID_POSTSCRIPT, fontData.mPostscriptName);
nameDataLoaded = true;
famData->mFontInfo.mLoadStats.facenames++;
}
// other family names
if (famData->mFontInfo.mLoadOtherNames) {
gfxFontUtils::ReadOtherFamilyNamesForFace(
famData->mFamilyName, (const char*)(nameData.Elements()), nameSize,
famData->mOtherFamilyNames, false);
}
}
}
// read cmap
bool cmapLoaded = false;
gfxWindowsFontType feType =
GDIFontEntry::DetermineFontType(metrics, fontType);
if (famData->mFontInfo.mLoadCmaps && (feType == GFX_FONT_TYPE_PS_OPENTYPE ||
feType == GFX_FONT_TYPE_TT_OPENTYPE ||
feType == GFX_FONT_TYPE_TRUETYPE)) {
uint32_t kCMAP =
NativeEndian::swapToBigEndian(TRUETYPE_TAG('c', 'm', 'a', 'p'));
uint32_t cmapSize;
AutoTArray<uint8_t, 1024> cmapData;
cmapSize = ::GetFontData(hdc, kCMAP, 0, nullptr, 0);
if (cmapSize != GDI_ERROR && cmapSize > 0 &&
cmapData.SetLength(cmapSize, fallible)) {
::GetFontData(hdc, kCMAP, 0, cmapData.Elements(), cmapSize);
bool cmapLoaded = false;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
uint32_t offset;
if (NS_SUCCEEDED(gfxFontUtils::ReadCMAP(cmapData.Elements(), cmapSize,
*charmap, offset))) {
fontData.mCharacterMap = charmap;
fontData.mUVSOffset = offset;
cmapLoaded = true;
famData->mFontInfo.mLoadStats.cmaps++;
}
}
}
if (cmapLoaded || nameDataLoaded) {
famData->mFontInfo.mFontFaceData.Put(fontName, fontData);
}
return famData->mFontInfo.mCanceled ? 0 : 1;
}
void GDIFontInfo::LoadFontFamilyData(const nsACString& aFamilyName) {
// iterate over the family
LOGFONTW logFont;
memset(&logFont, 0, sizeof(LOGFONTW));
logFont.lfCharSet = DEFAULT_CHARSET;
logFont.lfPitchAndFamily = 0;
NS_ConvertUTF8toUTF16 name(aFamilyName);
uint32_t l = std::min<uint32_t>(name.Length(), LF_FACESIZE - 1);
memcpy(logFont.lfFaceName, name.BeginReading(), l * sizeof(char16_t));
EnumerateFontsForFamilyData data(aFamilyName, *this);
EnumFontFamiliesExW(mHdc, &logFont,
(FONTENUMPROCW)GDIFontInfo::EnumerateFontsForFamily,
(LPARAM)(&data), 0);
// if found other names, insert them
if (data.mOtherFamilyNames.Length() != 0) {
mOtherFamilyNames.Put(aFamilyName, data.mOtherFamilyNames);
mLoadStats.othernames += data.mOtherFamilyNames.Length();
}
}
already_AddRefed<FontInfoData> gfxGDIFontList::CreateFontInfoData() {
bool loadCmaps = !UsesSystemFallback() ||
gfxPlatform::GetPlatform()->UseCmapsDuringSystemFallback();
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<GDIFontInfo> fi =
new GDIFontInfo(true, NeedFullnamePostscriptNames(), loadCmaps);
return fi.forget();
}
gfxFontFamily* gfxGDIFontList::CreateFontFamily(const nsACString& aName) const {
return new GDIFontFamily(aName);
}
#ifdef MOZ_BUNDLED_FONTS
void gfxGDIFontList::ActivateBundledFonts() {
nsCOMPtr<nsIFile> localDir;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir));
if (NS_FAILED(rv)) {
return;
}
if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) {
return;
}
bool isDir;
if (NS_FAILED(localDir->IsDirectory(&isDir)) || !isDir) {
return;
}
nsCOMPtr<nsIDirectoryEnumerator> e;
rv = localDir->GetDirectoryEntries(getter_AddRefs(e));
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIFile> file;
while (NS_SUCCEEDED(e->GetNextFile(getter_AddRefs(file))) && file) {
nsAutoString path;
if (NS_FAILED(file->GetPath(path))) {
continue;
}
AddFontResourceExW(path.get(), FR_PRIVATE, nullptr);
}
}
#endif