다음을 통해 공유


Direct2D 및 DirectWrite 사용하여 텍스트 렌더링

GDI, GDI+ 또는 WPF와 같은 다른 API와 달리 Direct2D는 DirectWrite 다른 API와 상호 운용되어 텍스트를 조작하고 렌더링합니다. 이 항목에서는 이러한 개별 구성 요소의 이점과 상호 운용에 대해 설명합니다.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

Direct2D를 통해 증분 채택 가능

애플리케이션을 한 그래픽 API에서 다른 그래픽 API로 이동하는 것은 여러 가지 이유로 원하는 것이 아니거나 어려울 수 있습니다. 이는 애플리케이션 자체가 한 릴리스에서 새 API로 이식하기에는 너무 크거나 최신 API의 일부가 바람직하지만 이전 API가 애플리케이션의 다른 부분에서 충분히 잘 작동하기 때문에 이전 인터페이스를 사용하는 플러그 인을 지원해야 하기 때문일 수 있습니다.

Direct2DDirectWrite 별도의 구성 요소로 구현되므로 전체 2D 그래픽 시스템 또는 텍스트 부분만 업그레이드할 수 있습니다. 예를 들어 텍스트에 DirectWrite 사용하지만 렌더링에 GDI 또는 GDI+를 사용하도록 애플리케이션을 업데이트할 수 있습니다.

Text Services와 텍스트 렌더링 비교

애플리케이션이 발전함에 따라 텍스트 처리 요구 사항이 점점 더 복잡해지고 있습니다. 처음에는 텍스트가 일반적으로 정적으로 배치된 UI로 제한되었고 텍스트는 단추와 같은 잘 정의된 상자에 렌더링되었습니다. 애플리케이션을 점점 더 많은 언어로 사용할 수 있게 되면서 번역된 텍스트의 너비와 높이가 언어마다 크게 다를 수 있으므로 이 방법을 유지하기가 더 어려워졌습니다. 적응하기 위해 애플리케이션은 다른 방법이 아니라 텍스트의 실제 렌더링 크기에 따라 UI를 동적으로 배치하기 시작했습니다.

애플리케이션이 이 작업을 완료할 수 있도록 DirectWriteIDWriteTextLayout 인터페이스를 제공합니다. 이 API를 사용하면 애플리케이션에서 다양한 글꼴 및 글꼴 크기, 밑줄, 취소선, 양방향 텍스트, 효과, 줄임표 및 포함된 비 문자(예: 비트맵 이모티콘 또는 아이콘)와 같은 복잡한 특성을 가진 텍스트 조각을 지정할 수 있습니다. 그러면 애플리케이션이 UI 레이아웃을 반복적으로 결정할 때 텍스트의 다양한 특성을 변경할 수 있습니다. 다음 그림과 자습서:시작 DirectWrite 항목에 표시된 DirectWrite 헬로 월드 샘플은 이러한 많은 효과를 보여 줍니다.

레이아웃은 너비에 따라 문자 모양을 배치하거나(WPF와 같이) 문자 모양을 가장 가까운 픽셀 위치( GDI 와 같이)에 맞출 수 있습니다.

애플리케이션은 텍스트 측정값을 가져오는 것 외에도 텍스트의 다양한 부분을 테스트할 수 있습니다. 예를 들어 텍스트의 하이퍼링크를 클릭하는 것을 알고 싶을 수 있습니다. 적중 테스트에 대한 자세한 내용은 텍스트 레이아웃에서 적중 테스트를 수행하는 방법 항목을 참조하세요.

다음 다이어그램과 같이 텍스트 레이아웃 인터페이스가 애플리케이션에서 사용하는 렌더링 API와 분리됩니다.

텍스트 레이아웃 및 그래픽 API 다이어그램

DirectWrite 애플리케이션이 원하는 그래픽 API를 사용하여 텍스트를 렌더링하기 위해 구현할 수 있는 렌더링 인터페이스(IDWriteTextRenderer)를 제공하기 때문에 이러한 분리가 가능합니다. 구현된 IDWriteTextRenderer::D rawGlyphRun 콜백 메서드는 텍스트 레이아웃을 렌더링할 때 DirectWrite 호출됩니다. 그리기 작업을 수행하거나 전달하는 것은 이 메서드의 책임입니다.

문자 모양을 그리기 위해 Direct2D는 Direct2D 표면에 그리기 위해 ID2D1RenderTarget::D rawGlyphRun을 제공하고 DirectWrite GDI 표면으로 그리기 위한 IDWriteBitmapRenderTarget::D rawGlyphRun을 제공하여 GDI를 사용하여 창으로 전송할 수 있습니다. Direct2D와 DirectWrite 모두의 DrawGlyphRun에는 애플리케이션이 IDWriteTextRenderer에서 구현하는 DrawGlyphRun 메서드와 정확히 호환되는 매개 변수가 있습니다.

