mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
f5cf8c125c
--HG-- rename : gfx/thebes/src/GLContext.cpp => gfx/thebes/GLContext.cpp rename : gfx/thebes/public/GLContext.h => gfx/thebes/GLContext.h rename : gfx/thebes/public/GLContextProvider.h => gfx/thebes/GLContextProvider.h rename : gfx/thebes/src/GLContextProviderCGL.mm => gfx/thebes/GLContextProviderCGL.mm rename : gfx/thebes/src/GLContextProviderEGL.cpp => gfx/thebes/GLContextProviderEGL.cpp rename : gfx/thebes/src/GLContextProviderGLX.cpp => gfx/thebes/GLContextProviderGLX.cpp rename : gfx/thebes/src/GLContextProviderNull.cpp => gfx/thebes/GLContextProviderNull.cpp rename : gfx/thebes/src/GLContextProviderOSMesa.cpp => gfx/thebes/GLContextProviderOSMesa.cpp rename : gfx/thebes/src/GLContextProviderWGL.cpp => gfx/thebes/GLContextProviderWGL.cpp rename : gfx/thebes/public/GLDefs.h => gfx/thebes/GLDefs.h rename : gfx/thebes/public/GLXLibrary.h => gfx/thebes/GLXLibrary.h rename : gfx/thebes/public/WGLLibrary.h => gfx/thebes/WGLLibrary.h rename : gfx/thebes/src/cairo-gdk-utils.c => gfx/thebes/cairo-gdk-utils.c rename : gfx/thebes/src/cairo-gdk-utils.h => gfx/thebes/cairo-gdk-utils.h rename : gfx/thebes/src/cairo-xlib-utils.c => gfx/thebes/cairo-xlib-utils.c rename : gfx/thebes/src/cairo-xlib-utils.h => gfx/thebes/cairo-xlib-utils.h rename : gfx/thebes/src/genUnicodeScriptData.pl => gfx/thebes/genUnicodeScriptData.pl rename : gfx/thebes/public/gfx3DMatrix.h => gfx/thebes/gfx3DMatrix.h rename : gfx/thebes/src/gfxASurface.cpp => gfx/thebes/gfxASurface.cpp rename : gfx/thebes/public/gfxASurface.h => gfx/thebes/gfxASurface.h rename : gfx/thebes/src/gfxAlphaRecovery.cpp => gfx/thebes/gfxAlphaRecovery.cpp rename : gfx/thebes/public/gfxAlphaRecovery.h => gfx/thebes/gfxAlphaRecovery.h rename : gfx/thebes/src/gfxAndroidPlatform.cpp => gfx/thebes/gfxAndroidPlatform.cpp rename : gfx/thebes/public/gfxAndroidPlatform.h => gfx/thebes/gfxAndroidPlatform.h rename : gfx/thebes/src/gfxAtomList.h => gfx/thebes/gfxAtomList.h rename : gfx/thebes/src/gfxAtoms.cpp => gfx/thebes/gfxAtoms.cpp rename : gfx/thebes/src/gfxAtoms.h => gfx/thebes/gfxAtoms.h rename : gfx/thebes/src/gfxBeOSPlatform.cpp => gfx/thebes/gfxBeOSPlatform.cpp rename : gfx/thebes/public/gfxBeOSPlatform.h => gfx/thebes/gfxBeOSPlatform.h rename : gfx/thebes/src/gfxBeOSSurface.cpp => gfx/thebes/gfxBeOSSurface.cpp rename : gfx/thebes/public/gfxBeOSSurface.h => gfx/thebes/gfxBeOSSurface.h rename : gfx/thebes/public/gfxColor.h => gfx/thebes/gfxColor.h rename : gfx/thebes/src/gfxContext.cpp => gfx/thebes/gfxContext.cpp rename : gfx/thebes/public/gfxContext.h => gfx/thebes/gfxContext.h rename : gfx/thebes/src/gfxCoreTextShaper.cpp => gfx/thebes/gfxCoreTextShaper.cpp rename : gfx/thebes/src/gfxCoreTextShaper.h => gfx/thebes/gfxCoreTextShaper.h rename : gfx/thebes/src/gfxD2DSurface.cpp => gfx/thebes/gfxD2DSurface.cpp rename : gfx/thebes/public/gfxD2DSurface.h => gfx/thebes/gfxD2DSurface.h rename : gfx/thebes/src/gfxDDrawSurface.cpp => gfx/thebes/gfxDDrawSurface.cpp rename : gfx/thebes/public/gfxDDrawSurface.h => gfx/thebes/gfxDDrawSurface.h rename : gfx/thebes/src/gfxDWriteCommon.cpp => gfx/thebes/gfxDWriteCommon.cpp rename : gfx/thebes/src/gfxDWriteCommon.h => gfx/thebes/gfxDWriteCommon.h rename : gfx/thebes/src/gfxDWriteFontList.cpp => gfx/thebes/gfxDWriteFontList.cpp rename : gfx/thebes/src/gfxDWriteFontList.h => gfx/thebes/gfxDWriteFontList.h rename : gfx/thebes/src/gfxDWriteFonts.cpp => gfx/thebes/gfxDWriteFonts.cpp rename : gfx/thebes/public/gfxDWriteFonts.h => gfx/thebes/gfxDWriteFonts.h rename : gfx/thebes/src/gfxDWriteShaper.cpp => gfx/thebes/gfxDWriteShaper.cpp rename : gfx/thebes/src/gfxDWriteShaper.h => gfx/thebes/gfxDWriteShaper.h rename : gfx/thebes/src/gfxDWriteTextAnalysis.cpp => gfx/thebes/gfxDWriteTextAnalysis.cpp rename : gfx/thebes/src/gfxDWriteTextAnalysis.h => gfx/thebes/gfxDWriteTextAnalysis.h rename : gfx/thebes/src/gfxDirectFBSurface.cpp => gfx/thebes/gfxDirectFBSurface.cpp rename : gfx/thebes/public/gfxDirectFBSurface.h => gfx/thebes/gfxDirectFBSurface.h rename : gfx/thebes/src/gfxDllDeps.cpp => gfx/thebes/gfxDllDeps.cpp rename : gfx/thebes/src/gfxFT2FontBase.cpp => gfx/thebes/gfxFT2FontBase.cpp rename : gfx/thebes/public/gfxFT2FontBase.h => gfx/thebes/gfxFT2FontBase.h rename : gfx/thebes/src/gfxFT2FontList.cpp => gfx/thebes/gfxFT2FontList.cpp rename : gfx/thebes/src/gfxFT2FontList.h => gfx/thebes/gfxFT2FontList.h rename : gfx/thebes/src/gfxFT2Fonts.cpp => gfx/thebes/gfxFT2Fonts.cpp rename : gfx/thebes/public/gfxFT2Fonts.h => gfx/thebes/gfxFT2Fonts.h rename : gfx/thebes/src/gfxFT2Utils.cpp => gfx/thebes/gfxFT2Utils.cpp rename : gfx/thebes/src/gfxFT2Utils.h => gfx/thebes/gfxFT2Utils.h rename : gfx/thebes/src/gfxFont.cpp => gfx/thebes/gfxFont.cpp rename : gfx/thebes/public/gfxFont.h => gfx/thebes/gfxFont.h rename : gfx/thebes/public/gfxFontConstants.h => gfx/thebes/gfxFontConstants.h rename : gfx/thebes/src/gfxFontMissingGlyphs.cpp => gfx/thebes/gfxFontMissingGlyphs.cpp rename : gfx/thebes/src/gfxFontMissingGlyphs.h => gfx/thebes/gfxFontMissingGlyphs.h rename : gfx/thebes/src/gfxFontTest.cpp => gfx/thebes/gfxFontTest.cpp rename : gfx/thebes/public/gfxFontTest.h => gfx/thebes/gfxFontTest.h rename : gfx/thebes/src/gfxFontUtils.cpp => gfx/thebes/gfxFontUtils.cpp rename : gfx/thebes/public/gfxFontUtils.h => gfx/thebes/gfxFontUtils.h rename : gfx/thebes/src/gfxFontconfigUtils.cpp => gfx/thebes/gfxFontconfigUtils.cpp rename : gfx/thebes/src/gfxFontconfigUtils.h => gfx/thebes/gfxFontconfigUtils.h rename : gfx/thebes/src/gfxGDIFont.cpp => gfx/thebes/gfxGDIFont.cpp rename : gfx/thebes/src/gfxGDIFont.h => gfx/thebes/gfxGDIFont.h rename : gfx/thebes/src/gfxGDIFontList.cpp => gfx/thebes/gfxGDIFontList.cpp rename : gfx/thebes/src/gfxGDIFontList.h => gfx/thebes/gfxGDIFontList.h rename : gfx/thebes/src/gfxGDIShaper.cpp => gfx/thebes/gfxGDIShaper.cpp rename : gfx/thebes/src/gfxGDIShaper.h => gfx/thebes/gfxGDIShaper.h rename : gfx/thebes/src/gfxGdkNativeRenderer.cpp => gfx/thebes/gfxGdkNativeRenderer.cpp rename : gfx/thebes/public/gfxGdkNativeRenderer.h => gfx/thebes/gfxGdkNativeRenderer.h rename : gfx/thebes/public/gfxGlitzSurface.h => gfx/thebes/gfxGlitzSurface.h rename : gfx/thebes/src/gfxHarfBuzzShaper.cpp => gfx/thebes/gfxHarfBuzzShaper.cpp rename : gfx/thebes/src/gfxHarfBuzzShaper.h => gfx/thebes/gfxHarfBuzzShaper.h rename : gfx/thebes/src/gfxImageSurface.cpp => gfx/thebes/gfxImageSurface.cpp rename : gfx/thebes/public/gfxImageSurface.h => gfx/thebes/gfxImageSurface.h rename : gfx/thebes/src/gfxMacFont.cpp => gfx/thebes/gfxMacFont.cpp rename : gfx/thebes/src/gfxMacFont.h => gfx/thebes/gfxMacFont.h rename : gfx/thebes/src/gfxMacPlatformFontList.h => gfx/thebes/gfxMacPlatformFontList.h rename : gfx/thebes/src/gfxMacPlatformFontList.mm => gfx/thebes/gfxMacPlatformFontList.mm rename : gfx/thebes/src/gfxMatrix.cpp => gfx/thebes/gfxMatrix.cpp rename : gfx/thebes/public/gfxMatrix.h => gfx/thebes/gfxMatrix.h rename : gfx/thebes/src/gfxOS2Fonts.cpp => gfx/thebes/gfxOS2Fonts.cpp rename : gfx/thebes/public/gfxOS2Fonts.h => gfx/thebes/gfxOS2Fonts.h rename : gfx/thebes/src/gfxOS2Platform.cpp => gfx/thebes/gfxOS2Platform.cpp rename : gfx/thebes/public/gfxOS2Platform.h => gfx/thebes/gfxOS2Platform.h rename : gfx/thebes/src/gfxOS2Surface.cpp => gfx/thebes/gfxOS2Surface.cpp rename : gfx/thebes/public/gfxOS2Surface.h => gfx/thebes/gfxOS2Surface.h rename : gfx/thebes/src/gfxPDFSurface.cpp => gfx/thebes/gfxPDFSurface.cpp rename : gfx/thebes/public/gfxPDFSurface.h => gfx/thebes/gfxPDFSurface.h rename : gfx/thebes/src/gfxPSSurface.cpp => gfx/thebes/gfxPSSurface.cpp rename : gfx/thebes/public/gfxPSSurface.h => gfx/thebes/gfxPSSurface.h rename : gfx/thebes/src/gfxPangoFonts.cpp => gfx/thebes/gfxPangoFonts.cpp rename : gfx/thebes/public/gfxPangoFonts.h => gfx/thebes/gfxPangoFonts.h rename : gfx/thebes/src/gfxPath.cpp => gfx/thebes/gfxPath.cpp rename : gfx/thebes/public/gfxPath.h => gfx/thebes/gfxPath.h rename : gfx/thebes/src/gfxPattern.cpp => gfx/thebes/gfxPattern.cpp rename : gfx/thebes/public/gfxPattern.h => gfx/thebes/gfxPattern.h rename : gfx/thebes/src/gfxPlatform.cpp => gfx/thebes/gfxPlatform.cpp rename : gfx/thebes/public/gfxPlatform.h => gfx/thebes/gfxPlatform.h rename : gfx/thebes/src/gfxPlatformFontList.cpp => gfx/thebes/gfxPlatformFontList.cpp rename : gfx/thebes/src/gfxPlatformFontList.h => gfx/thebes/gfxPlatformFontList.h rename : gfx/thebes/src/gfxPlatformGtk.cpp => gfx/thebes/gfxPlatformGtk.cpp rename : gfx/thebes/public/gfxPlatformGtk.h => gfx/thebes/gfxPlatformGtk.h rename : gfx/thebes/src/gfxPlatformMac.cpp => gfx/thebes/gfxPlatformMac.cpp rename : gfx/thebes/public/gfxPlatformMac.h => gfx/thebes/gfxPlatformMac.h rename : gfx/thebes/public/gfxPoint.h => gfx/thebes/gfxPoint.h rename : gfx/thebes/src/gfxQPainterSurface.cpp => gfx/thebes/gfxQPainterSurface.cpp rename : gfx/thebes/public/gfxQPainterSurface.h => gfx/thebes/gfxQPainterSurface.h rename : gfx/thebes/src/gfxQtNativeRenderer.cpp => gfx/thebes/gfxQtNativeRenderer.cpp rename : gfx/thebes/public/gfxQtNativeRenderer.h => gfx/thebes/gfxQtNativeRenderer.h rename : gfx/thebes/src/gfxQtPlatform.cpp => gfx/thebes/gfxQtPlatform.cpp rename : gfx/thebes/public/gfxQtPlatform.h => gfx/thebes/gfxQtPlatform.h rename : gfx/thebes/src/gfxQuartzImageSurface.cpp => gfx/thebes/gfxQuartzImageSurface.cpp rename : gfx/thebes/public/gfxQuartzImageSurface.h => gfx/thebes/gfxQuartzImageSurface.h rename : gfx/thebes/src/gfxQuartzNativeDrawing.cpp => gfx/thebes/gfxQuartzNativeDrawing.cpp rename : gfx/thebes/public/gfxQuartzNativeDrawing.h => gfx/thebes/gfxQuartzNativeDrawing.h rename : gfx/thebes/src/gfxQuartzPDFSurface.cpp => gfx/thebes/gfxQuartzPDFSurface.cpp rename : gfx/thebes/public/gfxQuartzPDFSurface.h => gfx/thebes/gfxQuartzPDFSurface.h rename : gfx/thebes/src/gfxQuartzSurface.cpp => gfx/thebes/gfxQuartzSurface.cpp rename : gfx/thebes/public/gfxQuartzSurface.h => gfx/thebes/gfxQuartzSurface.h rename : gfx/thebes/src/gfxRect.cpp => gfx/thebes/gfxRect.cpp rename : gfx/thebes/public/gfxRect.h => gfx/thebes/gfxRect.h rename : gfx/thebes/src/gfxScriptItemizer.cpp => gfx/thebes/gfxScriptItemizer.cpp rename : gfx/thebes/src/gfxScriptItemizer.h => gfx/thebes/gfxScriptItemizer.h rename : gfx/thebes/src/gfxSharedImageSurface.cpp => gfx/thebes/gfxSharedImageSurface.cpp rename : gfx/thebes/public/gfxSharedImageSurface.h => gfx/thebes/gfxSharedImageSurface.h rename : gfx/thebes/src/gfxSkipChars.cpp => gfx/thebes/gfxSkipChars.cpp rename : gfx/thebes/public/gfxSkipChars.h => gfx/thebes/gfxSkipChars.h rename : gfx/thebes/src/gfxTextRunCache.cpp => gfx/thebes/gfxTextRunCache.cpp rename : gfx/thebes/public/gfxTextRunCache.h => gfx/thebes/gfxTextRunCache.h rename : gfx/thebes/src/gfxTextRunWordCache.cpp => gfx/thebes/gfxTextRunWordCache.cpp rename : gfx/thebes/public/gfxTextRunWordCache.h => gfx/thebes/gfxTextRunWordCache.h rename : gfx/thebes/public/gfxTypes.h => gfx/thebes/gfxTypes.h rename : gfx/thebes/src/gfxUnicodeProperties.cpp => gfx/thebes/gfxUnicodeProperties.cpp rename : gfx/thebes/src/gfxUnicodeProperties.h => gfx/thebes/gfxUnicodeProperties.h rename : gfx/thebes/src/gfxUnicodePropertyData.cpp => gfx/thebes/gfxUnicodePropertyData.cpp rename : gfx/thebes/src/gfxUniscribeShaper.cpp => gfx/thebes/gfxUniscribeShaper.cpp rename : gfx/thebes/src/gfxUniscribeShaper.h => gfx/thebes/gfxUniscribeShaper.h rename : gfx/thebes/src/gfxUserFontSet.cpp => gfx/thebes/gfxUserFontSet.cpp rename : gfx/thebes/public/gfxUserFontSet.h => gfx/thebes/gfxUserFontSet.h rename : gfx/thebes/src/gfxUtils.cpp => gfx/thebes/gfxUtils.cpp rename : gfx/thebes/public/gfxUtils.h => gfx/thebes/gfxUtils.h rename : gfx/thebes/src/gfxWindowsNativeDrawing.cpp => gfx/thebes/gfxWindowsNativeDrawing.cpp rename : gfx/thebes/public/gfxWindowsNativeDrawing.h => gfx/thebes/gfxWindowsNativeDrawing.h rename : gfx/thebes/src/gfxWindowsPlatform.cpp => gfx/thebes/gfxWindowsPlatform.cpp rename : gfx/thebes/public/gfxWindowsPlatform.h => gfx/thebes/gfxWindowsPlatform.h rename : gfx/thebes/src/gfxWindowsSurface.cpp => gfx/thebes/gfxWindowsSurface.cpp rename : gfx/thebes/public/gfxWindowsSurface.h => gfx/thebes/gfxWindowsSurface.h rename : gfx/thebes/src/gfxXlibNativeRenderer.cpp => gfx/thebes/gfxXlibNativeRenderer.cpp rename : gfx/thebes/public/gfxXlibNativeRenderer.h => gfx/thebes/gfxXlibNativeRenderer.h rename : gfx/thebes/src/gfxXlibSurface.cpp => gfx/thebes/gfxXlibSurface.cpp rename : gfx/thebes/public/gfxXlibSurface.h => gfx/thebes/gfxXlibSurface.h rename : gfx/thebes/src/ignorable.x-ccmap => gfx/thebes/ignorable.x-ccmap rename : gfx/thebes/src/nsUnicodeRange.cpp => gfx/thebes/nsUnicodeRange.cpp rename : gfx/thebes/src/nsUnicodeRange.h => gfx/thebes/nsUnicodeRange.h rename : gfx/thebes/src/woff-private.h => gfx/thebes/woff-private.h rename : gfx/thebes/src/woff.c => gfx/thebes/woff.c rename : gfx/thebes/src/woff.h => gfx/thebes/woff.h
648 lines
18 KiB
C++
648 lines
18 KiB
C++
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is Mozilla Foundation code.
|
|
*
|
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Bas Schouten <bschouten@mozilla.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "gfxDWriteFontList.h"
|
|
#include "gfxDWriteFonts.h"
|
|
#include "nsUnicharUtils.h"
|
|
#include "nsILocaleService.h"
|
|
|
|
#include "gfxGDIFontList.h"
|
|
|
|
#include "nsIWindowsRegKey.h"
|
|
|
|
// font info loader constants
|
|
static const PRUint32 kDelayBeforeLoadingFonts = 8 * 1000; // 8secs
|
|
static const PRUint32 kIntervalBetweenLoadingFonts = 150; // 150ms
|
|
|
|
static __inline void
|
|
BuildKeyNameFromFontName(nsAString &aName)
|
|
{
|
|
if (aName.Length() >= LF_FACESIZE)
|
|
aName.Truncate(LF_FACESIZE - 1);
|
|
ToLowerCase(aName);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// gfxDWriteFontFamily
|
|
|
|
gfxDWriteFontFamily::~gfxDWriteFontFamily()
|
|
{
|
|
}
|
|
|
|
void
|
|
gfxDWriteFontFamily::FindStyleVariations()
|
|
{
|
|
HRESULT hr;
|
|
if (mHasStyles) {
|
|
return;
|
|
}
|
|
mHasStyles = PR_TRUE;
|
|
|
|
for (UINT32 i = 0; i < mDWFamily->GetFontCount(); i++) {
|
|
nsRefPtr<IDWriteFont> font;
|
|
hr = mDWFamily->GetFont(i, getter_AddRefs(font));
|
|
if (FAILED(hr)) {
|
|
// This should never happen.
|
|
NS_WARNING("Failed to get existing font from family.");
|
|
continue;
|
|
}
|
|
|
|
if (font->GetSimulations() & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
|
|
// We don't want these.
|
|
continue;
|
|
}
|
|
|
|
nsRefPtr<IDWriteLocalizedStrings> names;
|
|
hr = font->GetFaceNames(getter_AddRefs(names));
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
|
|
BOOL exists;
|
|
nsAutoTArray<WCHAR,32> faceName;
|
|
UINT32 englishIdx = 0;
|
|
hr = names->FindLocaleName(L"en-us", &englishIdx, &exists);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
|
|
if (!exists) {
|
|
// No english found, use whatever is first in the list.
|
|
englishIdx = 0;
|
|
}
|
|
UINT32 length;
|
|
hr = names->GetStringLength(englishIdx, &length);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
if (!faceName.SetLength(length + 1)) {
|
|
// Eeep - running out of memory. Unlikely to end well.
|
|
continue;
|
|
}
|
|
|
|
hr = names->GetString(englishIdx, faceName.Elements(), length + 1);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
|
|
nsString fullID(mName);
|
|
fullID.Append(faceName.Elements());
|
|
|
|
/**
|
|
* Faces do not have a localized name so we just put the en-us name in
|
|
* here.
|
|
*/
|
|
gfxDWriteFontEntry *fe =
|
|
new gfxDWriteFontEntry(fullID, font);
|
|
fe->SetFamily(this);
|
|
|
|
mAvailableFonts.AppendElement(fe);
|
|
}
|
|
if (!mAvailableFonts.Length()) {
|
|
NS_WARNING("Family with no font faces in it.");
|
|
}
|
|
|
|
if (mIsBadUnderlineFamily) {
|
|
SetBadUnderlineFonts();
|
|
}
|
|
}
|
|
|
|
void
|
|
gfxDWriteFontFamily::LocalizedName(nsAString &aLocalizedName)
|
|
{
|
|
aLocalizedName.AssignLiteral("Unknown Font");
|
|
HRESULT hr;
|
|
nsresult rv;
|
|
nsCOMPtr<nsILocaleService> ls = do_GetService(NS_LOCALESERVICE_CONTRACTID,
|
|
&rv);
|
|
nsCOMPtr<nsILocale> locale;
|
|
rv = ls->GetApplicationLocale(getter_AddRefs(locale));
|
|
nsString localeName;
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = locale->GetCategory(NS_LITERAL_STRING(NSILOCALE_MESSAGE),
|
|
localeName);
|
|
}
|
|
if (NS_FAILED(rv)) {
|
|
localeName.AssignLiteral("en-us");
|
|
}
|
|
|
|
nsRefPtr<IDWriteLocalizedStrings> names;
|
|
|
|
hr = mDWFamily->GetFamilyNames(getter_AddRefs(names));
|
|
if (FAILED(hr)) {
|
|
return;
|
|
}
|
|
UINT32 idx = 0;
|
|
BOOL exists;
|
|
hr = names->FindLocaleName(localeName.BeginReading(),
|
|
&idx,
|
|
&exists);
|
|
if (FAILED(hr)) {
|
|
return;
|
|
}
|
|
if (!exists) {
|
|
// Use english is localized is not found.
|
|
hr = names->FindLocaleName(L"en-us", &idx, &exists);
|
|
if (FAILED(hr)) {
|
|
return;
|
|
}
|
|
if (!exists) {
|
|
// Use 0 index if english is not found.
|
|
idx = 0;
|
|
}
|
|
}
|
|
nsAutoTArray<WCHAR, 32> famName;
|
|
UINT32 length;
|
|
|
|
hr = names->GetStringLength(idx, &length);
|
|
if (FAILED(hr)) {
|
|
return;
|
|
}
|
|
|
|
if (!famName.SetLength(length + 1)) {
|
|
// Eeep - running out of memory. Unlikely to end well.
|
|
return;
|
|
}
|
|
|
|
hr = names->GetString(idx, famName.Elements(), length + 1);
|
|
if (FAILED(hr)) {
|
|
return;
|
|
}
|
|
|
|
aLocalizedName = nsDependentString(famName.Elements());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// gfxDWriteFontEntry
|
|
|
|
gfxDWriteFontEntry::~gfxDWriteFontEntry()
|
|
{
|
|
}
|
|
|
|
PRBool
|
|
gfxDWriteFontEntry::IsSymbolFont()
|
|
{
|
|
if (mFont) {
|
|
return mFont->IsSymbolFont();
|
|
} else {
|
|
return PR_FALSE;
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
gfxDWriteFontEntry::GetFontTable(PRUint32 aTableTag,
|
|
nsTArray<PRUint8> &aBuffer)
|
|
{
|
|
nsRefPtr<IDWriteFontFace> fontFace;
|
|
HRESULT hr;
|
|
nsresult rv;
|
|
rv = CreateFontFace(getter_AddRefs(fontFace));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
PRUint8 *tableData;
|
|
PRUint32 len;
|
|
void *tableContext = NULL;
|
|
BOOL exists;
|
|
hr = fontFace->TryGetFontTable(NS_SWAP32(aTableTag),
|
|
(const void**)&tableData,
|
|
&len,
|
|
&tableContext,
|
|
&exists);
|
|
|
|
if (FAILED(hr) || !exists) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (!aBuffer.SetLength(len)) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
memcpy(aBuffer.Elements(), tableData, len);
|
|
if (tableContext) {
|
|
fontFace->ReleaseFontTable(&tableContext);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
gfxDWriteFontEntry::ReadCMAP()
|
|
{
|
|
nsRefPtr<IDWriteFontFace> fontFace;
|
|
HRESULT hr;
|
|
nsresult rv;
|
|
rv = CreateFontFace(getter_AddRefs(fontFace));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
PRUint8 *tableData;
|
|
PRUint32 len;
|
|
void *tableContext = NULL;
|
|
BOOL exists;
|
|
hr = fontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p'),
|
|
(const void**)&tableData,
|
|
&len,
|
|
&tableContext,
|
|
&exists);
|
|
if (FAILED(hr)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
PRPackedBool isSymbol = fontFace->IsSymbolFont();
|
|
PRPackedBool isUnicode = PR_TRUE;
|
|
if (exists) {
|
|
rv = gfxFontUtils::ReadCMAP(tableData,
|
|
len,
|
|
mCharacterMap,
|
|
mUVSOffset,
|
|
isUnicode,
|
|
isSymbol);
|
|
}
|
|
|
|
if (tableContext) {
|
|
fontFace->ReleaseFontTable(tableContext);
|
|
}
|
|
|
|
mCmapInitialized = PR_TRUE;
|
|
mHasCmapTable = NS_SUCCEEDED(rv);
|
|
return rv;
|
|
}
|
|
|
|
gfxFont *
|
|
gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
|
|
PRBool aNeedsBold)
|
|
{
|
|
return new gfxDWriteFont(this, aFontStyle, aNeedsBold);
|
|
}
|
|
|
|
nsresult
|
|
gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace,
|
|
DWRITE_FONT_SIMULATIONS aSimulations)
|
|
{
|
|
HRESULT hr;
|
|
if (mFont) {
|
|
hr = mFont->CreateFontFace(aFontFace);
|
|
} else if (mFontFile) {
|
|
IDWriteFontFile *fontFile = mFontFile.get();
|
|
hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()->
|
|
CreateFontFace(mFaceType,
|
|
1,
|
|
&fontFile,
|
|
0,
|
|
aSimulations,
|
|
aFontFace);
|
|
}
|
|
if (FAILED(hr)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// gfxDWriteFontList
|
|
|
|
gfxDWriteFontList::gfxDWriteFontList()
|
|
{
|
|
mFontSubstitutes.Init();
|
|
}
|
|
|
|
gfxFontEntry *
|
|
gfxDWriteFontList::GetDefaultFont(const gfxFontStyle *aStyle,
|
|
PRBool &aNeedsBold)
|
|
{
|
|
NONCLIENTMETRICSW ncm;
|
|
ncm.cbSize = sizeof(ncm);
|
|
BOOL status = ::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
|
|
sizeof(ncm), &ncm, 0);
|
|
if (status) {
|
|
nsAutoString resolvedName;
|
|
if (ResolveFontName(nsDependentString(ncm.lfMessageFont.lfFaceName),
|
|
resolvedName)) {
|
|
return FindFontForFamily(resolvedName, aStyle, aNeedsBold);
|
|
}
|
|
}
|
|
|
|
return nsnull;
|
|
}
|
|
|
|
gfxFontEntry *
|
|
gfxDWriteFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
|
const nsAString& aFullname)
|
|
{
|
|
PRBool found;
|
|
gfxFontEntry *lookup;
|
|
|
|
// initialize name lookup tables if needed
|
|
if (!mFaceNamesInitialized) {
|
|
InitFaceNameLists();
|
|
}
|
|
|
|
// lookup in name lookup tables, return null if not found
|
|
if (!(lookup = mPostscriptNames.GetWeak(aFullname, &found)) &&
|
|
!(lookup = mFullnames.GetWeak(aFullname, &found)))
|
|
{
|
|
return nsnull;
|
|
}
|
|
gfxFontEntry *fe =
|
|
new gfxDWriteFontEntry(lookup->Name(),
|
|
static_cast<gfxDWriteFontEntry*>(lookup)->mFont,
|
|
aProxyEntry->Weight(),
|
|
aProxyEntry->Stretch(),
|
|
aProxyEntry->IsItalic());
|
|
|
|
return fe;
|
|
}
|
|
|
|
gfxFontEntry *
|
|
gfxDWriteFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
|
const PRUint8 *aFontData,
|
|
PRUint32 aLength)
|
|
{
|
|
nsresult rv;
|
|
nsAutoString uniqueName;
|
|
rv = gfxFontUtils::MakeUniqueUserFontName(uniqueName);
|
|
if (NS_FAILED(rv)) {
|
|
NS_Free((void*)aFontData);
|
|
return nsnull;
|
|
}
|
|
|
|
nsTArray<PRUint8> newFontData;
|
|
|
|
rv = gfxFontUtils::RenameFont(uniqueName, aFontData, aLength, &newFontData);
|
|
NS_Free((void*)aFontData);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return nsnull;
|
|
}
|
|
|
|
DWORD numFonts = 0;
|
|
|
|
nsRefPtr<IDWriteFontFile> fontFile;
|
|
HRESULT hr;
|
|
|
|
/**
|
|
* We pass in a pointer to a structure containing a pointer to the array
|
|
* containing the font data and a unique identifier. DWrite will
|
|
* internally copy what is at that pointer, and pass that to
|
|
* CreateStreamFromKey. The array will be empty when the function
|
|
* succesfully returns since it swaps out the data.
|
|
*/
|
|
ffReferenceKey key;
|
|
key.mArray = &newFontData;
|
|
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
|
do_GetService("@mozilla.org/uuid-generator;1");
|
|
if (!uuidgen) {
|
|
return nsnull;
|
|
}
|
|
|
|
rv = uuidgen->GenerateUUIDInPlace(&key.mGUID);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return nsnull;
|
|
}
|
|
|
|
hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()->
|
|
CreateCustomFontFileReference(&key,
|
|
sizeof(key),
|
|
gfxDWriteFontFileLoader::Instance(),
|
|
getter_AddRefs(fontFile));
|
|
|
|
if (FAILED(hr)) {
|
|
NS_WARNING("Failed to create custom font file reference.");
|
|
return nsnull;
|
|
}
|
|
|
|
BOOL isSupported;
|
|
DWRITE_FONT_FILE_TYPE fileType;
|
|
UINT32 numFaces;
|
|
|
|
PRUint16 w = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
|
|
gfxDWriteFontEntry *entry =
|
|
new gfxDWriteFontEntry(uniqueName,
|
|
fontFile,
|
|
aProxyEntry->Weight(),
|
|
aProxyEntry->Stretch(),
|
|
aProxyEntry->IsItalic());
|
|
|
|
fontFile->Analyze(&isSupported, &fileType, &entry->mFaceType, &numFaces);
|
|
if (!isSupported || numFaces > 1) {
|
|
// We don't know how to deal with 0 faces either.
|
|
delete entry;
|
|
return nsnull;
|
|
}
|
|
|
|
return entry;
|
|
}
|
|
|
|
void
|
|
gfxDWriteFontList::InitFontList()
|
|
{
|
|
HRESULT hr;
|
|
gfxFontCache *fc = gfxFontCache::GetCache();
|
|
if (fc) {
|
|
fc->AgeAllGenerations();
|
|
}
|
|
|
|
gfxPlatformFontList::InitFontList();
|
|
|
|
mFontSubstitutes.Clear();
|
|
mNonExistingFonts.Clear();
|
|
|
|
nsRefPtr<IDWriteFontCollection> systemFonts;
|
|
hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()->
|
|
GetSystemFontCollection(getter_AddRefs(systemFonts));
|
|
NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
|
|
|
|
for (UINT32 i = 0; i < systemFonts->GetFontFamilyCount(); i++) {
|
|
nsRefPtr<IDWriteFontFamily> family;
|
|
systemFonts->GetFontFamily(i, getter_AddRefs(family));
|
|
|
|
nsRefPtr<IDWriteLocalizedStrings> names;
|
|
hr = family->GetFamilyNames(getter_AddRefs(names));
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
|
|
UINT32 englishIdx = 0;
|
|
|
|
BOOL exists;
|
|
hr = names->FindLocaleName(L"en-us", &englishIdx, &exists);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
if (!exists) {
|
|
// Use 0 index if english is not found.
|
|
englishIdx = 0;
|
|
}
|
|
|
|
nsAutoTArray<WCHAR, 32> famName;
|
|
UINT32 length;
|
|
|
|
hr = names->GetStringLength(englishIdx, &length);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
|
|
if (!famName.SetLength(length + 1)) {
|
|
// Eeep - running out of memory. Unlikely to end well.
|
|
continue;
|
|
}
|
|
|
|
hr = names->GetString(englishIdx, famName.Elements(), length + 1);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
|
|
nsAutoString name(famName.Elements());
|
|
BuildKeyNameFromFontName(name);
|
|
|
|
if (!mFontFamilies.GetWeak(name)) {
|
|
nsRefPtr<gfxFontFamily> fam =
|
|
new gfxDWriteFontFamily(nsDependentString(famName.Elements()),
|
|
family);
|
|
if (mBadUnderlineFamilyNames.Contains(name)) {
|
|
fam->SetBadUnderlineFamily();
|
|
}
|
|
mFontFamilies.Put(name, fam);
|
|
}
|
|
}
|
|
|
|
GetFontSubstitutes();
|
|
|
|
StartLoader(kDelayBeforeLoadingFonts, kIntervalBetweenLoadingFonts);
|
|
}
|
|
|
|
static void
|
|
RemoveCharsetFromFontSubstitute(nsAString &aName)
|
|
{
|
|
PRInt32 comma = aName.FindChar(PRUnichar(','));
|
|
if (comma >= 0)
|
|
aName.Truncate(comma);
|
|
}
|
|
|
|
nsresult
|
|
gfxDWriteFontList::GetFontSubstitutes()
|
|
{
|
|
// Create the list of FontSubstitutes
|
|
nsCOMPtr<nsIWindowsRegKey> regKey =
|
|
do_CreateInstance("@mozilla.org/windows-registry-key;1");
|
|
if (!regKey) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
NS_NAMED_LITERAL_STRING(
|
|
kFontSubstitutesKey,
|
|
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
|
|
|
|
nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
|
|
kFontSubstitutesKey,
|
|
nsIWindowsRegKey::ACCESS_READ);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
PRUint32 count;
|
|
rv = regKey->GetValueCount(&count);
|
|
if (NS_FAILED(rv) || count == 0)
|
|
return rv;
|
|
for (PRUint32 i = 0; i < count; i++) {
|
|
nsAutoString substituteName;
|
|
rv = regKey->GetValueName(i, substituteName);
|
|
if (NS_FAILED(rv) || substituteName.IsEmpty() ||
|
|
substituteName.CharAt(1) == PRUnichar('@')) {
|
|
continue;
|
|
}
|
|
PRUint32 valueType;
|
|
rv = regKey->GetValueType(substituteName, &valueType);
|
|
if (NS_FAILED(rv) || valueType != nsIWindowsRegKey::TYPE_STRING) {
|
|
continue;
|
|
}
|
|
nsAutoString actualFontName;
|
|
rv = regKey->ReadStringValue(substituteName, actualFontName);
|
|
if (NS_FAILED(rv)) {
|
|
continue;
|
|
}
|
|
|
|
RemoveCharsetFromFontSubstitute(substituteName);
|
|
BuildKeyNameFromFontName(substituteName);
|
|
RemoveCharsetFromFontSubstitute(actualFontName);
|
|
BuildKeyNameFromFontName(actualFontName);
|
|
gfxFontFamily *ff;
|
|
if (!actualFontName.IsEmpty() &&
|
|
(ff = mFontFamilies.GetWeak(actualFontName))) {
|
|
mFontSubstitutes.Put(substituteName, ff);
|
|
} else {
|
|
mNonExistingFonts.AppendElement(substituteName);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
PRBool
|
|
gfxDWriteFontList::GetStandardFamilyName(const nsAString& aFontName,
|
|
nsAString& aFamilyName)
|
|
{
|
|
gfxFontFamily *family = FindFamily(aFontName);
|
|
if (family) {
|
|
family->LocalizedName(aFamilyName);
|
|
return PR_TRUE;
|
|
}
|
|
|
|
return PR_FALSE;
|
|
}
|
|
|
|
PRBool
|
|
gfxDWriteFontList::ResolveFontName(const nsAString& aFontName,
|
|
nsAString& aResolvedFontName)
|
|
{
|
|
nsAutoString keyName(aFontName);
|
|
BuildKeyNameFromFontName(keyName);
|
|
|
|
nsRefPtr<gfxFontFamily> ff;
|
|
if (mFontSubstitutes.Get(keyName, &ff)) {
|
|
aResolvedFontName = ff->Name();
|
|
return PR_TRUE;
|
|
}
|
|
|
|
if (mNonExistingFonts.Contains(keyName)) {
|
|
return PR_FALSE;
|
|
}
|
|
|
|
return gfxPlatformFontList::ResolveFontName(aFontName, aResolvedFontName);
|
|
}
|