TextClass.h
TextClass.cpp
#include "TextClass.h" bool TextClass::Initialize() { if (!CreateDevInDependentResources()) return false; return true; } TextClass::TextClass(int scrw, int scrh, HWND hwnd) { screenWidth = scrw; screenHeight = scrh; g_hWnd = hwnd; } TextClass::~TextClass() { ReleaseDevDependentResources(); ReleaseDevInDependentResources(); } bool TextClass::Draw() { HRESULT hr = S_OK; // Make sure device dependent resources have been loaded. // Normally this call will be a no-operation. if (!CreateDevDependentResources()) return false; if (g_pRT->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED) return true; // Start the drawing cycle g_pRT->BeginDraw(); // First make sure the transformation is set to the identity transformation. g_pRT->SetTransform(D2D1::IdentityMatrix()); // Clear the background of the window with a white color. g_pRT->Clear(D2D1::ColorF(D2D1::ColorF::White)); // Specify the upper-left origin of where the text will be rendered to // and apply a rotation transformation if we are in rotation mode. D2D1_POINT_2F origin = D2D1::Point2F(static_cast<FLOAT>(g_siMargin), static_cast<FLOAT>(g_siMargin)); if (g_bRotate) g_pRT->SetTransform(D2D1::Matrix3x2F::Rotation(g_fAngle, D2D1::Point2F(0.0f, 0.0f))); // Draw our text. g_pRT->DrawTextLayout(origin, g_pTextLayout, g_pSolidBrush); // Calculate the top of the "Arabic" text by calculating the height of the text // that was rendered up to now. DWRITE_TEXT_METRICS textMetrics = { 0 }; if (FAILED(g_pTextLayout->GetMetrics(&textMetrics))) return false; FLOAT fArabicTextTop = textMetrics.top + textMetrics.height; // Specify the upper-left origin of where the Arabic text will be rendered to // and apply a rotation transformation if we are in rotation mode. origin.y = fArabicTextTop; if (g_bRotate) g_pRT->SetTransform(D2D1::Matrix3x2F::Rotation(g_fAngle, D2D1::Point2F(0.0f, 0.0f))); // Draw our text. g_pRT->DrawTextLayout(origin, g_pArabicTextLayout, g_pSolidBrush); // Calculate the top of the "Fancy Typography Rendering" text by calculating the height of the text // that was rendered up to now. if (FAILED(g_pArabicTextLayout->GetMetrics(&textMetrics))) return false; FLOAT fFancyTypographTop = fArabicTextTop + textMetrics.height; // Calculate the width of the "Fancy Typography Rendering" text for setting up the gradient brush. if (FAILED(g_pFancyTextLayout->GetMetrics(&textMetrics))) return false; // Setup the linear gradient brush properties based on the calculated text size. D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props; props.startPoint.x = textMetrics.left; props.startPoint.y = 0.0f; props.endPoint.x = textMetrics.left + textMetrics.width; props.endPoint.y = 0.0f; // Setup an array of gradient stops. D2D1_GRADIENT_STOP stops[3]; stops[0].color = D2D1::ColorF(D2D1::ColorF::Red); stops[0].position = 0.0f; stops[1].color = D2D1::ColorF(D2D1::ColorF::Blue); stops[1].position = 0.5f; stops[2].color = D2D1::ColorF(D2D1::ColorF::Red); stops[2].position = 1.0f; // Construct a gradient stop collection object. ID2D1GradientStopCollection *pStopCollection = NULL; if (FAILED(g_pRT->CreateGradientStopCollection(stops, 3, D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &pStopCollection))) return false; // Create a linear gradient brush. ID2D1LinearGradientBrush *pGradientBrush = NULL; if (FAILED(g_pRT->CreateLinearGradientBrush(&props, NULL, pStopCollection, &pGradientBrush))) return false; DWRITE_TEXT_RANGE range = { 0, 27 }; if (FAILED(g_pFancyTextLayout->SetDrawingEffect(pGradientBrush, range))) return false; if (pGradientBrush) pGradientBrush->Release(); if (pStopCollection) pStopCollection->Release(); // Specify the upper-left origin of where the "Fancy" text will be rendered to // and apply a rotation transformation if we are in rotation mode. origin.y = fFancyTypographTop; if (g_bRotate) g_pRT->SetTransform(D2D1::Matrix3x2F::Rotation(g_fAngle, D2D1::Point2F(0.0f, 0.0f))); // Draw our text. g_pRT->DrawTextLayout(origin, g_pFancyTextLayout, g_pSolidBrush); // Finish the drawing cycle. hr = g_pRT->EndDraw(); // If something went wrong, release device dependent resource so they // will be recreated on the next call. if (FAILED(hr)) ReleaseDevDependentResources(); return true; } bool TextClass::CreateDevInDependentResources() { if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_pD2DFactory))) return false; if (FAILED(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&g_pDWriteFactory)))) return false; if (FAILED(g_pDWriteFactory->CreateTextFormat(L"Arial", NULL, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, ConvertPointSizeToDIP(12.0f), L"en-us", &g_pTextFormat))) return false; if (FAILED(g_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING))) return false; return true; } void TextClass::ReleaseDevInDependentResources() { if (g_pTextFormat != NULL) g_pTextFormat->Release(); if (g_pDWriteFactory != NULL) g_pDWriteFactory->Release(); if (g_pD2DFactory != NULL) g_pD2DFactory->Release(); } bool TextClass::CreateDevDependentResources() { HRESULT result; if (g_pRT != NULL) return true; if (!IsWindowVisible(g_hWnd)) return false; RECT rc; GetClientRect(g_hWnd, &rc); D2D1_SIZE_U size = D2D1::SizeU((rc.right - rc.left), (rc.bottom - rc.top)); result = g_pD2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(g_hWnd, size), &g_pRT); if (FAILED(result)) //0x887a0001 return false; if (FAILED(g_pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &g_pSolidBrush))) return false; if (FAILED(CreateTextLayouts())) return false; return true; } void TextClass::ReleaseDevDependentResources() { if (g_pTextLayout) g_pTextLayout->Release(); if (g_pFancyTextLayout) g_pFancyTextLayout->Release(); if (g_pArabicTextLayout) g_pArabicTextLayout->Release(); if (g_pSolidBrush) g_pSolidBrush->Release(); if (g_pRT) g_pRT->Release(); } bool TextClass::CreateTextLayouts() { D2D1_SIZE_F sizeRT = g_pRT->GetSize(); sizeRT.height -= 2 * g_siMargin; sizeRT.width -= 2 * g_siMargin; TCHAR* pStr = L"Test of formatting: normal, bold, underlined, italic, huge, bold&italic&underlined.\n" L"Test of coloring: orange, red, blue.\n" L"Test of hit-testing: move your mouse over the third word of this sentence.\n" L"Test of word wrapping: this text has some longer lines to test the proper working of the word wrapping feature of DirectWrite. " L"To test the correct word wrapping, try to resize this window and verify that this whole piece of text is readable without missing words.\n\n" L"The Arabic example below shows that rendering right-to-left languages is not a problem at all. NOTE: I have no idea what that text is saying, " L"so do not blame me if it says something wrong.\n\n" L"The \"Fancy Typography Rendering\" example below uses some special typographic features of the Grabriola font. " L"It also shows how to mix different text alignment for different paragraphs and how to use gradient brushes.\n\n"; if (g_pTextLayout) g_pTextLayout->Release(); if (FAILED(g_pDWriteFactory->CreateTextLayout(pStr, _tcslen(pStr), g_pTextFormat, sizeRT.width, sizeRT.height, &g_pTextLayout))) return false; DWRITE_TEXT_RANGE range = { 28, 4 }; if (FAILED(g_pTextLayout->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, range))) return false; range.startPosition = 34; range.length = 10; if (FAILED(g_pTextLayout->SetUnderline(TRUE, range))) return false; range.startPosition = 46; range.length = 6; if (FAILED(g_pTextLayout->SetFontStyle(DWRITE_FONT_STYLE_ITALIC, range))) return false; range.startPosition = 54; range.length = 4; if (FAILED(g_pTextLayout->SetFontSize(ConvertPointSizeToDIP(36.0f), range))) return false; range.startPosition = 60; range.length = 22; if (FAILED(g_pTextLayout->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, range))) return false; if (FAILED(g_pTextLayout->SetFontStyle(DWRITE_FONT_STYLE_ITALIC, range))) return false; if (FAILED(g_pTextLayout->SetUnderline(TRUE, range))) return false; range.startPosition = 102; range.length = 6; ID2D1SolidColorBrush *pBrush = NULL; if (FAILED(g_pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Orange), &pBrush))) return false; if (FAILED(g_pTextLayout->SetDrawingEffect(pBrush, range))) return false; if (pBrush) pBrush->Release(); // Red formatting range.startPosition = 110; range.length = 3; if (FAILED(g_pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &pBrush))) return false; if (FAILED(g_pTextLayout->SetDrawingEffect(pBrush, range))) return false; if (pBrush) pBrush->Release(); // Blue formatting. range.startPosition = 115; range.length = 4; if (FAILED(g_pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Blue), &pBrush))) return false; if (FAILED(g_pTextLayout->SetDrawingEffect(pBrush, range))) return false; if (pBrush) pBrush->Release(); if (g_bOverLink) { range.startPosition = 129; range.length = 11; if (FAILED(g_pTextLayout->SetUnderline(TRUE, range))) return false; if (FAILED(g_pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Blue), &pBrush))) return false; if (FAILED(g_pTextLayout->SetDrawingEffect(pBrush, range))) return false; if (pBrush) pBrush->Release(); } // Fancy Typograph formatting. TCHAR* pStr2 = L"Fancy Typography Rendering."; if (g_pFancyTextLayout) g_pFancyTextLayout->Release(); if (FAILED(g_pDWriteFactory->CreateTextLayout(pStr2, _tcslen(pStr2), g_pTextFormat, sizeRT.width, sizeRT.height, &g_pFancyTextLayout))) return false; range.startPosition = 0; range.length = 27; // Center the text horizontally. if (FAILED(g_pFancyTextLayout->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER))) return false; // Assign a font that has special typography features. if (FAILED(g_pFancyTextLayout->SetFontFamilyName(L"Gabriola", range))) return false; // Set font size. if (FAILED(g_pFancyTextLayout->SetFontSize(ConvertPointSizeToDIP(36.0f), range))) return false; // Declare a typography smart pointer. IDWriteTypography *pTypography = NULL; // Create a typography interface instance. if (FAILED(g_pDWriteFactory->CreateTypography(&pTypography))) return false; // Set the stylistic set of the font to use. DWRITE_FONT_FEATURE fontFeature = { DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7, 1 }; if (FAILED(pTypography->AddFontFeature(fontFeature))) return false; // Assign the typography to the text range. if (FAILED(g_pFancyTextLayout->SetTypography(pTypography, range))) return false; // Release our typography object. if (pTypography) pTypography->Release(); // Arabic text rendering example TCHAR* pArabic = L"?????? ??? ???? ?????? ?????? ?? ?????? ?????? ???? ???? ??????? ??????? ?? ?????? ????? ??? ?????? ?????? ????? . ??? ????? ??????? ??? ???? ????? ???? ???? ??? ??????? ????? ?????? ????? ????? ?????? ?? ???? ?????? ?????? . ???? ??? ??????? ????????? ??????? ????? ?????? ? ????? ?? ???? ?????????? ?????? ??????? ? ??? ??????? ?????? ???????? ??????? ??????? ??????? ???????? ???? ???? ?? ???? ???? ??? ?? ???? ????? . ??? ????? ?? ???????? ? ??? ??? ? ?????? ??? ???????? ???????? ?????? . "; if (g_pArabicTextLayout) g_pArabicTextLayout->Release(); if (FAILED(g_pDWriteFactory->CreateTextLayout(pArabic, _tcslen(pArabic), g_pTextFormat, sizeRT.width, sizeRT.height, &g_pArabicTextLayout))) return false; // Set reading direction to right-to-left if (FAILED(g_pArabicTextLayout->SetReadingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT))) return false; range.startPosition = 0; range.length = _tcslen(pArabic); if (FAILED(g_pArabicTextLayout->SetFontFamilyName(L"Arial", range))) return false; if (FAILED(g_pArabicTextLayout->SetFontSize(ConvertPointSizeToDIP(22.0f), range))) return false; return true; } float TextClass::ConvertPointSizeToDIP(float points) { return (points/72.0f)*96.0f; }
소스 다 올리기엔 너무 많은거 같아서 핵심 부분만 올림여..;;
TextClass 생성할때 윈도우 핸들이랑 창 크기 넘겨주고 Initialize()를 호출한 다음에 그리는 부분에서 Draw()를 호출해 주는 방향임돠
그러면 TestClass.cpp 164번 line에서 result가 0x887a0001이 떠서 false로 넘어가버림..;;
디버깅 하면 g_pRT가 NULL로 나오네여...ㅜ
참고로 윈도우 핸들 만드는 옵션이 이거임요
m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
http://blog.naver.com/khk6435/50132700788
참조하셈
설정부터 차근차근 따라해보는게 좋을 듯
저 위 코드는 걍 잊어버리고 이 블로그껄로 다시해보셈
d3d면 걍 직접 공부할때 쓰던 코드 보여주면 그만인데
ㅇㅇ// ㄳㄳ 일단 저 블로그 따라 해보고 또 뭐가 안되면 프갤에 다시 질문하겠습니다