유사한 분리 후 텍스트 관련 기능(예: 글꼴 열거형 및 관리, 문자 모양 분석 등)은 Direct2D 대신 DirectWrite 처리됩니다. DirectWrite 개체는 Direct2D에서 직접 수락됩니다. 기존 GDI 애플리케이션이 DirectWrite 활용할 수 있도록 IDWriteGdiInterop 메서드 인터페이스에 다음을 수행하는 메서드를 제공합니다.

문자 모양 대 텍스트

Text는 사각형에 배치된 다양한 스타일 한정자(글꼴, 가중치, 밑줄, 취소선 등)가 있는 유니코드 코드 포인트(문자) 집합입니다. 반면 문자 모양은 특정 글꼴 파일의 특정 인덱스입니다. 문자 모양은 렌더링할 수 있는 곡선 집합을 정의하지만 텍스트 의미가 없습니다. 문자 모양과 문자 간에 다대다 매핑이 있을 수 있습니다. 동일한 글꼴 얼굴에서 제공되며 기준선에 순차적으로 배치되는 문자 모양 시퀀스를 GlyphRun이라고 합니다. DirectWrite및 Direct2D는 모두 가장 정확한 문자 모양 렌더링 API DrawGlyphRun을 호출하며 서명이 매우 유사합니다. 다음은 Direct2D의 ID2D1RenderTarget 에서 가져옵니다.

STDMETHOD_(void, DrawGlyphRun)(
        D2D1_POINT_2F baselineOrigin,
        __in CONST DWRITE_GLYPH_RUN *glyphRun,
        __in ID2D1Brush *foregroundBrush,
        DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL 
        ) PURE;

이 메서드는 DirectWriteIDWriteBitmapRenderTarget에서 가져옵니다.

STDMETHOD(DrawGlyphRun)(
        FLOAT baselineOriginX,
        FLOAT baselineOriginY,
        DWRITE_MEASURING_MODE measuringMode,
        __in DWRITE_GLYPH_RUN const* glyphRun,
        IDWriteRenderingParams* renderingParams,
        COLORREF textColor,
        __out_opt RECT* blackBoxRect = NULL
        ) PURE;

DirectWrite 버전은 기준선 원점, 측정 모드 및 문자 모양 실행 매개 변수를 유지하고 추가 매개 변수를 포함합니다.

또한 DirectWriteIDWriteTextRenderer 인터페이스를 구현하여 문자 모양에 대한 사용자 지정 렌더러를 사용할 수 있습니다. 이 인터페이스에는 다음 코드 예제와 같이 DrawGlyphRun 메서드도 있습니다.

STDMETHOD(DrawGlyphRun)(
        __maybenull void* clientDrawingContext,
        FLOAT baselineOriginX,
        FLOAT baselineOriginY,
        DWRITE_MEASURING_MODE measuringMode,
        __in DWRITE_GLYPH_RUN const* glyphRun,
        __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
        __maybenull IUnknown* clientDrawingEffect
        ) PURE;

