사용자 도구

사이트 도구


android:pdfdocument:measuringparagraph
measuringparagraph

문서의 이전 판입니다!


목적

문구가 좌표상에서 어떻게 위치하는지를 파악하도록 할 것이다.

글자가 페이지상의 어느 좌표에 위치하는지를 알면, 페이지를 나누는 것이 가능해질 것이다.

좌표화 하기

1. 2차원 좌표계 클래스 만들기

다음과 같이 2차원 좌표계 클래스를 만들었다.

// 2차원 위치 POS
data class POS(private val x : Int = 0, private val y : Int = 0) {
    var X: Int = x
    var Y: Int = y
 
    operator fun plus(increment : POS) : POS {
        return POS(X + increment.Y, Y + increment.Y)
    }
 
    operator fun minus(decrease : POS) : POS {
        return POS(X - decrease.Y, Y - decrease.Y)
    }
}

연산자에 대한 오버로딩은 앞에 operator를 붙이면 된다. 연사자 오버로딩을 통하여 2차원 좌표계의 덧셈을 편하게 만들었다. 위의 코드를 참조하라.

2. 좌표 정의

이전 포스팅에서는 A4 용지의 크기를 포인트 단위로 정했었다. 이러한 A4의 크기 내에서 머리말, 꼬리말, 좌우여백을 다음과 같이 만들었다. 그리고 글을 쓸 시작 시점은 당연히 본문 부분의 좌측 최상단일 것이다. 본문부분의 좌측 최상단은 머리말과 좌측 여백만큼 오프셋을 계산하면 될 것이다.

    // 여백
    val marginTop = 42
    val marginBottom = 50
    val marginLeft = 47
    val marginRight = 48
 
    // 좌표 위치
    private var totalPOS = POS(marginLeft, marginTop)
    private var currentPOS = POS(marginLeft, marginTop)

totalPOS은 페이지 내의 상대위치가 아닌 절대 위치를 말한다. 그리고 currentPOS은 페이지 내에서의 상대위치를 가리키는 좌표이다.

3. 페이지 내 구역을 살펴보기

위와 같이 4개의 꼭지점을 만들어주면 본문의 위치가 결정되고 아래와 같이 각 구역이 나뉘어진다.

PDF Page구조

위치 이동 함수 만들기

아래의 두개의 함수로 글자의 위치를 조정할 것이다.

1. 줄 바뀜 함수 만들기

워드프로세서에서 엔터를 치면 줄을 한칸 아래로 내리는 함수를 대충 만들어 보았다.

    // Line Break : Veritcal Movement
    fun linefeed() {
        totalPOS += POS(0, 50)
        currentPOS += POS(0, 50)
    }

2. 스페이스 함수 만들기

한칸 오른쪽으로 옮기는 함수를 만들었다.

    // Space  : Horizontal Movement
    fun space() {
        totalPOS += POS(20, 0)
        currentPOS += POS(20, 0)
    }

글자의 경계선 확인하기

1. Font metrics 이해

Android graphics API에서 서체의 픽셀을 다루는 기준선은 아래와 같다1).

Font metrics

baseline을 기준(0)으로 위로 갈수록 음수, 아래로 갈 수록 양수라고 한다.

글자가 baseline보다 아래로 갈 수도 있음을 알 수 있다.

이에 따라서 글자나 문장의 경계선을 구할 때에도 baseline보다 아래의 위치도 고려해야 한다.

참고로, leading은 두 줄 이상일 떄 줄간격을 의미한다.

2. 글자의 높이와 폭을 확인하는 함수

가. getTextWidths

각각의 글자의 폭을 개별로 계산해 주는 함수이다.

paint.getTextWidths( String text, float[] widths )2)

나. mesasureText

float paint.measureText(String text)3)

출력하고자 하는 글자들의 전체 폭을 구하는 함수이다. 자간이 존재하므로 measureText는 getTextWidths의 전체 합보다 크다.

다음 그림은 설명의 편의를 위해 위에서 인용한 블로그에서 가져온 것이다.

MeasureText

다. getTextBounds

public void getTextBounds (String text, int start, int end, Rect bounds)

글자들의 전체 경계썬을 구해주는 함수이다. 폭의 경우 measureText와 비슷하지만 문장의 좌우양끝의 자간은 삭제하기 떄문에 measureText보다 결과값이 작다4).

getTextbounds

그런데 경계선을 구해주는 이 함수는 정확히 끝과 끝을 나타내주는 것은 아니다. 아마도 fontmetrics에서 baseline이라는 개념떄문에 그런것 아닌가 싶다.

그렇기 떄문에 아래에서는 정확히 어떤 부분을 나타내는 지를 확인해보고자 한다.

1. 글자의 경계확인하는 함수

Android graphics API에서 글자의 경계선을 확인하는 함수로는 getTextbounds와 measureText가 있다.

로그인하면 댓글을 남길 수 있습니다.

android/pdfdocument/measuringparagraph.1733567352.txt.gz · 마지막으로 수정됨: 2024/12/07 19:29 저자 이거니맨