void nf_free(nf_font_t font) { if(font) { IDWriteTextFormat * format = (IDWriteTextFormat*)font; format->Release(); } nf_ctx_free(); }
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::DrawText( LPCWSTR pText, int Length, const RECT &Rect, CDirectWriteFont &Font, CDirectWriteBrush &Brush, unsigned int Flags) { if (pText == nullptr) return false; if (m_pRenderTarget == nullptr) return false; bool fOK = false; IDWriteTextFormat *pTextFormat = Font.GetTextFormat(); if (pTextFormat != nullptr) { ID2D1Brush *pBrush = Brush.GetBrush(); if (pBrush != nullptr) { pTextFormat->SetTextAlignment( (Flags & DRAW_TEXT_ALIGN_HORZ_CENTER) != 0 ? DWRITE_TEXT_ALIGNMENT_CENTER : (Flags & DRAW_TEXT_ALIGN_RIGHT) != 0 ? DWRITE_TEXT_ALIGNMENT_TRAILING : ((Flags & DRAW_TEXT_ALIGN_JUSTIFIED) != 0 && Util::OS::IsWindows8OrLater()) ? DWRITE_TEXT_ALIGNMENT_JUSTIFIED : DWRITE_TEXT_ALIGNMENT_LEADING); pTextFormat->SetParagraphAlignment( (Flags & DRAW_TEXT_ALIGN_VERT_CENTER) != 0 ? DWRITE_PARAGRAPH_ALIGNMENT_CENTER : (Flags & DRAW_TEXT_ALIGN_BOTTOM) != 0 ? DWRITE_PARAGRAPH_ALIGNMENT_FAR : DWRITE_PARAGRAPH_ALIGNMENT_NEAR); pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); DWRITE_TRIMMING Trimming = {DWRITE_TRIMMING_GRANULARITY_NONE, 0, 0}; pTextFormat->SetTrimming(&Trimming, nullptr); m_pRenderTarget->DrawText( pText, Length >= 0 ? Length : ::lstrlenW(pText), pTextFormat, D2DRectF(Rect), pBrush); fOK = true; pBrush->Release(); } pTextFormat->Release(); } return fOK; }
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); }
void ImageWindow::OnPaint() { Mutex::Locker locker( frontBufferMutex ); // Nothing to do if( frames.IsEmpty() ) return; if( !frames.PeekFront(0)->ready ) return; Ptr<Frame> currentFrame = frames.PopFront(); Ptr<Frame> nextFrame = NULL; if( !frames.IsEmpty() ) nextFrame = frames.PeekFront(0); while( nextFrame && nextFrame->ready ) { // Free up the current frame since it's been removed from the deque currentFrame = frames.PopFront(); if( frames.IsEmpty() ) break; nextFrame = frames.PeekFront(0); } if( currentFrame->imageData ) greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width ); if( currentFrame->colorImageData ) colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch ); pRT->BeginDraw(); pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) ); // This will mirror our image D2D1_MATRIX_3X2_F m; m._11 = -1; m._12 = 0; m._21 = 0; m._22 = 1; m._31 = 0; m._32 = 0; pRT->SetTransform( m ); ID2D1SolidColorBrush* whiteBrush; pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush ); if( currentFrame->imageData ) { pRT->FillOpacityMask( greyBitmap, whiteBrush, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), //D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) ); } else if( currentFrame->colorImageData ) { pRT->DrawBitmap( colorBitmap, D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) ); } pRT->SetTransform(D2D1::Matrix3x2F::Identity()); whiteBrush->Release(); Array<CirclePlot>::Iterator it; for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it ) { ID2D1SolidColorBrush* aBrush; pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush ); D2D1_ELLIPSE ellipse; ellipse.point.x = it->x; ellipse.point.y = it->y; ellipse.radiusX = it->radius; ellipse.radiusY = it->radius; if( it->fill ) pRT->FillEllipse( &ellipse, aBrush ); else pRT->DrawEllipse( &ellipse, aBrush ); aBrush->Release(); } static const WCHAR msc_fontName[] = L"Verdana"; static const FLOAT msc_fontSize = 20; IDWriteTextFormat* textFormat = NULL; // Create a DirectWrite text format object. pDWriteFactory->CreateTextFormat( msc_fontName, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, msc_fontSize, L"", //locale &textFormat ); D2D1_SIZE_F renderTargetSize = pRT->GetSize(); Array<TextPlot>::Iterator textIt; for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt ) { ID2D1SolidColorBrush* aBrush; pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush ); WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(), sizeof( WCHAR ) ); for( unsigned i = 0; i < textIt->text.GetLength(); ++i ) { tmpString[i] = (WCHAR)textIt->text.GetCharAt( i ); } pRT->DrawText( tmpString, (UINT32)textIt->text.GetLength(), textFormat, D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush ); free( tmpString ); aBrush->Release(); } if( textFormat ) textFormat->Release(); pRT->EndDraw(); pRT->Flush(); }
static void fontDialogDrawSampleText(struct fontDialog *f, ID2D1RenderTarget *rt) { D2D1_COLOR_F color; D2D1_BRUSH_PROPERTIES props; ID2D1SolidColorBrush *black; IDWriteFont *font; IDWriteLocalizedStrings *sampleStrings; BOOL exists; WCHAR *sample; WCHAR *family; IDWriteTextFormat *format; D2D1_RECT_F rect; HRESULT hr; color.r = 0.0; color.g = 0.0; color.b = 0.0; color.a = 1.0; ZeroMemory(&props, sizeof (D2D1_BRUSH_PROPERTIES)); props.opacity = 1.0; // identity matrix props.transform._11 = 1; props.transform._22 = 1; hr = rt->CreateSolidColorBrush( &color, &props, &black); if (hr != S_OK) logHRESULT(L"error creating solid brush", hr); font = (IDWriteFont *) cbGetItemData(f->styleCombobox, (WPARAM) f->curStyle); hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT, &sampleStrings, &exists); if (hr != S_OK) exists = FALSE; if (exists) { sample = fontCollectionCorrectString(f->fc, sampleStrings); sampleStrings->Release(); } else sample = L"The quick brown fox jumps over the lazy dog."; // DirectWrite doesn't allow creating a text format from a font; we need to get this ourselves family = cbGetItemText(f->familyCombobox, f->curFamily); hr = dwfactory->CreateTextFormat(family, NULL, font->GetWeight(), font->GetStyle(), font->GetStretch(), // typographic points are 1/72 inch; this parameter is 1/96 inch // fortunately Microsoft does this too, in https://msdn.microsoft.com/en-us/library/windows/desktop/dd371554%28v=vs.85%29.aspx f->curSize * (96.0 / 72.0), // see http://stackoverflow.com/questions/28397971/idwritefactorycreatetextformat-failing and https://msdn.microsoft.com/en-us/library/windows/desktop/dd368203.aspx // TODO use the current locale again? L"", &format); if (hr != S_OK) logHRESULT(L"error creating IDWriteTextFormat", hr); uiFree(family); rect.left = 0; rect.top = 0; rect.right = realGetSize(rt).width; rect.bottom = realGetSize(rt).height; rt->DrawText(sample, wcslen(sample), format, &rect, black, // TODO really? D2D1_DRAW_TEXT_OPTIONS_NONE, DWRITE_MEASURING_MODE_NATURAL); format->Release(); if (exists) uiFree(sample); black->Release(); }