이 버전에는 사용자 지정 텍스트 렌더러를 구현할 때 유용한 더 많은 매개 변수가 포함되어 있습니다. 최종 매개 변수는 애플리케이션 구현 사용자 지정 그리기 효과에 사용됩니다. (클라이언트 그리기 효과에 대한 자세한 내용은 텍스트 레이아웃에 클라이언트 그리기 효과를 추가하는 방법을 참조하세요.

각 문자 모양 실행은 원점에서 시작하여 이 원점부터 시작하는 줄에 배치됩니다. 문자 모양은 현재 월드 변환 및 연결된 렌더링 대상에서 선택한 텍스트 렌더링 설정에 의해 변경됩니다. 이 API는 일반적으로 자체 레이아웃을 수행하는 애플리케이션(예: Word 프로세서) 또는 IDWriteTextRenderer 인터페이스를 구현한 애플리케이션에서만 직접 호출됩니다.

DirectWrite 및 Direct2D

Direct2DDrawGlyphRun을 통해 문자 모양 수준 렌더링 서비스를 제공합니다. 그러나 이를 위해서는 기본적으로 GDI에서 DrawText API의 기능을 자체적으로 재현하는 렌더링 세부 정보를 구현해야 합니다.

따라서 Direct2D 는 문자 모양 대신 텍스트를 허용하는 API를 제공합니다. ID2D1RenderTarget::D rawTextLayoutID2D1RenderTarget::D rawText. 두 메서드 모두 Direct2D 화면에 렌더링됩니다. GDI 표면으로 렌더링하려면 IDWriteBitmapRenderTarget::D rawGlyphRun 이 제공됩니다. 그러나 이 메서드를 사용하려면 애플리케이션에서 사용자 지정 텍스트 렌더러를 구현해야 합니다. 자세한 내용은 GDI Surface로 렌더링 항목을 참조하세요.

애플리케이션의 텍스트 사용은 일반적으로 간단하게 시작됩니다. 예를 들어 고정 레이아웃 단추에 확인 또는 취소 를 배치합니다. 그러나 시간이 지남에 따라 국제화 및 기타 기능이 추가됨에 따라 더 복잡해집니다. 결국 많은 애플리케이션이 DirectWrite 텍스트 레이아웃 개체를 사용하고 텍스트 렌더러를 구현해야 합니다.

따라서 Direct2D 는 애플리케이션이 작업 코드를 백트랙하거나 중단하지 않고도 간단하게 시작하고 더 정교해질 수 있는 계층화된 API를 제공합니다. 간소화된 보기는 다음 다이어그램에 표시됩니다.

directwrite 및 direct2d 애플리케이션 다이어그램

Drawtext

DrawText 는 사용할 가장 간단한 API입니다. 유니코드 문자열, 전경 브러시, 단일 형식 개체 및 대상 사각형을 사용합니다. 레이아웃 사각형 내에서 전체 문자열을 배치하고 렌더링하고 필요에 따라 클리핑합니다. 이 기능은 간단한 텍스트를 고정 레이아웃 UI에 배치할 때 유용합니다.

DrawTextLayout

IDWriteTextLayout 개체를 만들면 애플리케이션에서 텍스트 및 기타 UI 요소의 측정 및 정렬을 시작하고 여러 글꼴, 스타일, 밑줄 및 취소선이 지원됩니다. Direct2D 는 이 개체를 직접 수락하고 지정된 지점에서 텍스트를 렌더링하는 DrawTextLayout API를 제공합니다. (너비와 높이는 레이아웃 개체에서 제공됩니다.) Direct2D는 예상되는 모든 텍스트 레이아웃 기능을 구현하는 것 외에도 효과 개체를 브러시로 해석하고 선택한 문자 모양 범위에 해당 브러시를 적용합니다. 인라인 개체도 호출합니다. 그런 다음 애플리케이션이 원하는 경우 텍스트에 문자 모양이 아닌 문자(아이콘)를 삽입할 수 있습니다. 텍스트 레이아웃 개체를 사용하는 또 다른 이점은 문자 모양 위치가 캐시된다는 것입니다. 따라서 여러 그리기 호출에 동일한 레이아웃 개체를 다시 사용하고 각 호출에 대한 문자 모양 위치를 다시 계산하지 않도록 하면 성능이 크게 향상됩니다. GDI의 DrawText에는 이 기능이 없습니다.

DrawGlyphRun

마지막으로 애플리케이션은 IDWriteTextRenderer 인터페이스 자체를 구현하고 DrawGlyphRunFillRectangle 자체 또는 다른 렌더링 API를 호출할 수 있습니다. Text Layout 개체와의 모든 기존 상호 작용은 변경되지 않은 상태로 유지됩니다.

사용자 지정 텍스트 렌더러를 구현하는 방법에 대한 예제는 사용자 지정 텍스트 렌더러를 사용하여 렌더링 항목을 참조하세요.

문자 모양 렌더링

기존 GDI 애플리케이션에 DirectWrite 추가하면 애플리케이션에서 IDWriteBitmapRenderTarget API를 사용하여 문자 모양을 렌더링할 수 있습니다. DirectWrite 제공하는 IDWriteBitmapRenderTarget::D rawGlyphRun 메서드는 Direct2D와 같은 추가 API를 요구하지 않고 메모리 DC에 단색으로 렌더링됩니다.

이렇게 하면 애플리케이션에서 다음과 같은 고급 텍스트 렌더링 기능을 얻을 수 있습니다.

  • 하위 픽셀 ClearType을 사용하면 애플리케이션이 문자 모양을 하위 픽셀 위치에 배치하여 선명한 문자 모양 렌더링 및 문자 모양 레이아웃을 모두 허용할 수 있습니다.
  • Y 방향 앤티앨리어싱을 사용하면 더 큰 문자 모양에서 곡선을 더 부드럽게 렌더링할 수 있습니다.

Direct2D로 이동하는 애플리케이션은 다음 기능도 가져옵니다.

  • 하드웨어 가속.
  • 방사형 그라데이션, 선형 그라데이션 및 비트맵과 같은 임의의 Direct2D 브러시로 텍스트를 채우는 기능입니다.
  • PushAxisAlignedClip, PushLayerCreateCompatibleRenderTarget API를 통한 계층화 및 클리핑에 대한 추가 지원.
  • 회색조 텍스트 렌더링을 지원하는 기능입니다. 이렇게 하면 텍스트 브러시 불투명도 및 텍스트 앤티앨리어싱에 따라 대상 알파 채널이 올바르게 채워집니다.

하드웨어 가속을 효율적으로 지원하기 위해 Direct2D알파 보정이라는 감마 수정에 약간 다른 근사치를 사용합니다. 따라서 텍스트를 렌더링할 때 렌더링 대상 색 픽셀을 검사하는 데 Direct2D가 필요하지 않습니다.

결론

이 항목에서는 Direct2DDirectWrite 간의 차이점과 유사성과 이를 별도의 협력 API로 제공하기 위한 아키텍처 동기에 대해 설명합니다.