F.R.I.D.A.Y.

DirectWrite - 텍스트 출력하기 1 본문

DEV/Direct2D

DirectWrite - 텍스트 출력하기 1

F.R.I.D.A.Y. 2021. 4. 10. 21:52
반응형

Direct2D에서 텍스트 출력하기


기본 환경 구성

 DirectWrite를 사용할 수 있는 환경을 구성합니다.

 OnCreate 함수 바인딩

 먼저 Direct2D를 사용할 수 있도록 구성하겠습니다. 메시지 핸들링을 기본 구조로 사용하므로 WM_CREATE 메시지에 대해 반응하는 함수 OnCreate 함수를 구성하고, 이어서 작성하겠습니다.

 이렇게 만들어진 OnCreate 함수를 HandleMessage 함수에 바인딩 하겠습니다.

LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_CLOSE) {
		PostQuitMessage(0);
		return 0;
	}
	else if (uMsg == WM_DESTROY) {
		DestroyWindow(hWnd);
		return 0;
	}

	switch (uMsg) {
		case WM_CREATE:
			{
				return OnCreate();
			}
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

 

팩토리 & 렌더타겟 생성

 이어서 ID2D1Factory와 ID2D1HwndRenderTarget 객체를 생성하겠습니다.

 

종속성 추가

 mainWin.h 파일의 상단에 아래 내용을 추가합니다.

#include <d2d1.h>
#pragma comment(lib, "d2d1")

 d2d1.h 헤더는 Direct2D를 사용할 때 필요한 주요 인터페이스를 담고 있으며, 그 아래 pragma 구문은 Visual Studio에서 제공하는 라이브러리를 링커에 추가하는 컴파일 명령어입니다.

 

멤버 변수 생성

 다음으로 MainWindow 클래스의 멤버로 아래 내용을 추가합니다. 외부에서 접근하지 않으므로 접근 제한자는 private입니다.

	ID2D1Factory* pFactory;
	ID2D1HwndRenderTarget* pRT;

 

 OnCreate에서 초기화하겠습니다.

 

 OnCreate에서 초기화

  이제 Direct2D 리소스를 생성할 수 있도록 Factory와 HwndRenderTarget을 초기화 합니다.

	HRESULT hr = D2D1CreateFactory(
		D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory
	);

	if (SUCCEEDED(hr)) {
		RECT rc;
		GetClientRect(hWnd, &rc);
		hr = pFactory->CreateHwndRenderTarget(
			D2D1::RenderTargetProperties(),
			D2D1::HwndRenderTargetProperties(
				hWnd, D2D1::SizeU(
					rc.right - rc.left, rc.bottom - rc.top)
			), &pRT);
	}

 

 

DirectWrite 구성하기

 Direct2D에서 텍스트를 그리기 위해서는 DirectWrite라는 객체가 다시 필요합니다. DirectWrite는 아래의 객체가 필요합니다.

  • IDWriteFactory
  • IDWriteTextFormat
  • ID2D1SolidColorBrush[# ID2D1Facotry -> ID2D1HwndRenderTarget에서 이어짐]

 

 DirectWrite는 Direct2D를 사용할 때 꼭 사용하는 대상이 아니기 때문에, 아래의 추가 종속성 파일이 필요합니다.

  • dwrite.h
  • dwrite.lib

 

종속성 추가

 따라서 종속성을 추가하기 위해 아래 코드를 mainWin.h의 상단에 추가합니다.

#include <dwrite.h>
#pragma comment(lib, "dwrite")

추가된 모습

 

멤버 변수 생성

 그리고 멤버 MainWindow의 멤버 변수로 아래 내용을 추가합니다. 이 멤버들 역시 D2D 멤버[# d2d1.h 헤더로 추가할 수 있는 대상을 지칭합니다]들과 같이 접근 제한자는 private입니다.

ID2D1SolidColorBrush* pBrush;

IDwriteFactory* pWFactory;
IDWriteTextFormat* pWFormat;

 

초기화

 변수를 생성했으니 초기화를 진행합니다. 역시 OnCreate 함수에서 이어가겠습니다. 우리는 기존에 Direct2D 팩토리 및 렌더타겟을 초기화 했습니다. 이어서 초기화 하겠습니다.

		if (SUCCEEDED(hr)) {
			hr = DWriteCreateFactory(
				DWRITE_FACTORY_TYPE_SHARED,
				__uuidof(IDWriteFactory),
				reinterpret_cast<IUnknown**>(&pWFactory));
			if (FAILED(hr)) PostQuitMessage(0);

 if 구문을 너무 들어가면 들여쓰기가 많아지므로 성공을 확인하는 SUCCEEDED 매크로 대신 FAILED 매크로를 사용하겠습니다. 그리고 실패한 경우 빠르게 다시 실행할 수 있도록 프로그램을 종료하도록 PostQuitMessage를 보냅니다.

 

 이어서 브러시 객체도 초기화합니다.

			hr = pRT->CreateSolidColorBrush(
				D2D1::ColorF(
					D2D1::ColorF::Black
				), &pBrush);

			if (FAILED(hr)) PostQuitMessage(0);

 

 다음으로 IDWriteFactory에 있는 CreateTextFormat 메서드로 IDWriteTextFormat 객체도 초기화 해줍니다.

			hr = pWFactory->CreateTextFormat(
				L"D2Coding",
				nullptr,
				DWRITE_FONT_WEIGHT_NORMAL,
				DWRITE_FONT_STYLE_NORMAL,
				DWRITE_FONT_STRETCH_NORMAL,
				72.0f,
				L"ko-kr",
				&pWFormat
			);
            
			if (FAILED(hr)) PostQuitMessage(0);

 

 텍스트 및 단락 정렬은 중심으로 하겠습니다.

			hr = pWFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);

			if (FAILED(hr)) PostQuitMessage(0);

			hr = pWFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

 

더보기

# 코드 중간 점검

 여기까지 잘 따라왔다면, OnCreate 메서드에는 다음 내용이 작성되어 있습니다.

LRESULT MainWindow::OnCreate()
{
	HRESULT hr = D2D1CreateFactory(
		D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory
	);

	if (SUCCEEDED(hr)) {
		RECT rc;
		GetClientRect(hWnd, &rc);
		hr = pFactory->CreateHwndRenderTarget(
			D2D1::RenderTargetProperties(),
			D2D1::HwndRenderTargetProperties(
				hWnd, D2D1::SizeU(
					rc.right - rc.left, rc.bottom - rc.top)
			), &pRT);


		if (SUCCEEDED(hr)) {
			hr = DWriteCreateFactory(
				DWRITE_FACTORY_TYPE_SHARED,
				__uuidof(IDWriteFactory),
				reinterpret_cast<IUnknown**>(&pWFactory));
			if (FAILED(hr)) PostQuitMessage(0);


			hr = pRT->CreateSolidColorBrush(
				D2D1::ColorF(
					D2D1::ColorF::Black
				), &pBrush);

			if (FAILED(hr)) PostQuitMessage(0);

			hr = pWFactory->CreateTextFormat(
				L"D2Coding",
				nullptr,
				DWRITE_FONT_WEIGHT_NORMAL,
				DWRITE_FONT_STYLE_NORMAL,
				DWRITE_FONT_STRETCH_NORMAL,
				72.0f,
				L"ko-kr",
				&pWFormat
			);
			
			if (FAILED(hr)) PostQuitMessage(0);

			hr = pWFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);

			if (FAILED(hr)) PostQuitMessage(0);

			hr = pWFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

		}
	}

	return hr; 
}

 


다음에는 실제 텍스트를 출력하는 작업을 진행하겠습니다.

 

DirectWrite - 텍스트 출력하기 2

 텍스트 출력하기 1에서 구성한 코드를 기반으로 이제 출력하는 코드를 작성합니다. OnPaint 구성  이제 DirectWrite를 사용하기 위해 OnPaint 메서드를 구성하겠습니다. OnPaint 메서드를 구성하고 난

pang2h.tistory.com

 

# index

728x90
반응형
Comments