예제 #1
0
int CDirectWriteRenderer::GetFitCharCount(LPCWSTR pText, int Length, int Width, CDirectWriteFont &Font)
{
	if (pText == nullptr || Length == 0)
		return 0;
	if (m_pRenderTarget == nullptr)
		return 0;

	int FitCharCount = 0;

	IDWriteFactory *pFactory = m_System.GetDWriteFactory();

	if (pFactory != nullptr) {
		IDWriteTextFormat *pTextFormat = Font.GetTextFormat();

		if (pTextFormat != nullptr) {
			IDWriteTextLayout *pTextLayout;

			pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
			pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
			if (Length < 0)
				Length = ::lstrlenW(pText);
			HRESULT hr = pFactory->CreateTextLayout(
				pText,
				Length,
				pTextFormat,
				static_cast<float>(Width),
				m_pRenderTarget->GetSize().height,
				&pTextLayout);
			if (SUCCEEDED(hr)) {
				Util::CTempBuffer<DWRITE_CLUSTER_METRICS, 256> ClusterMetrics(Length);
				UINT32 ClusterCount;

				hr = pTextLayout->GetClusterMetrics(ClusterMetrics.GetBuffer(), Length, &ClusterCount);
				if (SUCCEEDED(hr)) {
					float Pos = 0.0f;

					for (UINT32 i = 0; i < ClusterCount; i++) {
						Pos += ClusterMetrics[i].width;
						if (static_cast<int>(std::ceil(Pos)) > Width)
							break;
						FitCharCount += ClusterMetrics[i].length;
					}
				}

				pTextLayout->Release();
			}

			pTextFormat->Release();
		}

		pFactory->Release();
	}

	return FitCharCount;
}
예제 #2
0
bool CDirectWriteRenderer::GetTextMetrics(
	LPCWSTR pText, int Length, CDirectWriteFont &Font, TextMetrics *pMetrics)
{
	if (pText == nullptr || pMetrics == nullptr)
		return false;
	if (m_pRenderTarget == nullptr)
		return false;

	HRESULT hr = E_UNEXPECTED;
	IDWriteFactory *pFactory = m_System.GetDWriteFactory();

	if (pFactory != nullptr) {
		IDWriteTextFormat *pTextFormat = Font.GetTextFormat();

		if (pTextFormat != nullptr) {
			D2D1_SIZE_F Size;
			IDWriteTextLayout *pTextLayout;

			pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
			pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
			if (Length < 0)
				Length = ::lstrlenW(pText);
			Size = m_pRenderTarget->GetSize();
			hr = pFactory->CreateTextLayout(
				pText,
				Length,
				pTextFormat,
				Size.width,
				Size.height,
				&pTextLayout);
			if (SUCCEEDED(hr)) {
				DWRITE_TEXT_METRICS Metrics;

				hr = pTextLayout->GetMetrics(&Metrics);
				if (SUCCEEDED(hr)) {
					pMetrics->Width = Metrics.width;
					pMetrics->WidthIncludingTrailingWhitespace = Metrics.widthIncludingTrailingWhitespace;
					pMetrics->Height = Metrics.height;
				}

				pTextLayout->Release();
			}

			pTextFormat->Release();
		}

		pFactory->Release();
	}

	return SUCCEEDED(hr);
}
예제 #3
0
bool CDirectWriteRenderer::UpdateRenderingParams()
{
	if (m_pRenderTarget == nullptr)
		return false;

	bool fUpdated = false;
	IDWriteFactory *pFactory = m_System.GetDWriteFactory();

	if (pFactory != nullptr) {
		IDWriteRenderingParams *pRenderingParams;

		HRESULT hr = pFactory->CreateMonitorRenderingParams(m_hMonitor, &pRenderingParams);
		if (SUCCEEDED(hr)) {
			if (m_RenderingParams.Mask != 0) {
				IDWriteRenderingParams *pCustomRenderingParams;
				hr = pFactory->CreateCustomRenderingParams(
					(m_RenderingParams.Mask & RenderingParams::PARAM_GAMMA) != 0 ?
						m_RenderingParams.Gamma : pRenderingParams->GetGamma(),
					(m_RenderingParams.Mask & RenderingParams::PARAM_ENHANCED_CONTRAST) != 0 ?
						m_RenderingParams.EnhancedContrast : pRenderingParams->GetEnhancedContrast(),
					(m_RenderingParams.Mask & RenderingParams::PARAM_CLEARTYPE_LEVEL) != 0 ?
						m_RenderingParams.ClearTypeLevel : pRenderingParams->GetClearTypeLevel(),
					(m_RenderingParams.Mask & RenderingParams::PARAM_PIXEL_GEOMETRY) != 0 ?
						m_RenderingParams.PixelGeometry : pRenderingParams->GetPixelGeometry(),
					(m_RenderingParams.Mask & RenderingParams::PARAM_RENDERING_MODE) != 0 ?
						m_RenderingParams.RenderingMode : pRenderingParams->GetRenderingMode(),
					&pCustomRenderingParams);
				if (SUCCEEDED(hr)) {
					m_pRenderTarget->SetTextRenderingParams(pCustomRenderingParams);
					pCustomRenderingParams->Release();
				}
			} else {
				m_pRenderTarget->SetTextRenderingParams(pRenderingParams);
			}

			if (SUCCEEDED(hr))
				fUpdated = true;

			pRenderingParams->Release();
		}

		pFactory->Release();
	}

	return fUpdated;
}
예제 #4
0
bool CDirectWriteFont::Create(CDirectWriteRenderer &Renderer, const LOGFONT &lf)
{
	Destroy();

	IDWriteFactory *pFactory = Renderer.GetSystem().GetDWriteFactory();

	if (pFactory == nullptr)
		return false;

	float FontSize;
	if (lf.lfHeight < 0 || Renderer.GetDC() == nullptr) {
		FontSize = static_cast<float>(std::abs(lf.lfHeight));
	} else {
		HDC hdc = Renderer.GetDC();
		HFONT hfont = ::CreateFontIndirect(&lf);
		HGDIOBJ hOldFont = ::SelectObject(hdc, hfont);
		TEXTMETRIC tm;
		::GetTextMetrics(hdc, &tm);
		FontSize = static_cast<float>(tm.tmHeight - tm.tmInternalLeading);
		::SelectObject(hdc, hOldFont);
		::DeleteObject(hfont);
	}

	IDWriteTextFormat *pTextFormat;
	HRESULT hr = pFactory->CreateTextFormat(
		lf.lfFaceName,
		nullptr,
		static_cast<DWRITE_FONT_WEIGHT>(lf.lfWeight),
		lf.lfItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
		DWRITE_FONT_STRETCH_NORMAL,
		FontSize,
		L"",
		&pTextFormat);
	if (SUCCEEDED(hr)) {
		m_pTextFormat = pTextFormat;
		m_LogFont = lf;
	}

	pFactory->Release();

	return true;
}
void
gfxWindowsPlatform::UpdateRenderMode()
{
/* Pick the default render mode for
 * desktop.
 */
    mRenderMode = RENDER_GDI;

    OSVERSIONINFOA versionInfo;
    versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
    ::GetVersionExA(&versionInfo);
    bool isVistaOrHigher = versionInfo.dwMajorVersion >= 6;

    bool safeMode = false;
    nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
    if (xr)
      xr->GetInSafeMode(&safeMode);

    mUseDirectWrite = Preferences::GetBool("gfx.font_rendering.directwrite.enabled", false);

#ifdef CAIRO_HAS_D2D_SURFACE
    bool d2dDisabled = false;
    bool d2dForceEnabled = false;
    bool d2dBlocked = false;

    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
    if (gfxInfo) {
        PRInt32 status;
        if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT2D, &status))) {
            if (status != nsIGfxInfo::FEATURE_NO_INFO) {
                d2dBlocked = true;
            }
        }
    }

    d2dDisabled = Preferences::GetBool("gfx.direct2d.disabled", false);
    d2dForceEnabled = Preferences::GetBool("gfx.direct2d.force-enabled", false);

    // In Metro mode there is no fallback available
    d2dForceEnabled |= IsRunningInWindows8Metro();

    bool tryD2D = !d2dBlocked || d2dForceEnabled;

    // Do not ever try if d2d is explicitly disabled,
    // or if we're not using DWrite fonts.
    if (d2dDisabled || mUsingGDIFonts) {
        tryD2D = false;
    }

    if (isVistaOrHigher  && !safeMode && tryD2D) {
        VerifyD2DDevice(d2dForceEnabled);
        if (mD2DDevice) {
            mRenderMode = RENDER_DIRECT2D;
            mUseDirectWrite = true;
        }
    } else {
        mD2DDevice = nullptr;
    }
#endif

#ifdef CAIRO_HAS_DWRITE_FONT
    // Enable when it's preffed on -and- we're using Vista or higher. Or when
    // we're going to use D2D.
    if (!mDWriteFactory && (mUseDirectWrite && isVistaOrHigher)) {
        mozilla::ScopedGfxFeatureReporter reporter("DWrite");
        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();

            if (SUCCEEDED(hr)) {
                hr = mDWriteFactory->CreateTextAnalyzer(
                    getter_AddRefs(mDWriteAnalyzer));
            }

            SetupClearTypeParams();

            if (hr == S_OK)
              reporter.SetSuccessful();
        }
    }
#endif

    PRUint32 backendMask = 1 << BACKEND_CAIRO;
    if (mRenderMode == RENDER_DIRECT2D) {
      backendMask |= 1 << BACKEND_DIRECT2D;
    } else {
      backendMask |= 1 << BACKEND_SKIA;
    }
    InitCanvasBackend(backendMask);
}