DrawAlignedText - draw spaced row of text between a margin

Started by kevin, March 19, 2015, 09:09:01 AM

Previous topic - Next topic

kevin

  DrawAlignedText - draw spaced row of text between a margin

  This example take a single line input string, splits it, works out the width of all the text fragments in pixels, then displays the text fragments so it  aligns to the edges, like you would see in a newspaper.   A newspaper is those black and white things old people read..    :)


PlayBASIC Code: [Select]
leftmargin=150
rightmargin=650

c=$304050
boxc 0,0,leftmargin,getsurfaceHeight(),true,c
boxc rightmargin,0,getsurfacewidth(),getsurfaceHeight(),true,c



do
message$=readdata$()
if len(Message$)
DrawAlignedText(Message$,LeftMargin,RightMargin)
else
exitdo
endif
loop

Sync
waitkey




data "Been testing an idea for a bit based z buffering"
Data "Rows of stupid text, asdfsdf"
data "type of simplification that could be parsed by a language"
data "wobble zoom bump and burp"
data ""




Function DrawAlignedText(T$,LeftMargin,RightMargin)

Ypos=GetCursorY()

Dim Frags$(255)
count=splittoarray(t$," ",Frags$(),0)

DisplayWidth=RightMargin-LeftMargin

Count2=Count-1

SpaceWidth=GEtTextWidth(" ")
for lp =0 to count2
s$=frags$(lp)
RawTextWidth+=GetTextWidth(S$)
next


Spacing#=float(DisplayWidth-RAwTextWidth)/Count2

XPos#=LeftMargin
For lp =0 to Count2
s$=frags$(lp)
text Xpos#,Ypos,s$
xpos#+=GetTextWidth(s$)+Spacing#
next

SetCursorY Ypos+GetTextHeight("|")
EndFUnction






 DrawAlignedMessage

    This version is the logical extension of the previous example, except this time the render function will handle long dialog styled messages, which will wrap and each row will be aligned within the display margins.

PlayBASIC Code: [Select]
   // set our margins 
leftmargin=150
rightmargin=650

// display the margin so the user can see it
c=$304050
boxc 0,0,leftmargin,getsurfaceHeight(),true,c
boxc rightmargin,0,getsurfacewidth(),getsurfaceHeight(),true,c


// make a big long message to display
message$="Been testing an idea for a bit based z buffering Rows of stupid text, asdfsdf type of simplification that could be parsed by a language wobble zoom bump and burp "
message$+=message$
message$+=message$


// render it within this long message within the bounds
DrawAlignedMessage(Message$,LeftMargin,RightMargin)


// show the screen, wait for a key press and end when the user hits a key
Sync
WaitKey
end




/*
------------------------------------------------------------------------------
------------------------------------------------------------------------------
---[ DRAW ALIGNED MESSAGE ]---------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

This function takes the longer input message split it up fragments and then
rendering the text so it wraps within the user defined margins while keeping
even spacing.

*/



type tMessageFragment
WordPos
WordSize
WidthInPixels
Row
EndType



Function DrawAlignedMessage(Message$,LeftMargin,RightMargin)

// compute the size this text should fit into
DisplayWidth=RightMargin-LeftMargin

// make sure there's some room between text fragments
TrimmedDisplayWidth=DisplayWidth-16

Dim Message(1000) as tMessageFragment


// break this message down into list of tokens

SearchStatus=true
LastPos =1
Xpos =0
TokenCount =0
RowCount =0

SpaceWidth =GetTExtWidth(" ")

// -------------------------------------------------------------------------
repeat // split the input message and lay it out in a tokenized form
// -------------------------------------------------------------------------

NextPos=instring(Message$," ",LastPOs)

if NextPOs=0
NextPos=len(Message$)+1
SearchDone=true
endif

ThisWord$=Mid$(Message$,LastPOs,NextPOs-LastPOs)

Message(TokenCount) = new tMessageFragment
Message(TokenCount).WordPos = LastPos
Message(TokenCount).WordSize = NextPOs-LastPos

WidthInPixels=GetTextWidth(ThisWord$)
Message(TokenCount).WidthInPixels = WidthInPixels

if Xpos+WidthInPixels+SpaceWidth>=TrimmedDisplayWidth
Xpos=0
RowCount++
else
Xpos+=WidthInPixels+SpaceWidth
endif
Message(TokenCount).Row = RowCount


TokenCount++

; move forward
LastPOs=NextPos +1
until SearchDone=true


// Get the Pens current Ypos on the screem, so it acts like print
Ypos=GetCursorY()

LastPOs=0
// -------------------------------------------------------------------------
For Rowlp=0 to RowCount ; RENDER ROWS
// -------------------------------------------------------------------------

// the number of pixels that will be in this row
TotalWidthOfRowInPixels=0

// find the end of this row up front and compute it's size in pixels
for Searchlp=LastPos to TokenCount-1
ThisRow=Message(Searchlp).row
if ThisRow=RowLP
NextPos=SearchLp
TotalWidthOfRowInPixels+=Message(Searchlp).WidthInPixels
else
exitfor searchlp
endif
next


TokensOnRow=NextPos-LastPos

// compute the
Spacing#=float(DisplayWidth-TotalWidthOfRowInPixels)/TokensOnRow

XPos#=LeftMargin
For Drawlp =LastPos TO NextPos
s$=mid$(MEssage$,Message(Drawlp).WordPos,Message(Drawlp).WordSize)
text Xpos#,Ypos,s$
xpos#+=Message(DrawLp).WidthInPixels+Spacing#
next
Ypos+=GetTextHeight("|")

LastPos=NextPos+1
next

Login required to view complete source code