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 hAlign = JUSTIFY_ALIGN #521

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

Request: Text hAlign = JUSTIFY_ALIGN #521

IagoBeuller opened this issue Dec 27, 2022 · 0 comments

Comments

@IagoBeuller
Copy link

IagoBeuller commented Dec 27, 2022

Would be nice if add this alignment style.

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

import
    pixie,
    unicode

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
    lastLineId: int = arrangement.lines.len-1
  
  var
    rune, lastRune: Rune
    lastWordRuneId: int
    spacesIdx: seq[int]
    incWidth, spaceWidth, lineWidth, xOffset: float32
  
  for lineId, (start, stop) in arrangement.lines:
    lastRune = runes[stop]

    # This line must not be justified, if it's the last or if the last rune is a breakline char.
    if lineId == lastLineId or lastRune == LF:
      continue

    echo runes[start..stop]
    # Get the spaces indexes of this line to increase their width, and get the line width.
    # Spaces in the end will be pushed away the maxWidth like the Microsoft Word.
    spacesIdx = @[]
    lastRune = NR
    for rId in start..stop:
      rune = runes[rId]
      if not rune.isWhiteSpace():
        if lastRune.isWhiteSpace():
          spacesIdx.add(rId-1)
        lastWordRuneId = rId
      lastRune = rune

    lineWidth = rects[lastWordRuneId].right

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

      if incWidth > 0:
        spaceWidth = rects[spacesIdx[0]].w + incWidth

        # Adjust the runes X position
        xOffset = 0
        for rId in spacesIdx[0]..stop:
          positions[rId].x += xOffset
          rects[rId].x += xOffset
          
          if rId in spacesIdx:
            rects[rId].w = spaceWidth
            xOffset += incWidth
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