Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: Text h_align = pixie.JUSTIFY_ALIGN #26

Open
IagoBeuller opened this issue Dec 22, 2022 · 0 comments
Open

Request: Text h_align = pixie.JUSTIFY_ALIGN #26

IagoBeuller opened this issue Dec 22, 2022 · 0 comments

Comments

@IagoBeuller
Copy link

IagoBeuller commented Dec 22, 2022

Would be nice if add this alignment style, also give access to Arrangement attributes(selectionRects, lines, positions).

I've made this little library for making this feature for me, it behaves like the Microsoft Word Office.

import
    nimpy,
    pixie,
    unicode

pyExportModule("pixie_utils")

const
    LF = Rune(10)
    NR = Rune(0)

proc justifyArrangement*(arrangement: Arrangement, maxWidth: float32) {.raises: [].} =
    proc right(rect: Rect): float32 =
        rect.x + rect.w

    let
        runes: ptr = arrangement.runes.addr
        positions: ptr = arrangement.positions.addr
        rects: ptr = arrangement.selectionRects.addr
        last_lineId: int = arrangement.lines.len-1
    var
        rune, last_rune: Rune
        last_wordRuneId: int
        spaces_idx: seq[int]
        inc_width, space_width, line_width, x_offset: float32
    
    for lineId, (start, stop) in arrangement.lines:
        last_rune = runes[stop]

        # This line must not be justified, if it is the last or if the last rune is a breakline char.
        if lineId == last_lineId or last_rune.uint32 == LF.uint32:
            continue

        echo runes[start..stop]
        # Get the spaces indexes of this line to increase their width, and get the line width.
        spaces_idx = @[]
        last_rune = NR
        for r_id in start..stop:
            rune = runes[r_id]
            if not rune.isWhiteSpace():
                if last_rune.isWhiteSpace():
                    spaces_idx.add(r_id-1)
                last_wordRuneId = r_id
            last_rune = runes[r_id]

        line_width = rects[last_wordRuneId].right

        echo "Line spaces: ", spaces_idx.len
        if spaces_idx.len > 0:
            # Get the amount of pixels/units to increase each space width in the middle of the line.
            inc_width = (maxWidth - line_width) / spaces_idx.len.float32

            if inc_width > 0:
                space_width = rects[spaces_idx[0]].w + inc_width

                # Adjust the runes X position
                x_offset = 0
                for r_id in spaces_idx[0]..stop:
                    positions[r_id].x += x_offset

                    if r_id in spaces_idx:
                        rects[r_id].x += x_offset
                        rects[r_id].w = space_width
                        x_offset += inc_width
                    else:
                        rects[r_id].x += x_offset

proc justifyArrangement(arrangement_ref: int, maxWidth: float32) {.exportpy: "justifyArrangement".} =
    justifyArrangement(cast[Arrangement](arrangement_ref), maxWidth)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant