본문 바로가기

일하면서 사용한 짧은 지식/C++, DirectX11

ID2D1GeometrySink의 AddLines 메서드를 이용해 ID2D1PathGeometry*에 Underline(밑줄), Strikethrough(취소선) 추가하기

1. AddLines 메서드를 이용해 직접 윤곽선을 추가해야 했던 동기

 

 

https://myoung-min.tistory.com/60

 

GDI의 LOGFONT에서 DirectWrite 폰트를 생성할 때 가져오지 못하는 정보도 있다. (Underline, StrikeOut)

Glyph를 이용해 텍스트를 그리는데 Bold, Italic, Underline, StrikeOut 효과를 적용할 필요가 있었다. IDWriteFontFace*에서 GlyphIndices 받아와 ID2D1PathGeometry*를 생성하고 그려야하는 상황이었다. IDWrite..

myoung-min.tistory.com

 

위 내용처럼 LOGFONT에 밑줄, 취소선의 값을 설정하고

 

IDWriteGdiInterop*로 CreateFontFromLOGFONT 메서드를 이용해 IDWriteFont를 생성

 

IDWriteFont의 CreateFontFace 메서드를 이용하여 IDWriteFontFace* 생성

 

IDWriteFontFace*의 GetGlyphIndicesW 메서드를 이용해 glyphIndices 정보를 받는다.

 

glyphIndices 정보를 가지고 IDWriteFontFace*의 GetGlyphRunOutline 메서드로

 

ID2D1PathGeometry*에서 열어준 ID2D1GeometrySink*에 적용하여 Glyph 윤곽선을 적용한다.

 

 

하지만 LOGFONT에서 적용했던 밑줄, 취소선에 대한 내용은 Glyph 윤곽선에 반영이 되지 않아 직접 그려줄 필요가 있었다.

 

 

2. ID2D1GeometrySink의 AddLines 메서드를 이용해 ID2D1PathGeometry*에 Underline(밑줄), Strikethrough(취소선) 추가하기

 

 

IDWriteFontFace*의 GetMetrics 메서드를 사용하면 DWRITE_FONT_METRICS 구조체를 얻을 수 있다.

 

https://docs.microsoft.com/en-us/windows/win32/api/dwrite/ns-dwrite-dwrite_font_metrics

 

DWRITE_FONT_METRICS (dwrite.h) - Win32 apps

The DWRITE_FONT_METRICS structure specifies the metrics that are applicable to all glyphs within the font face.

docs.microsoft.com

struct DWRITE_FONT_METRICS {
  UINT16 designUnitsPerEm;
  UINT16 ascent;
  UINT16 descent;
  INT16  lineGap;
  UINT16 capHeight;
  UINT16 xHeight;
  INT16  underlinePosition;
  UINT16 underlineThickness;
  INT16  strikethroughPosition;
  UINT16 strikethroughThickness;
};

 

이 구조체 멤버에서 폰트에대한 밑줄, 취소선 위치와 두께 정보를 얻을 수 있다.

 

이 정보를 통해 아래 내용과 같이 폰트 값과 디바이스 값의 비율을 맞추어 D2D1_POINT_2F 4개의 사각형 좌표를 생성하였다.

 

https://docs.microsoft.com/en-us/windows/win32/gdi/device-vs--design-units

 

Device vs. Design Units - Win32 apps

An application can retrieve font metrics for a physical font only after the font has been selected into a device context.

docs.microsoft.com

 

ID2D1GeometrySink*의 메서드 BeginFigure, AddLines, EndFigure 메서드를 차례로 호출하여 밑줄 또는 취소선에 대한 사각형 Glyph를 추가해준다.

AddLines 메서드에 D2D1_POINT_2F 배열을 파라미터로 전달한다.

 

여기까지 하면 글자 윤곽선에 밑줄 또는 취소선 윤곽선이 추가된다.

 

하지만 겹치는 부분이 배경으로 인식되는 문제가 발생하여 ID2D1PathGeometry* 각각 생성하고 하나의 ID2D1PathGeometry*로 합치는 방법을 이용하여 해결하였다.

 

글자 윤곽선에 대한 ID2D1PathGeometry*를 생성하고

밑줄, 취소선에 대한 ID2D1PathGeometry*를 생성

이후 CombineWithGeometry 메서드를 이용해 합쳐줄 ID2D1GeometrySink*에 적용하는 방법이다.