2006-02-01 05:35:38 +03:00
|
|
|
/* -*- 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) 2005
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2006-06-10 04:21:05 +04:00
|
|
|
* Stuart Parmenter <stuart@mozilla.com>
|
2006-02-01 05:35:38 +03:00
|
|
|
* Vladimir Vukicevic <vladimir@pobox.com>
|
2006-11-21 09:31:04 +03:00
|
|
|
* Masayuki Nakano <masayuki@d-toybox.com>
|
2007-01-05 18:51:27 +03:00
|
|
|
* Masatoshi Kimura <VYV03354@nifty.ne.jp>
|
2006-02-01 05:35:38 +03:00
|
|
|
*
|
|
|
|
* 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 ***** */
|
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
#include "mozilla/Util.h"
|
|
|
|
|
2006-02-01 05:35:38 +03:00
|
|
|
#include "gfxWindowsPlatform.h"
|
|
|
|
|
|
|
|
#include "gfxImageSurface.h"
|
|
|
|
#include "gfxWindowsSurface.h"
|
|
|
|
|
2006-06-10 04:21:05 +04:00
|
|
|
#include "nsUnicharUtils.h"
|
|
|
|
|
2011-06-12 06:30:16 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2006-06-10 04:21:05 +04:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2009-01-18 23:14:14 +03:00
|
|
|
#include "nsTArray.h"
|
2006-06-10 04:21:05 +04:00
|
|
|
|
2007-01-05 18:51:27 +03:00
|
|
|
#include "nsIWindowsRegKey.h"
|
2008-10-01 07:01:53 +04:00
|
|
|
#include "nsILocalFile.h"
|
|
|
|
#include "plbase64.h"
|
2010-08-28 06:44:37 +04:00
|
|
|
#include "nsIXULRuntime.h"
|
2007-01-05 18:51:27 +03:00
|
|
|
|
2010-08-31 01:45:29 +04:00
|
|
|
#include "nsIGfxInfo.h"
|
|
|
|
|
2011-03-02 23:50:36 +03:00
|
|
|
#include "gfxCrashReporterUtils.h"
|
|
|
|
|
2009-10-07 18:13:40 +04:00
|
|
|
#include "gfxGDIFontList.h"
|
2010-03-15 12:34:25 +03:00
|
|
|
#include "gfxGDIFont.h"
|
2011-06-18 13:04:30 +04:00
|
|
|
|
2010-02-27 19:05:54 +03:00
|
|
|
#ifdef CAIRO_HAS_DWRITE_FONT
|
2010-02-26 09:36:07 +03:00
|
|
|
#include "gfxDWriteFontList.h"
|
|
|
|
#include "gfxDWriteFonts.h"
|
|
|
|
#include "gfxDWriteCommon.h"
|
|
|
|
#include <dwrite.h>
|
2009-01-23 09:24:29 +03:00
|
|
|
#endif
|
|
|
|
|
2011-06-17 16:55:51 +04:00
|
|
|
#include "gfxUserFontSet.h"
|
|
|
|
|
|
|
|
#include <string>
|
2011-06-15 14:22:57 +04:00
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
using namespace mozilla;
|
2011-06-24 21:41:18 +04:00
|
|
|
using namespace mozilla::gfx;
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
|
|
#include "gfxD2DSurface.h"
|
2010-06-30 17:52:13 +04:00
|
|
|
|
2010-08-14 10:34:55 +04:00
|
|
|
#include <d3d10_1.h>
|
2011-08-09 23:38:26 +04:00
|
|
|
#include <dxgi.h>
|
2010-08-14 10:34:55 +04:00
|
|
|
|
2011-06-24 21:41:18 +04:00
|
|
|
#include "mozilla/gfx/2D.h"
|
|
|
|
|
2010-06-30 17:52:13 +04:00
|
|
|
#include "nsMemory.h"
|
2011-06-17 16:55:51 +04:00
|
|
|
#endif
|
|
|
|
|
2012-02-09 03:13:50 +04:00
|
|
|
/**
|
|
|
|
* XXX below should be >= MOZ_NTDDI_WIN8 or such which is not defined yet
|
|
|
|
*/
|
|
|
|
#if MOZ_WINSDK_TARGETVER > MOZ_NTDDI_WIN7
|
|
|
|
#define ENABLE_GPU_MEM_REPORTER
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined CAIRO_HAS_D2D_SURFACE || defined ENABLE_GPU_MEM_REPORTER
|
|
|
|
#include "nsIMemoryReporter.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ENABLE_GPU_MEM_REPORTER
|
|
|
|
#include <winternl.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* XXX need to check that extern C is really needed with Win8 SDK.
|
|
|
|
* It was required for files I had available at push time.
|
|
|
|
*/
|
|
|
|
extern "C" {
|
|
|
|
#include <d3dkmthk.h>
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-06-17 16:55:51 +04:00
|
|
|
using namespace mozilla;
|
2010-06-30 17:52:13 +04:00
|
|
|
|
2011-06-17 16:55:51 +04:00
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
2010-06-30 17:52:13 +04:00
|
|
|
|
2011-06-16 22:34:09 +04:00
|
|
|
NS_MEMORY_REPORTER_IMPLEMENT(
|
|
|
|
D2DCache,
|
|
|
|
"gfx-d2d-surfacecache",
|
|
|
|
KIND_OTHER,
|
|
|
|
UNITS_BYTES,
|
|
|
|
cairo_d2d_get_image_surface_cache_usage,
|
|
|
|
"Memory used by the Direct2D internal surface cache.")
|
2010-06-30 17:52:13 +04:00
|
|
|
|
2011-06-16 22:34:09 +04:00
|
|
|
namespace
|
2010-08-18 07:43:49 +04:00
|
|
|
{
|
|
|
|
|
2011-06-16 22:34:09 +04:00
|
|
|
PRInt64 GetD2DSurfaceVramUsage() {
|
|
|
|
cairo_device_t *device =
|
|
|
|
gfxWindowsPlatform::GetPlatform()->GetD2DDevice();
|
|
|
|
if (device) {
|
|
|
|
return cairo_d2d_get_surface_vram_usage(device);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2011-05-23 06:49:56 +04:00
|
|
|
|
2011-06-16 22:34:09 +04:00
|
|
|
} // anonymous namespace
|
2010-08-18 07:43:49 +04:00
|
|
|
|
2011-06-16 22:34:09 +04:00
|
|
|
NS_MEMORY_REPORTER_IMPLEMENT(
|
|
|
|
D2DVram,
|
|
|
|
"gfx-d2d-surfacevram",
|
|
|
|
KIND_OTHER,
|
|
|
|
UNITS_BYTES,
|
|
|
|
GetD2DSurfaceVramUsage,
|
|
|
|
"Video memory used by D2D surfaces")
|
2010-08-18 07:43:49 +04:00
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
#endif
|
2009-07-09 03:34:02 +04:00
|
|
|
|
2010-05-27 09:05:30 +04:00
|
|
|
#define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content"
|
|
|
|
#define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts"
|
|
|
|
|
2011-04-21 10:29:50 +04:00
|
|
|
#define GFX_CLEARTYPE_PARAMS "gfx.font_rendering.cleartype_params."
|
|
|
|
#define GFX_CLEARTYPE_PARAMS_GAMMA "gfx.font_rendering.cleartype_params.gamma"
|
|
|
|
#define GFX_CLEARTYPE_PARAMS_CONTRAST "gfx.font_rendering.cleartype_params.enhanced_contrast"
|
|
|
|
#define GFX_CLEARTYPE_PARAMS_LEVEL "gfx.font_rendering.cleartype_params.cleartype_level"
|
|
|
|
#define GFX_CLEARTYPE_PARAMS_STRUCTURE "gfx.font_rendering.cleartype_params.pixel_structure"
|
|
|
|
#define GFX_CLEARTYPE_PARAMS_MODE "gfx.font_rendering.cleartype_params.rendering_mode"
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
#ifdef CAIRO_HAS_DWRITE_FONT
|
|
|
|
// DirectWrite is not available on all platforms, we need to use the function
|
|
|
|
// pointer.
|
|
|
|
typedef HRESULT (WINAPI*DWriteCreateFactoryFunc)(
|
2011-11-08 13:25:33 +04:00
|
|
|
DWRITE_FACTORY_TYPE factoryType,
|
|
|
|
REFIID iid,
|
|
|
|
IUnknown **factory
|
2010-02-26 09:36:07 +03:00
|
|
|
);
|
|
|
|
#endif
|
2010-08-16 11:15:03 +04:00
|
|
|
|
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
|
|
typedef HRESULT (WINAPI*D3D10CreateDevice1Func)(
|
|
|
|
IDXGIAdapter *pAdapter,
|
|
|
|
D3D10_DRIVER_TYPE DriverType,
|
|
|
|
HMODULE Software,
|
|
|
|
UINT Flags,
|
|
|
|
D3D10_FEATURE_LEVEL1 HardwareLevel,
|
|
|
|
UINT SDKVersion,
|
|
|
|
ID3D10Device1 **ppDevice
|
2010-08-14 10:34:55 +04:00
|
|
|
);
|
2011-08-09 23:38:26 +04:00
|
|
|
|
|
|
|
typedef HRESULT(WINAPI*CreateDXGIFactory1Func)(
|
|
|
|
REFIID riid,
|
|
|
|
void **ppFactory
|
|
|
|
);
|
2010-08-14 10:34:55 +04:00
|
|
|
#endif
|
2010-02-26 09:36:07 +03:00
|
|
|
|
2012-02-09 03:13:50 +04:00
|
|
|
#ifdef ENABLE_GPU_MEM_REPORTER
|
|
|
|
class GPUAdapterMultiReporter : public nsIMemoryMultiReporter {
|
|
|
|
|
|
|
|
// Callers must Release the DXGIAdapter after use or risk mem-leak
|
|
|
|
static bool GetDXGIAdapter(__out IDXGIAdapter **DXGIAdapter)
|
|
|
|
{
|
|
|
|
ID3D10Device1 *D2D10Device;
|
|
|
|
IDXGIDevice *DXGIDevice;
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
if (D2D10Device = mozilla::gfx::Factory::GetDirect3D10Device()) {
|
|
|
|
if (D2D10Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&DXGIDevice) == S_OK) {
|
|
|
|
result = (DXGIDevice->GetAdapter(DXGIAdapter) == S_OK);
|
|
|
|
DXGIDevice->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIMemoryMultiReporter abstract method implementation
|
|
|
|
NS_IMETHOD
|
|
|
|
CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|
|
|
nsISupports* aClosure)
|
|
|
|
{
|
|
|
|
PRInt32 winVers, buildNum;
|
|
|
|
HANDLE ProcessHandle = GetCurrentProcess();
|
|
|
|
|
|
|
|
PRInt64 dedicatedBytesUsed = 0;
|
|
|
|
PRInt64 sharedBytesUsed = 0;
|
|
|
|
PRInt64 committedBytesUsed = 0;
|
|
|
|
IDXGIAdapter *DXGIAdapter;
|
|
|
|
|
|
|
|
HMODULE gdi32Handle;
|
|
|
|
PFND3DKMT_QUERYSTATISTICS queryD3DKMTStatistics;
|
|
|
|
|
|
|
|
winVers = gfxWindowsPlatform::WindowsOSVersion(&buildNum);
|
|
|
|
|
|
|
|
// GPU memory reporting is not available before Windows 7
|
|
|
|
if (winVers < gfxWindowsPlatform::kWindows7)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
if (gdi32Handle = LoadLibrary(TEXT("gdi32.dll")))
|
|
|
|
queryD3DKMTStatistics = (PFND3DKMT_QUERYSTATISTICS)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics");
|
|
|
|
|
|
|
|
if (queryD3DKMTStatistics && GetDXGIAdapter(&DXGIAdapter)) {
|
|
|
|
// Most of this block is understood thanks to wj32's work on Process Hacker
|
|
|
|
|
|
|
|
DXGI_ADAPTER_DESC adapterDesc;
|
|
|
|
D3DKMT_QUERYSTATISTICS queryStatistics;
|
|
|
|
|
|
|
|
DXGIAdapter->GetDesc(&adapterDesc);
|
|
|
|
DXGIAdapter->Release();
|
|
|
|
|
|
|
|
memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
|
|
|
|
queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS;
|
|
|
|
queryStatistics.AdapterLuid = adapterDesc.AdapterLuid;
|
|
|
|
queryStatistics.hProcess = ProcessHandle;
|
|
|
|
if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) {
|
|
|
|
committedBytesUsed = queryStatistics.QueryResult.ProcessInformation.SystemMemory.BytesAllocated;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
|
|
|
|
queryStatistics.Type = D3DKMT_QUERYSTATISTICS_ADAPTER;
|
|
|
|
queryStatistics.AdapterLuid = adapterDesc.AdapterLuid;
|
|
|
|
if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) {
|
|
|
|
ULONG i;
|
|
|
|
ULONG segmentCount = queryStatistics.QueryResult.AdapterInformation.NbSegments;
|
|
|
|
|
|
|
|
for (i = 0; i < segmentCount; i++) {
|
|
|
|
memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
|
|
|
|
queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT;
|
|
|
|
queryStatistics.AdapterLuid = adapterDesc.AdapterLuid;
|
|
|
|
queryStatistics.QuerySegment.SegmentId = i;
|
|
|
|
|
|
|
|
if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) {
|
|
|
|
bool aperture;
|
|
|
|
|
|
|
|
// SegmentInformation has a different definition in Win7 than later versions
|
|
|
|
if (winVers > gfxWindowsPlatform::kWindows7)
|
|
|
|
aperture = queryStatistics.QueryResult.SegmentInformation.Aperture;
|
|
|
|
else
|
|
|
|
aperture = queryStatistics.QueryResult.SegmentInformationV1.Aperture;
|
|
|
|
|
|
|
|
memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));
|
|
|
|
queryStatistics.Type = D3DKMT_QUERYSTATISTICS_PROCESS_SEGMENT;
|
|
|
|
queryStatistics.AdapterLuid = adapterDesc.AdapterLuid;
|
|
|
|
queryStatistics.hProcess = ProcessHandle;
|
|
|
|
queryStatistics.QueryProcessSegment.SegmentId = i;
|
|
|
|
if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) {
|
|
|
|
if (aperture)
|
|
|
|
sharedBytesUsed += queryStatistics.QueryResult
|
|
|
|
.ProcessSegmentInformation
|
|
|
|
.BytesCommitted;
|
|
|
|
else
|
|
|
|
dedicatedBytesUsed += queryStatistics.QueryResult
|
|
|
|
.ProcessSegmentInformation
|
|
|
|
.BytesCommitted;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeLibrary(gdi32Handle);
|
|
|
|
|
|
|
|
aCb->Callback(EmptyCString(),
|
|
|
|
NS_LITERAL_CSTRING("gpu-committed"),
|
|
|
|
nsIMemoryReporter::KIND_OTHER,
|
|
|
|
nsIMemoryReporter::UNITS_BYTES,
|
|
|
|
committedBytesUsed,
|
|
|
|
NS_LITERAL_CSTRING("Memory committed by the Windows graphics system."),
|
|
|
|
aClosure);
|
|
|
|
aCb->Callback(EmptyCString(),
|
|
|
|
NS_LITERAL_CSTRING("gpu-dedicated"),
|
|
|
|
nsIMemoryReporter::KIND_OTHER,
|
|
|
|
nsIMemoryReporter::UNITS_BYTES,
|
|
|
|
dedicatedBytesUsed,
|
|
|
|
NS_LITERAL_CSTRING("Out-of-process memory allocated for this process in a "
|
|
|
|
"physical GPU adapter's memory."),
|
|
|
|
aClosure);
|
|
|
|
aCb->Callback(EmptyCString(),
|
|
|
|
NS_LITERAL_CSTRING("gpu-shared"),
|
|
|
|
nsIMemoryReporter::KIND_OTHER,
|
|
|
|
nsIMemoryReporter::UNITS_BYTES,
|
|
|
|
sharedBytesUsed,
|
|
|
|
NS_LITERAL_CSTRING("In-process memory that is shared with the GPU."),
|
|
|
|
aClosure);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsIMemoryMultiReporter abstract method implementation
|
|
|
|
NS_IMETHOD
|
|
|
|
GetExplicitNonHeap(PRInt64 *aExplicitNonHeap)
|
|
|
|
{
|
|
|
|
// This reporter doesn't do any non-heap measurements.
|
|
|
|
*aExplicitNonHeap = 0;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS1(GPUAdapterMultiReporter, nsIMemoryMultiReporter)
|
|
|
|
#endif // ENABLE_GPU_MEM_REPORTER
|
|
|
|
|
2008-03-27 00:32:51 +03:00
|
|
|
static __inline void
|
|
|
|
BuildKeyNameFromFontName(nsAString &aName)
|
|
|
|
{
|
|
|
|
if (aName.Length() >= LF_FACESIZE)
|
|
|
|
aName.Truncate(LF_FACESIZE - 1);
|
|
|
|
ToLowerCase(aName);
|
|
|
|
}
|
2008-03-19 03:06:55 +03:00
|
|
|
|
2006-02-01 05:35:38 +03:00
|
|
|
gfxWindowsPlatform::gfxWindowsPlatform()
|
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
mPrefFonts.Init(50);
|
2007-08-24 23:41:16 +04:00
|
|
|
|
2010-05-27 09:05:30 +04:00
|
|
|
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
|
|
|
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mUsingGDIFonts = false;
|
2010-11-08 14:02:27 +03:00
|
|
|
|
2010-08-27 00:44:53 +04:00
|
|
|
/*
|
|
|
|
* Initialize COM
|
|
|
|
*/
|
|
|
|
CoInitialize(NULL);
|
|
|
|
|
2010-08-20 05:26:00 +04:00
|
|
|
mScreenDC = GetDC(NULL);
|
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
2011-06-16 22:34:09 +04:00
|
|
|
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(D2DCache));
|
|
|
|
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(D2DVram));
|
2010-09-16 02:16:09 +04:00
|
|
|
mD2DDevice = nsnull;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
UpdateRenderMode();
|
2012-02-09 03:13:50 +04:00
|
|
|
|
|
|
|
#ifdef ENABLE_GPU_MEM_REPORTER
|
|
|
|
mGPUAdapterMultiReporter = new GPUAdapterMultiReporter();
|
|
|
|
NS_RegisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
|
|
|
#endif
|
2010-09-16 02:16:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
gfxWindowsPlatform::~gfxWindowsPlatform()
|
|
|
|
{
|
2012-02-09 03:13:50 +04:00
|
|
|
#ifdef ENABLE_GPU_MEM_REPORTER
|
|
|
|
NS_UnregisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
|
|
|
#endif
|
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
::ReleaseDC(NULL, mScreenDC);
|
|
|
|
// not calling FT_Done_FreeType because cairo may still hold references to
|
|
|
|
// these FT_Faces. See bug 458169.
|
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
|
|
if (mD2DDevice) {
|
|
|
|
cairo_release_device(mD2DDevice);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Uninitialize COM
|
|
|
|
*/
|
2010-11-08 14:02:27 +03:00
|
|
|
CoUninitialize();
|
2010-09-16 02:16:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gfxWindowsPlatform::UpdateRenderMode()
|
|
|
|
{
|
2011-06-10 20:27:01 +04:00
|
|
|
/* Pick the default render mode for
|
|
|
|
* desktop.
|
2009-07-09 03:34:02 +04:00
|
|
|
*/
|
|
|
|
mRenderMode = RENDER_GDI;
|
|
|
|
|
2010-08-14 10:34:55 +04:00
|
|
|
OSVERSIONINFOA versionInfo;
|
|
|
|
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
|
|
|
::GetVersionExA(&versionInfo);
|
|
|
|
bool isVistaOrHigher = versionInfo.dwMajorVersion >= 6;
|
2009-10-07 18:13:40 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool safeMode = false;
|
2010-08-31 04:02:18 +04:00
|
|
|
nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
|
|
|
|
if (xr)
|
|
|
|
xr->GetInSafeMode(&safeMode);
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
mUseDirectWrite = Preferences::GetBool("gfx.font_rendering.directwrite.enabled", false);
|
2010-09-16 02:16:09 +04:00
|
|
|
|
2010-06-30 17:52:13 +04:00
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
2011-09-29 10:19:26 +04:00
|
|
|
bool d2dDisabled = false;
|
|
|
|
bool d2dForceEnabled = false;
|
|
|
|
bool d2dBlocked = false;
|
2010-08-31 01:45:29 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
|
|
|
if (gfxInfo) {
|
|
|
|
PRInt32 status;
|
|
|
|
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT2D, &status))) {
|
2010-10-07 08:40:08 +04:00
|
|
|
if (status != nsIGfxInfo::FEATURE_NO_INFO) {
|
2011-10-17 18:59:28 +04:00
|
|
|
d2dDisabled = true;
|
2010-10-07 08:40:08 +04:00
|
|
|
if (status == nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION ||
|
|
|
|
status == nsIGfxInfo::FEATURE_BLOCKED_DEVICE)
|
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
d2dBlocked = true;
|
2010-08-31 01:45:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
d2dDisabled = Preferences::GetBool("gfx.direct2d.disabled", false);
|
|
|
|
d2dForceEnabled = Preferences::GetBool("gfx.direct2d.force-enabled", false);
|
2010-08-28 06:44:37 +04:00
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
bool tryD2D = !d2dBlocked || d2dForceEnabled;
|
|
|
|
|
2010-11-08 14:02:27 +03:00
|
|
|
// Do not ever try if d2d is explicitly disabled,
|
|
|
|
// or if we're not using DWrite fonts.
|
|
|
|
if (d2dDisabled || mUsingGDIFonts) {
|
2010-09-16 02:16:09 +04:00
|
|
|
tryD2D = false;
|
|
|
|
}
|
2010-08-14 10:34:55 +04:00
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
if (isVistaOrHigher && !safeMode && tryD2D) {
|
|
|
|
VerifyD2DDevice(d2dForceEnabled);
|
|
|
|
if (mD2DDevice) {
|
|
|
|
mRenderMode = RENDER_DIRECT2D;
|
2011-10-17 18:59:28 +04:00
|
|
|
mUseDirectWrite = true;
|
2010-08-14 10:34:55 +04:00
|
|
|
}
|
2010-09-16 02:16:09 +04:00
|
|
|
} else {
|
|
|
|
mD2DDevice = nsnull;
|
2010-08-14 10:34:55 +04:00
|
|
|
}
|
2010-06-30 17:52:13 +04:00
|
|
|
#endif
|
2010-08-14 10:34:55 +04:00
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
#ifdef CAIRO_HAS_DWRITE_FONT
|
2010-08-14 10:34:55 +04:00
|
|
|
// Enable when it's preffed on -and- we're using Vista or higher. Or when
|
|
|
|
// we're going to use D2D.
|
2010-09-16 02:16:09 +04:00
|
|
|
if (!mDWriteFactory && (mUseDirectWrite && isVistaOrHigher)) {
|
2011-03-02 23:50:36 +03:00
|
|
|
mozilla::ScopedGfxFeatureReporter reporter("DWrite");
|
2010-02-26 09:36:07 +03:00
|
|
|
DWriteCreateFactoryFunc createDWriteFactory = (DWriteCreateFactoryFunc)
|
|
|
|
GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory");
|
|
|
|
|
|
|
|
if (createDWriteFactory) {
|
|
|
|
/**
|
|
|
|
* I need a direct pointer to be able to cast to IUnknown**, I also
|
|
|
|
* need to remember to release this because the nsRefPtr will
|
|
|
|
* AddRef it.
|
|
|
|
*/
|
|
|
|
IDWriteFactory *factory;
|
|
|
|
HRESULT hr = createDWriteFactory(
|
|
|
|
DWRITE_FACTORY_TYPE_SHARED,
|
|
|
|
__uuidof(IDWriteFactory),
|
|
|
|
reinterpret_cast<IUnknown**>(&factory));
|
|
|
|
mDWriteFactory = factory;
|
|
|
|
factory->Release();
|
2011-03-02 23:50:36 +03:00
|
|
|
|
2011-12-06 16:39:19 +04:00
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
hr = mDWriteFactory->CreateTextAnalyzer(
|
|
|
|
getter_AddRefs(mDWriteAnalyzer));
|
|
|
|
}
|
|
|
|
|
2011-06-12 06:30:16 +04:00
|
|
|
SetupClearTypeParams();
|
2011-04-21 10:29:50 +04:00
|
|
|
|
2011-03-02 23:50:36 +03:00
|
|
|
if (hr == S_OK)
|
|
|
|
reporter.SetSuccessful();
|
2010-02-26 09:36:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2006-02-24 08:15:21 +03:00
|
|
|
}
|
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
void
|
2011-09-29 10:19:26 +04:00
|
|
|
gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
|
2006-02-24 08:15:21 +03:00
|
|
|
{
|
2010-08-11 03:59:51 +04:00
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
|
|
if (mD2DDevice) {
|
2010-09-16 02:16:09 +04:00
|
|
|
ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice);
|
|
|
|
|
|
|
|
if (SUCCEEDED(device->GetDeviceRemovedReason())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mD2DDevice = nsnull;
|
2010-08-11 03:59:51 +04:00
|
|
|
}
|
2010-08-27 00:44:53 +04:00
|
|
|
|
2011-03-02 23:50:36 +03:00
|
|
|
mozilla::ScopedGfxFeatureReporter reporter("D2D");
|
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
|
|
|
|
D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)
|
|
|
|
GetProcAddress(d3d10module, "D3D10CreateDevice1");
|
|
|
|
nsRefPtr<ID3D10Device1> device;
|
|
|
|
|
|
|
|
if (createD3DDevice) {
|
2011-08-09 23:38:26 +04:00
|
|
|
HMODULE dxgiModule = LoadLibraryA("dxgi.dll");
|
|
|
|
CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func)
|
|
|
|
GetProcAddress(dxgiModule, "CreateDXGIFactory1");
|
|
|
|
|
|
|
|
// Try to use a DXGI 1.1 adapter in order to share resources
|
|
|
|
// across processes.
|
|
|
|
nsRefPtr<IDXGIAdapter1> adapter1;
|
|
|
|
if (createDXGIFactory1) {
|
|
|
|
nsRefPtr<IDXGIFactory1> factory1;
|
|
|
|
HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
|
|
|
|
getter_AddRefs(factory1));
|
2012-01-31 09:15:23 +04:00
|
|
|
|
|
|
|
if (FAILED(hr) || !factory1) {
|
|
|
|
// This seems to happen with some people running the iZ3D driver.
|
|
|
|
// They won't get acceleration.
|
|
|
|
return;
|
|
|
|
}
|
2011-08-09 23:38:26 +04:00
|
|
|
|
|
|
|
nsRefPtr<IDXGIAdapter1> adapter1;
|
|
|
|
hr = factory1->EnumAdapters1(0, getter_AddRefs(adapter1));
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr) && adapter1) {
|
|
|
|
hr = adapter1->CheckInterfaceSupport(__uuidof(ID3D10Device1),
|
|
|
|
nsnull);
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
adapter1 = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-09 22:50:54 +04:00
|
|
|
// It takes a lot of time (5-10% of startup time or ~100ms) to do both
|
|
|
|
// a createD3DDevice on D3D10_FEATURE_LEVEL_10_0 and
|
|
|
|
// D3D10_FEATURE_LEVEL_10_1. Therefore we set a pref if we ever get
|
|
|
|
// 10.1 to work and we use that first if the pref is set.
|
|
|
|
// Going direct to a 10.1 check only takes 20-30ms.
|
|
|
|
// The initialization of hr doesn't matter here because it will get
|
|
|
|
// overwritten whether or not the preference is set.
|
|
|
|
// - If the preferD3D10_1 pref is set it gets overwritten immediately.
|
|
|
|
// - If the preferD3D10_1 pref is not set, the if condition after
|
|
|
|
// the one that follows us immediately will short circuit before
|
|
|
|
// checking FAILED(hr) and will again get overwritten immediately.
|
|
|
|
// We initialize it here just so it does not appear to be an
|
|
|
|
// uninitialized value.
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
bool preferD3D10_1 =
|
|
|
|
Preferences::GetBool("gfx.direct3d.prefer_10_1", false);
|
|
|
|
if (preferD3D10_1) {
|
|
|
|
hr = createD3DDevice(
|
|
|
|
adapter1,
|
|
|
|
D3D10_DRIVER_TYPE_HARDWARE,
|
|
|
|
NULL,
|
|
|
|
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
|
|
|
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
|
|
|
D3D10_FEATURE_LEVEL_10_1,
|
|
|
|
D3D10_1_SDK_VERSION,
|
|
|
|
getter_AddRefs(device));
|
|
|
|
|
|
|
|
// If we fail here, the DirectX version or video card probably
|
|
|
|
// changed. We previously could use 10.1 but now we can't
|
|
|
|
// anymore. Revert back to doing a 10.0 check first before
|
|
|
|
// the 10.1 check.
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
Preferences::SetBool("gfx.direct3d.prefer_10_1", false);
|
|
|
|
} else {
|
|
|
|
mD2DDevice = cairo_d2d_create_device_from_d3d10device(device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!preferD3D10_1 || FAILED(hr)) {
|
|
|
|
// If preferD3D10_1 is set and 10.1 failed, fall back to 10.0.
|
|
|
|
// if preferD3D10_1 is not yet set, then first try to create
|
|
|
|
// a 10.0 D3D device, then try to see if 10.1 works.
|
2010-09-16 02:16:09 +04:00
|
|
|
nsRefPtr<ID3D10Device1> device1;
|
|
|
|
hr = createD3DDevice(
|
2012-02-09 22:50:54 +04:00
|
|
|
adapter1,
|
|
|
|
D3D10_DRIVER_TYPE_HARDWARE,
|
|
|
|
NULL,
|
|
|
|
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
|
|
|
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
|
|
|
D3D10_FEATURE_LEVEL_10_0,
|
|
|
|
D3D10_1_SDK_VERSION,
|
|
|
|
getter_AddRefs(device1));
|
2010-08-27 00:44:53 +04:00
|
|
|
|
2010-09-16 02:16:09 +04:00
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
device = device1;
|
2012-02-09 22:50:54 +04:00
|
|
|
if (preferD3D10_1) {
|
|
|
|
mD2DDevice =
|
|
|
|
cairo_d2d_create_device_from_d3d10device(device);
|
|
|
|
}
|
2010-09-16 02:16:09 +04:00
|
|
|
}
|
2012-02-09 22:50:54 +04:00
|
|
|
}
|
2006-02-24 08:15:21 +03:00
|
|
|
|
2012-02-09 22:50:54 +04:00
|
|
|
// If preferD3D10_1 is not yet set and 10.0 succeeded
|
|
|
|
if (!preferD3D10_1 && SUCCEEDED(hr)) {
|
|
|
|
// We have 10.0, let's try 10.1. This second check will only
|
|
|
|
// ever be done once if it succeeds. After that an option
|
|
|
|
// will be set to prefer using 10.1 before trying 10.0.
|
|
|
|
// In the case that 10.1 fails, it won't be a long operation
|
|
|
|
// like it is when 10.1 succeeds, so we don't need to optimize
|
|
|
|
// the case where 10.1 is not supported, but 10.0 is supported.
|
|
|
|
nsRefPtr<ID3D10Device1> device1;
|
|
|
|
hr = createD3DDevice(
|
|
|
|
adapter1,
|
|
|
|
D3D10_DRIVER_TYPE_HARDWARE,
|
|
|
|
NULL,
|
|
|
|
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
|
|
|
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
|
|
|
D3D10_FEATURE_LEVEL_10_1,
|
|
|
|
D3D10_1_SDK_VERSION,
|
|
|
|
getter_AddRefs(device1));
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
device = device1;
|
|
|
|
Preferences::SetBool("gfx.direct3d.prefer_10_1", true);
|
|
|
|
}
|
2010-09-16 02:16:09 +04:00
|
|
|
mD2DDevice = cairo_d2d_create_device_from_d3d10device(device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mD2DDevice && aAttemptForce) {
|
|
|
|
mD2DDevice = cairo_d2d_create_device();
|
|
|
|
}
|
2011-03-02 23:50:36 +03:00
|
|
|
|
2011-06-24 21:41:18 +04:00
|
|
|
if (mD2DDevice) {
|
2011-03-02 23:50:36 +03:00
|
|
|
reporter.SetSuccessful();
|
2011-06-24 21:41:18 +04:00
|
|
|
mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice));
|
|
|
|
}
|
2010-09-16 02:16:09 +04:00
|
|
|
#endif
|
|
|
|
}
|
2010-11-08 14:02:27 +03:00
|
|
|
|
2011-02-25 04:31:16 +03:00
|
|
|
// bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd
|
|
|
|
// crashers so blacklist them altogether
|
|
|
|
|
|
|
|
#ifdef CAIRO_HAS_DWRITE_FONT
|
|
|
|
#define WINDOWS7_RTM_BUILD 7600
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
static bool
|
2011-02-25 04:31:16 +03:00
|
|
|
AllowDirectWrite()
|
|
|
|
{
|
|
|
|
PRInt32 winVers, buildNum;
|
|
|
|
|
|
|
|
winVers = gfxWindowsPlatform::WindowsOSVersion(&buildNum);
|
|
|
|
if (winVers == gfxWindowsPlatform::kWindows7 &&
|
|
|
|
buildNum < WINDOWS7_RTM_BUILD)
|
|
|
|
{
|
|
|
|
// don't use Direct2D/DirectWrite on older versions of Windows 7
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2011-02-25 04:31:16 +03:00
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-02-25 04:31:16 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxPlatformFontList*
|
|
|
|
gfxWindowsPlatform::CreatePlatformFontList()
|
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
mUsingGDIFonts = false;
|
2010-11-08 14:02:27 +03:00
|
|
|
gfxPlatformFontList *pfl;
|
2010-02-26 09:36:07 +03:00
|
|
|
#ifdef CAIRO_HAS_DWRITE_FONT
|
2011-02-25 04:31:16 +03:00
|
|
|
if (AllowDirectWrite() && GetDWriteFactory()) {
|
2010-11-08 14:02:27 +03:00
|
|
|
pfl = new gfxDWriteFontList();
|
|
|
|
if (NS_SUCCEEDED(pfl->InitFontList())) {
|
|
|
|
return pfl;
|
|
|
|
}
|
|
|
|
// DWrite font initialization failed! Don't know why this would happen,
|
|
|
|
// but apparently it can - see bug 594865.
|
|
|
|
// So we're going to fall back to GDI fonts & rendering.
|
|
|
|
gfxPlatformFontList::Shutdown();
|
|
|
|
SetRenderMode(RENDER_GDI);
|
2010-02-26 09:36:07 +03:00
|
|
|
}
|
|
|
|
#endif
|
2010-11-08 14:02:27 +03:00
|
|
|
pfl = new gfxGDIFontList();
|
2011-10-17 18:59:28 +04:00
|
|
|
mUsingGDIFonts = true;
|
2010-11-08 14:02:27 +03:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(pfl->InitFontList())) {
|
|
|
|
return pfl;
|
|
|
|
}
|
|
|
|
|
|
|
|
gfxPlatformFontList::Shutdown();
|
|
|
|
return nsnull;
|
2009-10-07 18:13:40 +04:00
|
|
|
}
|
2010-02-26 09:36:07 +03:00
|
|
|
|
2006-03-25 03:34:48 +03:00
|
|
|
already_AddRefed<gfxASurface>
|
2007-02-08 23:47:48 +03:00
|
|
|
gfxWindowsPlatform::CreateOffscreenSurface(const gfxIntSize& size,
|
2010-09-17 01:34:53 +04:00
|
|
|
gfxASurface::gfxContentType contentType)
|
2006-02-01 05:35:38 +03:00
|
|
|
{
|
2009-07-09 03:34:02 +04:00
|
|
|
gfxASurface *surf = nsnull;
|
|
|
|
|
|
|
|
#ifdef CAIRO_HAS_WIN32_SURFACE
|
|
|
|
if (mRenderMode == RENDER_GDI)
|
2010-09-17 01:34:53 +04:00
|
|
|
surf = new gfxWindowsSurface(size, gfxASurface::FormatFromContent(contentType));
|
2009-01-15 03:19:39 +03:00
|
|
|
#endif
|
2009-07-09 03:34:02 +04:00
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
|
|
if (mRenderMode == RENDER_DIRECT2D)
|
2010-09-17 01:34:53 +04:00
|
|
|
surf = new gfxD2DSurface(size, gfxASurface::FormatFromContent(contentType));
|
2010-02-26 09:36:07 +03:00
|
|
|
#endif
|
|
|
|
|
2009-07-09 03:34:02 +04:00
|
|
|
if (surf == nsnull)
|
2010-09-17 01:34:53 +04:00
|
|
|
surf = new gfxImageSurface(size, gfxASurface::FormatFromContent(contentType));
|
2009-07-09 03:34:02 +04:00
|
|
|
|
2006-03-25 03:34:48 +03:00
|
|
|
NS_IF_ADDREF(surf);
|
2009-07-09 03:34:02 +04:00
|
|
|
|
2006-03-25 03:34:48 +03:00
|
|
|
return surf;
|
2006-02-01 05:35:38 +03:00
|
|
|
}
|
|
|
|
|
2011-06-24 21:41:18 +04:00
|
|
|
RefPtr<ScaledFont>
|
|
|
|
gfxWindowsPlatform::GetScaledFontForFont(gfxFont *aFont)
|
|
|
|
{
|
|
|
|
if(mUseDirectWrite) {
|
|
|
|
gfxDWriteFont *font = static_cast<gfxDWriteFont*>(aFont);
|
|
|
|
|
|
|
|
NativeFont nativeFont;
|
|
|
|
nativeFont.mType = NATIVE_FONT_DWRITE_FONT_FACE;
|
|
|
|
nativeFont.mFont = font->GetFontFace();
|
|
|
|
RefPtr<ScaledFont> scaledFont =
|
|
|
|
mozilla::gfx::Factory::CreateScaledFontForNativeFont(nativeFont, font->GetAdjustedSize());
|
|
|
|
|
|
|
|
return scaledFont;
|
|
|
|
}
|
2011-06-30 16:35:46 +04:00
|
|
|
|
2011-11-18 08:00:37 +04:00
|
|
|
NativeFont nativeFont;
|
|
|
|
nativeFont.mType = NATIVE_FONT_GDI_FONT_FACE;
|
|
|
|
nativeFont.mFont = aFont;
|
|
|
|
RefPtr<ScaledFont> scaledFont =
|
|
|
|
Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
|
|
|
|
|
|
|
|
return scaledFont;
|
2011-06-24 21:41:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<gfxASurface>
|
|
|
|
gfxWindowsPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
|
|
|
{
|
|
|
|
#ifdef XP_WIN
|
|
|
|
if (aTarget->GetType() == BACKEND_DIRECT2D) {
|
2012-01-27 22:08:58 +04:00
|
|
|
void *surface = aTarget->GetUserData(&kThebesSurfaceKey);
|
2012-01-13 18:48:29 +04:00
|
|
|
if (surface) {
|
|
|
|
nsRefPtr<gfxASurface> surf = static_cast<gfxASurface*>(surface);
|
|
|
|
return surf.forget();
|
|
|
|
} else {
|
2012-02-07 09:14:21 +04:00
|
|
|
if (!GetD2DDevice()) {
|
|
|
|
// We no longer have a D2D device, can't do this.
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-01-13 18:48:29 +04:00
|
|
|
RefPtr<ID3D10Texture2D> texture =
|
|
|
|
static_cast<ID3D10Texture2D*>(aTarget->GetNativeSurface(NATIVE_SURFACE_D3D10_TEXTURE));
|
2011-06-24 21:41:18 +04:00
|
|
|
|
2012-01-13 18:48:29 +04:00
|
|
|
if (!texture) {
|
|
|
|
return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
|
|
|
|
}
|
2011-06-24 21:41:18 +04:00
|
|
|
|
2012-01-13 18:48:29 +04:00
|
|
|
aTarget->Flush();
|
2011-06-24 21:41:18 +04:00
|
|
|
|
2012-01-13 18:48:29 +04:00
|
|
|
nsRefPtr<gfxASurface> surf =
|
|
|
|
new gfxD2DSurface(texture, ContentForFormat(aTarget->GetFormat()));
|
2011-06-24 21:41:18 +04:00
|
|
|
|
2012-01-13 18:48:29 +04:00
|
|
|
// add a reference to be held by the drawTarget
|
|
|
|
surf->AddRef();
|
2012-01-27 22:08:58 +04:00
|
|
|
aTarget->AddUserData(&kThebesSurfaceKey, surf.get(), DestroyThebesSurface);
|
2012-01-13 18:48:29 +04:00
|
|
|
/* "It might be worth it to clear cairo surfaces associated with a drawtarget.
|
|
|
|
The strong reference means for example for D2D that cairo's scratch surface
|
|
|
|
will be kept alive (well after a user being done) and consume extra VRAM.
|
|
|
|
We can deal with this in a follow-up though." */
|
2011-06-24 21:41:18 +04:00
|
|
|
|
2012-01-13 18:48:29 +04:00
|
|
|
// shouldn't this hold a reference?
|
|
|
|
surf->SetData(&kDrawTarget, aTarget, NULL);
|
|
|
|
return surf.forget();
|
|
|
|
}
|
2011-06-24 21:41:18 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
|
|
|
|
}
|
|
|
|
|
2011-11-18 08:00:38 +04:00
|
|
|
bool
|
|
|
|
gfxWindowsPlatform::SupportsAzure(BackendType& aBackend)
|
|
|
|
{
|
|
|
|
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
|
|
if (mRenderMode == RENDER_DIRECT2D) {
|
|
|
|
aBackend = BACKEND_DIRECT2D;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-01-28 02:38:00 +04:00
|
|
|
if (mPreferredDrawTargetBackend != BACKEND_NONE) {
|
|
|
|
aBackend = mPreferredDrawTargetBackend;
|
2011-11-18 08:00:38 +04:00
|
|
|
return true;
|
|
|
|
}
|
2012-01-28 02:38:00 +04:00
|
|
|
|
2011-11-18 08:00:38 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2006-02-01 05:35:38 +03:00
|
|
|
nsresult
|
2010-02-24 20:57:57 +03:00
|
|
|
gfxWindowsPlatform::GetFontList(nsIAtom *aLangGroup,
|
2006-02-01 05:35:38 +03:00
|
|
|
const nsACString& aGenericFamily,
|
2009-01-18 23:14:14 +03:00
|
|
|
nsTArray<nsString>& aListOfFonts)
|
2006-02-01 05:35:38 +03:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup, aGenericFamily, aListOfFonts);
|
2006-02-24 08:15:21 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-01-05 18:51:27 +03:00
|
|
|
static void
|
|
|
|
RemoveCharsetFromFontSubstitute(nsAString &aName)
|
|
|
|
{
|
|
|
|
PRInt32 comma = aName.FindChar(PRUnichar(','));
|
|
|
|
if (comma >= 0)
|
|
|
|
aName.Truncate(comma);
|
|
|
|
}
|
|
|
|
|
2006-06-15 08:47:23 +04:00
|
|
|
nsresult
|
|
|
|
gfxWindowsPlatform::UpdateFontList()
|
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxPlatformFontList::PlatformFontList()->UpdateFontList();
|
2008-03-13 05:36:58 +03:00
|
|
|
|
2006-06-15 08:47:23 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2006-11-21 09:31:04 +03:00
|
|
|
struct ResolveData {
|
|
|
|
ResolveData(gfxPlatform::FontResolverCallback aCallback,
|
|
|
|
gfxWindowsPlatform *aCaller, const nsAString *aFontName,
|
|
|
|
void *aClosure) :
|
|
|
|
mFoundCount(0), mCallback(aCallback), mCaller(aCaller),
|
|
|
|
mFontName(aFontName), mClosure(aClosure) {}
|
|
|
|
PRUint32 mFoundCount;
|
|
|
|
gfxPlatform::FontResolverCallback mCallback;
|
|
|
|
gfxWindowsPlatform *mCaller;
|
|
|
|
const nsAString *mFontName;
|
|
|
|
void *mClosure;
|
|
|
|
};
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
gfxWindowsPlatform::ResolveFontName(const nsAString& aFontName,
|
|
|
|
FontResolverCallback aCallback,
|
2010-02-26 09:36:07 +03:00
|
|
|
void *aClosure,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool& aAborted)
|
2006-11-21 09:31:04 +03:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
nsAutoString resolvedName;
|
|
|
|
if (!gfxPlatformFontList::PlatformFontList()->
|
|
|
|
ResolveFontName(aFontName, resolvedName)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
aAborted = false;
|
2006-11-21 09:31:04 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2009-10-07 18:13:40 +04:00
|
|
|
aAborted = !(*aCallback)(resolvedName, aClosure);
|
2006-11-21 09:31:04 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-10-07 18:13:40 +04:00
|
|
|
nsresult
|
|
|
|
gfxWindowsPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
|
2007-05-29 19:09:23 +04:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxPlatformFontList::PlatformFontList()->GetStandardFamilyName(aFontName, aFamilyName);
|
|
|
|
return NS_OK;
|
2006-02-01 05:35:38 +03:00
|
|
|
}
|
2007-04-02 23:06:16 +04:00
|
|
|
|
|
|
|
gfxFontGroup *
|
|
|
|
gfxWindowsPlatform::CreateFontGroup(const nsAString &aFamilies,
|
2008-10-01 07:01:53 +04:00
|
|
|
const gfxFontStyle *aStyle,
|
|
|
|
gfxUserFontSet *aUserFontSet)
|
|
|
|
{
|
2010-04-07 00:19:39 +04:00
|
|
|
return new gfxFontGroup(aFamilies, aStyle, aUserFontSet);
|
2008-10-01 07:01:53 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
gfxFontEntry*
|
2009-01-03 06:21:49 +03:00
|
|
|
gfxWindowsPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
|
|
|
const nsAString& aFontName)
|
2008-10-01 07:01:53 +04:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
return gfxPlatformFontList::PlatformFontList()->LookupLocalFont(aProxyEntry,
|
|
|
|
aFontName);
|
2008-10-01 07:01:53 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
gfxFontEntry*
|
2008-12-06 02:19:27 +03:00
|
|
|
gfxWindowsPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
2008-10-29 21:09:50 +03:00
|
|
|
const PRUint8 *aFontData, PRUint32 aLength)
|
2008-10-01 07:01:53 +04:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
return gfxPlatformFontList::PlatformFontList()->MakePlatformFont(aProxyEntry,
|
|
|
|
aFontData,
|
|
|
|
aLength);
|
2008-10-01 07:01:53 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2008-10-01 07:01:53 +04:00
|
|
|
gfxWindowsPlatform::IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags)
|
|
|
|
{
|
2009-01-13 08:16:58 +03:00
|
|
|
// check for strange format flags
|
|
|
|
NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED),
|
|
|
|
"strange font format hint set");
|
|
|
|
|
|
|
|
// accept supported formats
|
2009-09-17 15:03:12 +04:00
|
|
|
if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_WOFF |
|
|
|
|
gfxUserFontSet::FLAG_FORMAT_OPENTYPE |
|
2009-01-13 08:16:58 +03:00
|
|
|
gfxUserFontSet::FLAG_FORMAT_TRUETYPE)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2008-10-01 07:01:53 +04:00
|
|
|
}
|
|
|
|
|
2009-01-13 08:16:58 +03:00
|
|
|
// reject all other formats, known and unknown
|
|
|
|
if (aFormatFlags != 0) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2008-10-01 07:01:53 +04:00
|
|
|
}
|
|
|
|
|
2009-01-13 08:16:58 +03:00
|
|
|
// no format hint set, need to look at data
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2007-04-02 23:06:16 +04:00
|
|
|
}
|
2007-05-30 04:07:03 +04:00
|
|
|
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxFontFamily *
|
2008-03-19 03:06:55 +03:00
|
|
|
gfxWindowsPlatform::FindFontFamily(const nsAString& aName)
|
2007-05-30 04:07:03 +04:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
return gfxPlatformFontList::PlatformFontList()->FindFamily(aName);
|
2008-03-19 03:06:55 +03:00
|
|
|
}
|
|
|
|
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxFontEntry *
|
2008-03-27 00:32:51 +03:00
|
|
|
gfxWindowsPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
|
2008-03-19 03:06:55 +03:00
|
|
|
{
|
2009-10-07 18:13:40 +04:00
|
|
|
nsRefPtr<gfxFontFamily> ff = FindFontFamily(aName);
|
2008-03-19 03:06:55 +03:00
|
|
|
if (!ff)
|
|
|
|
return nsnull;
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aNeedsBold;
|
2009-10-07 18:13:40 +04:00
|
|
|
return ff->FindFontForStyle(aFontStyle, aNeedsBold);
|
2007-05-30 04:07:03 +04:00
|
|
|
}
|
2007-07-24 02:02:17 +04:00
|
|
|
|
2009-04-07 20:02:11 +04:00
|
|
|
qcms_profile*
|
2007-07-24 02:02:17 +04:00
|
|
|
gfxWindowsPlatform::GetPlatformCMSOutputProfile()
|
|
|
|
{
|
2010-01-24 16:58:31 +03:00
|
|
|
WCHAR str[MAX_PATH];
|
|
|
|
DWORD size = MAX_PATH;
|
|
|
|
BOOL res;
|
2007-07-24 02:02:17 +04:00
|
|
|
|
|
|
|
HDC dc = GetDC(nsnull);
|
2010-01-06 02:39:56 +03:00
|
|
|
if (!dc)
|
|
|
|
return nsnull;
|
|
|
|
|
2010-01-24 16:58:31 +03:00
|
|
|
#if _MSC_VER
|
2010-01-06 02:39:56 +03:00
|
|
|
__try {
|
2010-01-24 16:58:31 +03:00
|
|
|
res = GetICMProfileW(dc, &size, (LPWSTR)&str);
|
2010-01-06 02:39:56 +03:00
|
|
|
} __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
|
2010-01-24 16:58:31 +03:00
|
|
|
res = FALSE;
|
2010-01-06 02:39:56 +03:00
|
|
|
}
|
2010-01-24 16:58:31 +03:00
|
|
|
#else
|
|
|
|
res = GetICMProfileW(dc, &size, (LPWSTR)&str);
|
|
|
|
#endif
|
2010-01-06 02:39:56 +03:00
|
|
|
|
2007-07-24 02:02:17 +04:00
|
|
|
ReleaseDC(nsnull, dc);
|
2010-01-24 16:58:31 +03:00
|
|
|
if (!res)
|
|
|
|
return nsnull;
|
2007-07-24 02:02:17 +04:00
|
|
|
|
2011-03-30 21:40:47 +04:00
|
|
|
qcms_profile* profile = qcms_profile_from_unicode_path(str);
|
2007-07-24 02:02:17 +04:00
|
|
|
#ifdef DEBUG_tor
|
|
|
|
if (profile)
|
|
|
|
fprintf(stderr,
|
|
|
|
"ICM profile read from %s successfully\n",
|
|
|
|
NS_ConvertUTF16toUTF8(str).get());
|
|
|
|
#endif
|
|
|
|
return profile;
|
|
|
|
}
|
2007-08-24 23:41:16 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxWindowsPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *array)
|
2007-08-24 23:41:16 +04:00
|
|
|
{
|
2008-03-19 03:06:55 +03:00
|
|
|
return mPrefFonts.Get(aKey, array);
|
2007-08-24 23:41:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-10-07 18:13:40 +04:00
|
|
|
gfxWindowsPlatform::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& array)
|
2007-08-24 23:41:16 +04:00
|
|
|
{
|
2008-03-19 03:06:55 +03:00
|
|
|
mPrefFonts.Put(aKey, array);
|
2007-08-24 23:41:16 +04:00
|
|
|
}
|
2008-04-04 06:01:22 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2010-05-27 09:05:30 +04:00
|
|
|
gfxWindowsPlatform::UseClearTypeForDownloadableFonts()
|
|
|
|
{
|
|
|
|
if (mUseClearTypeForDownloadableFonts == UNINITIALIZED_VALUE) {
|
2011-09-29 10:19:26 +04:00
|
|
|
mUseClearTypeForDownloadableFonts = Preferences::GetBool(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, true);
|
2010-05-27 09:05:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return mUseClearTypeForDownloadableFonts;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2010-05-27 09:05:30 +04:00
|
|
|
gfxWindowsPlatform::UseClearTypeAlways()
|
|
|
|
{
|
|
|
|
if (mUseClearTypeAlways == UNINITIALIZED_VALUE) {
|
2011-09-29 10:19:26 +04:00
|
|
|
mUseClearTypeAlways = Preferences::GetBool(GFX_USE_CLEARTYPE_ALWAYS, false);
|
2010-05-27 09:05:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return mUseClearTypeAlways;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32
|
2011-02-25 04:31:16 +03:00
|
|
|
gfxWindowsPlatform::WindowsOSVersion(PRInt32 *aBuildNum)
|
2010-05-27 09:05:30 +04:00
|
|
|
{
|
|
|
|
static PRInt32 winVersion = UNINITIALIZED_VALUE;
|
2011-02-25 04:31:16 +03:00
|
|
|
static PRInt32 buildNum = UNINITIALIZED_VALUE;
|
2010-05-27 09:05:30 +04:00
|
|
|
|
|
|
|
OSVERSIONINFO vinfo;
|
|
|
|
|
|
|
|
if (winVersion == UNINITIALIZED_VALUE) {
|
|
|
|
vinfo.dwOSVersionInfoSize = sizeof (vinfo);
|
|
|
|
if (!GetVersionEx(&vinfo)) {
|
|
|
|
winVersion = kWindowsUnknown;
|
2011-02-25 04:31:16 +03:00
|
|
|
buildNum = 0;
|
2010-05-27 09:05:30 +04:00
|
|
|
} else {
|
|
|
|
winVersion = PRInt32(vinfo.dwMajorVersion << 16) + vinfo.dwMinorVersion;
|
2011-02-25 04:31:16 +03:00
|
|
|
buildNum = PRInt32(vinfo.dwBuildNumber);
|
2010-05-27 09:05:30 +04:00
|
|
|
}
|
|
|
|
}
|
2011-02-25 04:31:16 +03:00
|
|
|
|
|
|
|
if (aBuildNum) {
|
|
|
|
*aBuildNum = buildNum;
|
|
|
|
}
|
|
|
|
|
2010-05-27 09:05:30 +04:00
|
|
|
return winVersion;
|
|
|
|
}
|
|
|
|
|
2011-01-14 15:57:17 +03:00
|
|
|
void
|
2011-01-28 13:35:40 +03:00
|
|
|
gfxWindowsPlatform::GetDLLVersion(const PRUnichar *aDLLPath, nsAString& aVersion)
|
2011-01-14 15:57:17 +03:00
|
|
|
{
|
|
|
|
DWORD versInfoSize, vers[4] = {0};
|
|
|
|
// version info not available case
|
|
|
|
aVersion.Assign(NS_LITERAL_STRING("0.0.0.0"));
|
|
|
|
versInfoSize = GetFileVersionInfoSizeW(aDLLPath, NULL);
|
|
|
|
nsAutoTArray<BYTE,512> versionInfo;
|
|
|
|
|
2011-02-15 05:28:51 +03:00
|
|
|
if (versInfoSize == 0 ||
|
|
|
|
!versionInfo.AppendElements(PRUint32(versInfoSize)))
|
|
|
|
{
|
2011-01-14 15:57:17 +03:00
|
|
|
return;
|
|
|
|
}
|
2011-02-15 05:28:51 +03:00
|
|
|
|
2011-01-28 13:35:40 +03:00
|
|
|
if (!GetFileVersionInfoW(aDLLPath, 0, versInfoSize,
|
2011-02-15 05:28:51 +03:00
|
|
|
LPBYTE(versionInfo.Elements())))
|
|
|
|
{
|
2011-01-14 15:57:17 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-02-15 05:28:51 +03:00
|
|
|
UINT len = 0;
|
|
|
|
VS_FIXEDFILEINFO *fileInfo = nsnull;
|
2011-01-14 15:57:17 +03:00
|
|
|
if (!VerQueryValue(LPBYTE(versionInfo.Elements()), TEXT("\\"),
|
2011-02-15 05:28:51 +03:00
|
|
|
(LPVOID *)&fileInfo, &len) ||
|
|
|
|
len == 0 ||
|
|
|
|
fileInfo == nsnull)
|
|
|
|
{
|
2011-01-14 15:57:17 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD fileVersMS = fileInfo->dwFileVersionMS;
|
|
|
|
DWORD fileVersLS = fileInfo->dwFileVersionLS;
|
|
|
|
|
|
|
|
vers[0] = HIWORD(fileVersMS);
|
|
|
|
vers[1] = LOWORD(fileVersMS);
|
|
|
|
vers[2] = HIWORD(fileVersLS);
|
|
|
|
vers[3] = LOWORD(fileVersLS);
|
|
|
|
|
|
|
|
char buf[256];
|
|
|
|
sprintf(buf, "%d.%d.%d.%d", vers[0], vers[1], vers[2], vers[3]);
|
|
|
|
aVersion.Assign(NS_ConvertUTF8toUTF16(buf));
|
|
|
|
}
|
|
|
|
|
2011-05-11 04:30:20 +04:00
|
|
|
void
|
|
|
|
gfxWindowsPlatform::GetCleartypeParams(nsTArray<ClearTypeParameterInfo>& aParams)
|
|
|
|
{
|
|
|
|
HKEY hKey, subKey;
|
|
|
|
DWORD i, rv, size, type;
|
|
|
|
WCHAR displayName[256], subkeyName[256];
|
|
|
|
|
|
|
|
aParams.Clear();
|
|
|
|
|
|
|
|
// construct subkeys based on HKLM subkeys, assume they are same for HKCU
|
|
|
|
rv = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
|
|
L"Software\\Microsoft\\Avalon.Graphics",
|
|
|
|
0, KEY_READ, &hKey);
|
|
|
|
|
|
|
|
if (rv != ERROR_SUCCESS) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// enumerate over subkeys
|
|
|
|
for (i = 0, rv = ERROR_SUCCESS; rv != ERROR_NO_MORE_ITEMS; i++) {
|
2011-10-11 09:50:08 +04:00
|
|
|
size = ArrayLength(displayName);
|
2011-05-11 04:30:20 +04:00
|
|
|
rv = RegEnumKeyExW(hKey, i, displayName, &size, NULL, NULL, NULL, NULL);
|
|
|
|
if (rv != ERROR_SUCCESS) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ClearTypeParameterInfo ctinfo;
|
|
|
|
ctinfo.displayName.Assign(displayName);
|
|
|
|
|
|
|
|
DWORD subrv, value;
|
|
|
|
bool foundData = false;
|
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
swprintf_s(subkeyName, ArrayLength(subkeyName),
|
2011-05-11 04:30:20 +04:00
|
|
|
L"Software\\Microsoft\\Avalon.Graphics\\%s", displayName);
|
|
|
|
|
|
|
|
// subkey for gamma, pixel structure
|
|
|
|
subrv = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
|
|
subkeyName, 0, KEY_QUERY_VALUE, &subKey);
|
|
|
|
|
|
|
|
if (subrv == ERROR_SUCCESS) {
|
|
|
|
size = sizeof(value);
|
|
|
|
subrv = RegQueryValueExW(subKey, L"GammaLevel", NULL, &type,
|
|
|
|
(LPBYTE)&value, &size);
|
|
|
|
if (subrv == ERROR_SUCCESS && type == REG_DWORD) {
|
|
|
|
foundData = true;
|
|
|
|
ctinfo.gamma = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
size = sizeof(value);
|
|
|
|
subrv = RegQueryValueExW(subKey, L"PixelStructure", NULL, &type,
|
|
|
|
(LPBYTE)&value, &size);
|
|
|
|
if (subrv == ERROR_SUCCESS && type == REG_DWORD) {
|
|
|
|
foundData = true;
|
|
|
|
ctinfo.pixelStructure = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(subKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// subkey for cleartype level, enhanced contrast
|
|
|
|
subrv = RegOpenKeyExW(HKEY_CURRENT_USER,
|
|
|
|
subkeyName, 0, KEY_QUERY_VALUE, &subKey);
|
|
|
|
|
|
|
|
if (subrv == ERROR_SUCCESS) {
|
|
|
|
size = sizeof(value);
|
|
|
|
subrv = RegQueryValueExW(subKey, L"ClearTypeLevel", NULL, &type,
|
|
|
|
(LPBYTE)&value, &size);
|
|
|
|
if (subrv == ERROR_SUCCESS && type == REG_DWORD) {
|
|
|
|
foundData = true;
|
|
|
|
ctinfo.clearTypeLevel = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
size = sizeof(value);
|
|
|
|
subrv = RegQueryValueExW(subKey, L"EnhancedContrastLevel",
|
|
|
|
NULL, &type, (LPBYTE)&value, &size);
|
|
|
|
if (subrv == ERROR_SUCCESS && type == REG_DWORD) {
|
|
|
|
foundData = true;
|
|
|
|
ctinfo.enhancedContrast = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(subKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (foundData) {
|
|
|
|
aParams.AppendElement(ctinfo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
|
|
|
2010-05-27 09:05:30 +04:00
|
|
|
void
|
2011-06-12 06:30:16 +04:00
|
|
|
gfxWindowsPlatform::FontsPrefsChanged(const char *aPref)
|
2010-05-27 09:05:30 +04:00
|
|
|
{
|
2011-09-29 10:19:26 +04:00
|
|
|
bool clearTextFontCaches = true;
|
2010-05-27 09:05:30 +04:00
|
|
|
|
2011-06-12 06:30:16 +04:00
|
|
|
gfxPlatform::FontsPrefsChanged(aPref);
|
2010-05-27 09:05:30 +04:00
|
|
|
|
|
|
|
if (!aPref) {
|
|
|
|
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
|
|
|
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
|
|
|
} else if (!strcmp(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, aPref)) {
|
|
|
|
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
|
|
|
} else if (!strcmp(GFX_USE_CLEARTYPE_ALWAYS, aPref)) {
|
|
|
|
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
2011-04-21 10:29:50 +04:00
|
|
|
} else if (!strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) {
|
2011-06-12 06:30:16 +04:00
|
|
|
SetupClearTypeParams();
|
2010-05-27 09:05:30 +04:00
|
|
|
} else {
|
2011-10-17 18:59:28 +04:00
|
|
|
clearTextFontCaches = false;
|
2010-05-27 09:05:30 +04:00
|
|
|
}
|
|
|
|
|
2010-06-09 04:33:13 +04:00
|
|
|
if (clearTextFontCaches) {
|
2010-05-27 09:05:30 +04:00
|
|
|
gfxFontCache *fc = gfxFontCache::GetCache();
|
2010-06-09 04:33:13 +04:00
|
|
|
if (fc) {
|
|
|
|
fc->Flush();
|
|
|
|
}
|
2010-05-27 09:05:30 +04:00
|
|
|
}
|
2010-08-14 16:43:27 +04:00
|
|
|
}
|
2011-03-02 04:00:33 +03:00
|
|
|
|
2011-04-21 10:29:50 +04:00
|
|
|
void
|
2011-06-12 06:30:16 +04:00
|
|
|
gfxWindowsPlatform::SetupClearTypeParams()
|
2011-04-21 10:29:50 +04:00
|
|
|
{
|
|
|
|
#if CAIRO_HAS_DWRITE_FONT
|
|
|
|
if (GetDWriteFactory()) {
|
|
|
|
// any missing prefs will default to invalid (-1) and be ignored;
|
|
|
|
// out-of-range values will also be ignored
|
|
|
|
FLOAT gamma = -1.0;
|
|
|
|
FLOAT contrast = -1.0;
|
|
|
|
FLOAT level = -1.0;
|
|
|
|
int geometry = -1;
|
|
|
|
int mode = -1;
|
|
|
|
PRInt32 value;
|
2011-06-12 06:30:16 +04:00
|
|
|
if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_GAMMA, &value))) {
|
2011-04-21 10:29:50 +04:00
|
|
|
if (value >= 1000 && value <= 2200) {
|
2011-05-11 04:30:20 +04:00
|
|
|
gamma = FLOAT(value / 1000.0);
|
2011-04-21 10:29:50 +04:00
|
|
|
}
|
|
|
|
}
|
2011-06-12 06:30:16 +04:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_CONTRAST, &value))) {
|
2011-04-21 10:29:50 +04:00
|
|
|
if (value >= 0 && value <= 1000) {
|
2011-05-11 04:30:20 +04:00
|
|
|
contrast = FLOAT(value / 100.0);
|
2011-04-21 10:29:50 +04:00
|
|
|
}
|
|
|
|
}
|
2011-06-12 06:30:16 +04:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_LEVEL, &value))) {
|
2011-04-21 10:29:50 +04:00
|
|
|
if (value >= 0 && value <= 100) {
|
2011-05-11 04:30:20 +04:00
|
|
|
level = FLOAT(value / 100.0);
|
2011-04-21 10:29:50 +04:00
|
|
|
}
|
|
|
|
}
|
2011-06-12 06:30:16 +04:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_STRUCTURE, &value))) {
|
2011-04-21 10:29:50 +04:00
|
|
|
if (value >= 0 && value <= 2) {
|
|
|
|
geometry = value;
|
|
|
|
}
|
|
|
|
}
|
2011-06-12 06:30:16 +04:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_MODE, &value))) {
|
2011-04-21 10:29:50 +04:00
|
|
|
if (value >= 0 && value <= 5) {
|
|
|
|
mode = value;
|
|
|
|
}
|
|
|
|
}
|
2011-06-12 06:30:16 +04:00
|
|
|
|
2011-04-21 10:29:50 +04:00
|
|
|
cairo_dwrite_set_cleartype_params(gamma, contrast, level, geometry, mode);
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case DWRITE_RENDERING_MODE_ALIASED:
|
|
|
|
case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC:
|
|
|
|
mMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
|
|
|
|
break;
|
|
|
|
case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL:
|
|
|
|
mMeasuringMode = DWRITE_MEASURING_MODE_GDI_NATURAL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-03-02 04:00:33 +03:00
|
|
|
bool
|
|
|
|
gfxWindowsPlatform::IsOptimus()
|
|
|
|
{
|
|
|
|
return GetModuleHandleA("nvumdshim.dll");
|
|
|
|
}
|