The main reason for text clipping is because all other 2d elements clip, but text just vanished when it's beyond the clip region. So to make everything flow I wanted to clip the text.
The method I'm using at the moment is just like TheComet said but simpler I think (Letter Clipping)
I first check if the text bounds over lap the clip bounds, if not then don't display anything. Anything that over laps on the y axis just clip until it's fully within in the clip bounds. With the x bounds, just either check if it's less than the clip bounds via letter count until it's not and remove the text by the letter count and shift it by the offset of that count, and if it's beyond the width of the clip, just min the len of the str until it fits, simple.
Example: Press any key to toggle clipping on and off
type rect
x as integer
y as integer
w as integer
h as integer
endtype
global _clipRegion as rect
global _enableClip as byte
sync on : sync rate 0
// just for display
type txt
s as string
x,y
endtype
dim t(100) as txt
for n = 0 to 100
t(n).s = "HELLO World"
t(n).x = rnd(screen width()-text width("HELLO World"))
t(n).y = rnd(screen height()-text size() )
next
///////////////////
do : cls rgb(64,64,64)
x = mousex()
y = mousey()
// toggle clipping
if scancode() <> 0 and down = 0
down = 1 : clipping = 1-clipping
endif
if scancode() = 0 then down = 0
if clipping then setTextClip( x-100,y-100,200,200 )
drawTextClip()
for n = 0 to 100
drawText( t(n).s, t(n).x, t(n).y )
next
resetTextClip()
ink rgb(255,255,255),0
text 0,0,"Move Mouse to Reveal"
text 0,12,"Press Any Key to toggle Clipping: "+str$(clipping)
text 0,24,"FPS: "+str$(screen fps())
sync
loop
function setTextClip( x,y,w,h )
_clipRegion.x = x : _clipRegion.y = y
_clipRegion.w = w : _clipRegion.h = h
_enableClip = 1
endfunction
function resetTextClip()
_enableClip = 0
endfunction
function drawTextClip()
if _enableClip
a2box _clipRegion.x-1,_clipRegion.y-1,_clipRegion.x+_clipRegion.w+1,_clipRegion.y+_clipRegion.h+1,rgb(255,0,0)
endif
endfunction
function drawText( str as string, x, y )
local textRight as integer
local textBottom as integer
local clipRight as integer
local clipBottom as integer
local offset as integer
local letterCount as integer
local xValid as byte
local yValid as byte
if not len(str) then exitfunction
if _enableClip
textRight = x + text width(str)
textBottom = y + text size()
clipRight = _clipRegion.x + _clipRegion.w
clipBottom = _clipRegion.y + _clipRegion.h
// check if the text is overlapping the clipping region
xValid = (( x >= _clipRegion.x ) && ( x <= clipRight ))
xValid = xValid || (( _clipRegion.x >= x ) && ( _clipRegion.x <= textRight ))
yValid = (( y >= _clipRegion.y ) && ( textBottom <= clipBottom ))
yValid = yValid || (( _clipRegion.y >= y ) && ( _clipRegion.y <= y ))
if not yValid then exitfunction
if xValid
// if text is fully inside the clip then...
if (x > _clipRegion.x) && (textRight < clipRight)
text x, y, str
exitfunction
endif
`positive x
if textRight > clipRight
while (x+text width(left$(str,len(str)))) > clipRight
str = left$(str,len(str)-1)
endwhile
endif
`negative x
if x < _clipRegion.x
while (x+offset) < _clipRegion.x
inc letterCount : offset = text width( left$(str,letterCount) )
endwhile
str = right$(str,len(str)-letterCount)
x = x+offset
endif
text x, y, str
endif
else
text x, y, str
endif
endfunction
I just wanted to see if there was a effective way of clipping say half way across a letter without grabbing or copying bits of the screen, though a render target is great for dynamic text. Most bits of text can be stored in images but things that change constant need could be stored in a render target. Depends how much is required on the screen.
"Get in the Van!" - Van B