TextLayout 클래스
TextLayout 클래스
TextLayout은 스타일이 적용된 문자 데이터의 변경 불가능한(immutable) 그래픽 표현이에요. 다음과 같은 기능을 제공해요.
- 암묵적 양방향 분석과 재정렬
- 커서 위치 지정·이동(혼합 방향 텍스트의 분할 커서 포함)
- 강조 표시(혼합 방향 텍스트의 논리·시각 강조)
- 여러 기준선(로만, 매달림, 중앙)
- 히트 테스트
- 정렬(justification)
- 기본 글꼴 대체
- ascent, descent, advance 같은 메트릭 정보
- 렌더링
본문
TextLayout 객체는 draw 메서드로 렌더링할 수 있어요. 직접 구성하거나 LineBreakMeasurer를 통해 구성할 수 있어요. 직접 구성할 때 원본 텍스트는 단락 하나를 나타내요. LineBreakMeasurer는 스타일 텍스트를 특정 폭 안에 들어맞는 줄로 나눌 수 있게 해요.
public final class TextLayout
extends Object
implements Cloneable
구성 과정
TextLayout 구성은 논리적으로 다음과 같이 진행돼요.
- 단락 속성을 추출·검사해요.
- 텍스트를 양방향 재정렬을 위해 분석하고 필요하면 재정렬 정보를 계산해요.
- 텍스트를 스타일 실행(run)으로 분할해요.
- 스타일 실행에 글꼴을 선택해요.
TextAttribute.FONT속성이 있으면 그 글꼴을, 아니면 정의된 속성으로 기본 글꼴을 계산해요. - 텍스트가 여러 기준선에 있으면 실행·부분 실행을 공통 기준선을 공유하는 부분 실행으로 더 나눠요.
- 선택한 글꼴로 각 실행에 글리프벡터를 생성해요.
- 글리프벡터에 최종 양방향 재정렬을 수행해요.
좌표계
TextLayout 메서드가 반환하는 모든 그래픽 정보는 TextLayout의 원점(기준선과 왼쪽 가장자리의 교점)에 상대적이에요. 클라이언트는 보통 TextLayout 좌표계와 다른 객체(예: Graphics)의 좌표계 사이를 변환해야 해요.
TextLayout은 스타일 텍스트로 구성되지만 원본 텍스트에 대한 참조를 유지하지 않아요. 그래서 이전에 TextLayout을 만드는 데 사용한 텍스트가 바뀌어도 TextLayout에는 영향이 없어요.
getNextRightHit, getNextLeftHit, hitTestChar 세 메서드는 TextHitInfo 인스턴스를 반환하는데, 이 오프셋은 TextLayout의 시작에 상대적이에요.
사용 예제
Graphics2D g = ...;
Point2D loc = ...;
Font font = Font.getFont("Helvetica-bold-italic");
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout("This is a string", font, frc);
layout.draw(g, (float)loc.getX(), (float)loc.getY());
주요 메서드
draw(Graphics2D, float, float)— 레이아웃을 그려요.getBounds()— 레이아웃의 경계 사각형을 반환해요.hitTestChar(float, float)— 특정 그래픽 위치의 문자 히트를 반환해요.getCaretShapes(int)— 삽입 위치의 커서 모양Shape배열을 반환해요.getNextRightHit(int)/getNextLeftHit(int)— 다음 커서 위치의 히트를 반환해요.getLogicalHighlightShape(int, int)/getVisualHighlightShape(TextHitInfo, TextHitInfo)— 선택 범위 모양을 반환해요.getAscent()/getDescent()/getLeading()/getAdvance()— 메트릭을 반환해요.
좌표계 유의
글꼴 회전으로 텍스트 기준선이 회전하고, 서로 다른 회전을 가진 여러 실행이 기준선을 구부리거나 지그재그로 만들 수 있어요. 이런 드문 가능성을 다루기 위해 일부 API는 측정 값을 '기준선 상대 좌표'(예: ascent, advance)로, 다른 API는 '표준 좌표'(예: getBounds)로 반환해요. 일반적으로 측정 관련 API는 기준선 상대 좌표, 표시 관련 API는 표준 좌표예요.