MewUI v0.20.0에서는 텍스트 스택을 통째로 재구축해 출시합니다. 프로젝트를 시작한 이래 가장 큰 규모의 변경으로, 코어의 새 텍스트 레이아웃 엔진, 그 위의 확장 가능한 텍스트 뷰 시스템, 재구축된 MultiLineTextBox, 새 읽기 전용 SyntaxViewer 컨트롤, 그리고 오래 예고해 온 AvalonEdit 호환 코드 에디터 MewvalonEdit의 정식 출시가 함께 들어갑니다.
왜 다시 만들었나
MewUI의 기존 텍스트 지원은 문자열 하나를 폰트 하나, 색 하나로 그리는 프리미티브 수준이었습니다. 측정, 그리기, hit test를 함께 소유하는 레이아웃 객체가 없었기 때문에, 그 이상이 필요한 컨트롤은 caret 배치, 선택 영역 geometry, 폭 캐시 같은 것들을 각자 구현해야 했습니다. 그 결과 컨트롤별 측정 캐시가 여기저기 흩어졌고, 각 컨트롤의 렌더링 코드를 고치지 않고는 구문 강조나 검색 하이라이트 같은 기능을 추가할 방법이 없었습니다.
새 엔진은 이 구조를 뒤집습니다. 측정, 그리기, hit test가 같은 레이아웃 객체와 같은 문자 cluster 데이터에서 나오므로, 측정 결과와 그려지는 위치, caret이 놓이는 자리가 항상 일치합니다.
새 텍스트 엔진

코어에 문서 텍스트에서 픽셀까지 전체 파이프라인을 소유하는 관리형 텍스트 엔진(Aprillz.MewUI.Text)이 들어왔습니다.
- 논리 줄에서 비주얼 줄로. 엔진이 문서의 줄을 조립해 뷰포트에 맞게 wrap하고, 화면에 보이는 줄만 materialize합니다. 큰 문서도 반응성을 유지하며, 10MB 이상의 큰 문서까지 소화합니다.
- Cluster 단위로 정확한 편집. Caret 이동, 히트테스트, 선택 등이 백엔드가 제공한 문자 Cluster 데이터를 사용합니다. Surrogate pair, Combining mark, Variation selector, ZWJ 이모지 시퀀스를 쪼개지 않습니다.
- 멀티런 스타일과 폰트 폴백. 하나의 레이아웃 안에 폰트, 굵기, 색, 장식을 섞을 수 있고, 여러 스크립트가 섞인 텍스트(라틴, CJK, 이모지)의 폰트 폴백을 기본 계약으로 지원합니다.
- 엔진 수준 캐시. 레이아웃 캐시가 개별 컨트롤에서 엔진으로 이동했습니다(반복되는 짧은 문자열은 content 기준, 안정적인 텍스트는 owner 기준). 컨트롤은 별도 캐시 코드 없이 프레임 사이에서 레이아웃을 재사용합니다.
- 백엔드. 엔진은 하나의 측정 계약으로 모든 MewUI 백엔드(Direct2D, GDI+, MewVG)에서 동작하며, 공통 편집/hit test 계약 테스트 스위트가 이를 뒷받침합니다.
- Line Box와 Line Spacing - 폰트의 Cap 높이와 Baseline을 기준으로 높이를 Trim할수 있고 Baseline을 조정할수 있어 다양한 폰트를 UI에 최적화된 모양으로 적용할 수 있습니다.
텍스트 컨트롤 계열은 컨트롤 하나가 아니라 루트에서 재구축되었습니다. 편집 컨트롤(TextBox, MultiLineTextBox)의 기반인 TextBase가 문서, 편집 세션, IME, 클립보드 처리를 엔진 위에서 소유하고, 표시 컨트롤의 기반인 TextBlockBase도 같은 엔진과 캐시로 레이아웃하고 그립니다. MultiLineTextBox는 그 위에 wrap, 뷰포트 가상화, 문서가 소유하는 undo 이력을 더합니다. MultiLineTextBox.Document에 새 문서를 할당해도 뷰와 확장 등록이 유지되므로, 에디터가 UI를 다시 만들지 않고 파일을 교체할 수 있습니다.
텍스트 뷰 확장 시스템
이번 릴리즈에서 가장 소개하고 싶은 부분은 이 두 번째 층입니다. 이제 컨트롤을 상속하지 않고 텍스트 표시를 확장할 수 있습니다. MultiLineTextBox와 새 읽기 전용 SyntaxViewer가 확장 파이프라인을 노출합니다.
| 기능 | 확장 |
|---|---|
| 문자 범위에 색/밑줄 | ITextClassifier |
| 임의 드로잉 (물결선, 괄호 강조) | ITextAdornmentProvider |
| 표시 텍스트 치환 (공백 기호, 접기 자리표시자) | ITextProjection |
| 인라인 요소 삽입 | ITextElementGenerator |
| 글자 배치가 변하는 스타일 (굵기, 크기) | ITextLineTransformer |
| 줄 숨김 (접기) | ITextLineCollapser |

검색 하이라이트는 작은 classifier 하나로 구현됩니다.
editor.Extensions.Classifiers.Add(new SearchHighlighter { Query = “engine” }); editor.InvalidateTextView();
확장은 화면에 보이는 줄에 대해서만 실행되고, 접기 같은 표시 치환이 활성일 때도 올바르게 동작하도록 오프셋 맵을 전달받으며, 여러 확장은 등록 순서대로 겹쳐집니다. 갤러리에 매치 이동까지 포함한 검색 하이라이트 데모(Inputs 페이지의 “Find Highlight” 카드)를 제공합니다.
SyntaxViewer는 MultiLineTextBox의 읽기 전용 대응 컨트롤로, 편집 기능 없이 분류, 장식, 선택, 스크롤을 제공합니다. MewUI 코어에 포함되며, 코드 뷰어나 마크다운 뷰어 같은 뷰어 확장이 그 위에 올라서도록 설계된 기반입니다.
MewvalonEdit: MewUI를 위한 AvalonEdit 호환 에디터
MewvalonEdit은 오래전부터 출시를 예고하고 준비해 온 확장입니다. 그동안 기다린 것이 바로 위의 작업입니다. 에디터의 완성도는 결국 그 아래 텍스트 스택이 결정하는데, 기존 스택으로는 코드 에디터를 감당할 수 없었습니다. 이제 새 엔진이 자리를 잡으면서 Aprillz.MewUI.MewvalonEdit를 v0.20.0에서 정식 출시합니다.

MewvalonEdit은 확장 시스템의 실전 검증이기도 합니다. MewvalonEdit의 모든 기능(강조, 접기, 검색, 공백 표시)은 MewUI 코어에 열려 있는 공개 계약을 기반으로 구현되어 있습니다.
