void nf_free(nf_font_t font)
{
	if(font)
	{
		IDWriteTextFormat * format = (IDWriteTextFormat*)font;
		format->Release();
	}

	nf_ctx_free();
}
Example #2
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;
}
Example #3
0
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;
}
Example #4
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);
}
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();
}
Example #6
0
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();
}