1. Algorithmics

I have a sizing algorithm to determine what the maximum font size allowable for
a sections of text in a window is...


I.e. if my text is "This is a test of the automatic\ntext sizing system."
It would recognise that the text takes up two lines, then see how big it can
make the text without making it go outside the area (in this case, the window)

Only problem is, it's very slow, especially for larger font sizes. (try
maximising the window)
The slow code is I think restricted to within the --#START OF CODE THAT IS TOO
SLOW#-- tags.

Can anyone see what could be improved?


Thanks
==============================================
 _______<-------------------\__
/  _____<--------------------__|===
| |_    <-------------------/
\__| Patrick Barnes





--------------------------------------------------------------------------------------
include win32lib.ew
without warning

constant win = create(Window, "Text scaling", 0, Default, Default, 200, 340, 0)

--constant text = "This is a test of the automatic\ntext sizing system."
constant text = "1\n2"
constant TABSIZE = 6
constant TAB = 9

atom dwin

--returns a sequence with the x,y size of the lines of text submitted
global function getMlTextExtent(integer win, sequence mtext, integer
linespacing)
	integer lnum, maxw
	lnum = length(mtext)
	maxw = 0
	for a = 1 to lnum do
		if getTextWidth(win, mtext[a]) > maxw then
			maxw = getTextWidth(win, mtext[a])
		end if
	end for
	return {maxw   ,   (lnum-1) * linespacing + (lnum)*getTextHeight(win, "T")}
end function

--takes a string and tokenises it into lines
global function toLinesText(sequence text)
	sequence lines
	atom ctr

	if not length(text) then --if no text, then don't bother
		return {}
elsif text[length(text)] = '\n' then --if the last char is a '\n' then get rid
of it.
		text = text[1..length(text) - 1]
	end if
	
	lines = {{}}
	ctr = 1
	for a = 1 to length(text) do --step through every letter, building up the lines
		if text[a] = TAB then
lines[ctr] &= repeat(' ', remainder( TABSIZE * ( floor( length(lines[ctr]) /
TABSIZE) + 1), length(lines[ctr]) ) )
		elsif text[a] = '\n' then
			lines &= {{}}
			ctr += 1
		elsif text[a] = '\r' then
			--ignore that character
		else lines[ctr] &= text[a]
		end if
	end for

	return lines	
end function

--correctly sizes the text to fit the window, and prints it out.
global procedure display(integer win, integer event, sequence params)
	sequence lines, pos, wsize, tsize
	atom fsize
	lines = toLinesText(text)	--splits text into lines
	pos = {0,0} --sets the text starting position
	wsize = getClientRect(win)	
	wsize = wsize[3..4] - wsize[1..2]	--get the window size
--#START OF CODE THAT IS TOO SLOW#--
	fsize = 1	--starting font size
	while 1 do
		--find the size of that text
		setFont(win, "Times New Roman", fsize, Normal)	
		tsize = getMlTextExtent(win, lines, 0)
		--if it's bigger than the window...
		if tsize[1] >= wsize[1] or tsize[2] >= wsize[2] then
			fsize -=1 --then exit
			exit
		end if
		fsize += 1 --otherwise make the text bigger and try again.
	end while
--#END OF CODE THAT IS TOO SLOW#--	
	--draw the text on the window.
	setFont(win, "Times New Roman", fsize, Normal)	
	for a = 1 to length(lines) do
			wPuts({win, pos[1], pos[2]}, lines[a])
			pos[2] += getTextHeight(win, lines[a])
	end for


end procedure
setHandler(win, w32HPaint, routine_id("display") )


procedure c(integer ID, integer Event, sequence params)
	closeWindow(win)
end procedure
setHandler(win, w32HKeyDown, routine_id("c") )

procedure resized(integer ID, integer Event, sequence params)
	repaintWindow(win)
end procedure
setHandler(win, w32HResize, routine_id("resized") )

WinMain(win, Normal)
-------------------------------------------------------------------


***********************************************************************




***********************************************************************

new topic     » topic index » view message » categorize

2. Re: Algorithmics

On Fri, 17 Jan 2003 11:47:31 +1100, Patrick.Barnes at transgrid.com.au
wrote:

>Can anyone see what could be improved?
A quick hack at a binary chop smile
Code may need cleaning a bit but seems to work:
integer bsize, ssize
--#START OF CODE THAT IS TOO SLOW#--
	fsize =3D 8	--starting font size
	ssize =3D 1
	bsize =3D 0
	while 1 do
		--find the size of that text
		setFont(win, "Times New Roman", fsize, Normal)=09
		tsize =3D getMlTextExtent(win, lines, 0)
		--if it's bigger than the window...
		if tsize[1] >=3D wsize[1] or tsize[2] >=3D wsize[2] then
			bsize=3Dfsize
			fsize=3Dssize+floor((fsize-ssize)/2)
			if fsize=3Dssize then
				exit
			end if
		else
			ssize=3Dfsize
			if bsize=3D0 then
				fsize*=3D2
			else
				if fsize+1=3Dbsize then exit end if
				fsize+=3Dfloor((bsize-fsize)/2)
			end if
		end if
	end while
--#END OF CODE THAT IS TOO SLOW#--=09

Pete

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu