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; }
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); }
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; }
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); }