1. Algorithmics
- Posted by Patrick.Barnes at transgrid.com.au Jan 17, 2003
- 329 views
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) ------------------------------------------------------------------- *********************************************************************** ***********************************************************************
2. Re: Algorithmics
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jan 17, 2003
- 345 views
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 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