;+ ; NAME: ; STR_SIZE ; ; PURPOSE: ; ; The purpose of this function is to return the proper ; character size to make a specified string a specifed ; width in a window. The width is specified in normalized ; coordinates. The function is extremely useful for sizing ; strings and labels in resizeable graphics windows. ; ; AUTHOR: ; ; FANNING SOFTWARE CONSULTING ; David Fanning, Ph.D. ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: david@idlcoyote.com ; Coyote's Guide to IDL Programming: http://www.idlcoyote.com/ ; ; CATEGORY: ; ; Graphics Programs, Widgets. ; ; CALLING SEQUENCE: ; ; thisCharSize = STR_SIZE(thisSting, targetWidth) ; ; INPUTS: ; ; thisString: This is the string that you want to make a specifed ; target size or width. ; ; OPTIONAL INPUTS: ; ; targetWidth: This is the target width of the string in normalized ; coordinates in the current graphics window. The character ; size of the string (returned as thisCharSize) will be ; calculated to get the string width as close as possible to ; the target width. The default is 0.25. ; ; KEYWORD PARAMETERS: ; ; INITSIZE: This is the initial size of the string. Default is 1.0. ; ; STEP: This is the amount the string size will change in each step ; of the interative process of calculating the string size. ; The default value is 0.05. ; ; XPOS: X position of the output test string. This can be ; used on the Postscript device, where no pixmap windows are ; available and where therefore the test strings would appear on ; the printable area. Default is 0.5 on most devices. If !D.NAME ; is PS, the default is 2.0 to draw the test string out of the ; drawable window area. ; ; YPOS: Y position of the output test string. This can be ; used on the Postscript device, where no pixmap windows are ; available and where therefore the test strings would appear on ; the printable area. Default is 0.5 on most devices. If !D.NAME ; is PS, the default is 2.0 to draw the test string out of the ; drawable window area. ; ; OUTPUTS: ; ; thisCharSize: This is the size the specified string should be set ; to if you want to produce output of the specified target ; width. The value is in standard character size units where ; 1.0 is the standard character size. ; ; EXAMPLE: ; ; To make the string "Happy Holidays" take up 30% of the width of ; the current graphics window, type this: ; ; XYOUTS, 0.5, 0.5, ALIGN=0.5, "Happy Holidays", $ ; CHARSIZE=STR_SIZE("Happy Holidays", 0.3) ; ; MODIFICATION HISTORY: ; ; Written by: David Fanning, 17 DEC 96. ; Added a scaling factor to take into account the aspect ratio ; of the window in determing the character size. 28 Oct 97. DWF ; Added check to be sure hardware fonts are not selected. 29 April 2000. DWF. ; Added a pixmap to get proper scaling in skinny windows. 16 May 2000. DWF. ; Forgot I can't do pixmaps in all devices. :-( Fixed. 7 Aug 2000. DWF. ; Added support of PostScript at behest of Benjamin Hornberger. 11 November 2004. DWF. ; Cleaned up the code a bit. 28 Feb 2011. DWF. ; Fixed non-square window algorithm to reflect my original intentions. 10 June 2011. ;- ; ;******************************************************************************************; ; Copyright (c) 2008, by Fanning Software Consulting, Inc. ; ; All rights reserved. ; ; ; ; Redistribution and use in source and binary forms, with or without ; ; modification, are permitted provided that the following conditions are met: ; ; ; ; * Redistributions of source code must retain the above copyright ; ; notice, this list of conditions and the following disclaimer. ; ; * Redistributions in binary form must reproduce the above copyright ; ; notice, this list of conditions and the following disclaimer in the ; ; documentation and/or other materials provided with the distribution. ; ; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ; ; contributors may be used to endorse or promote products derived from this ; ; software without specific prior written permission. ; ; ; ; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ; ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ; ; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ; ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;******************************************************************************************; FUNCTION STR_SIZE, theString, targetWidth, $ INITSIZE=initsize, $ STEP=step, $ XPOS=xpos, $ YPOS=ypos ON_ERROR, 2 ; No hardware fonts. thisFont = !P.Font IF (thisFont EQ 0) AND (!D.NAME NE 'PS') THEN !P.Font = -1 ; Check positional parameters. np = N_PARAMS() CASE np OF 0: MESSAGE, 'One string parameter is required.' 1: targetWidth = 0.25 ELSE: ENDCASE ; Check keywords. Assign default values. IF N_ELEMENTS(initsize) EQ 0 THEN initsize = 1.0 IF N_ELEMENTS(step) EQ 0 THEN step = 0.05 IF N_ELEMENTS(xpos) EQ 0 THEN IF !D.NAME NE 'PS' THEN xpos = 0.5 ELSE xpos = 2.0 IF N_ELEMENTS(ypos) EQ 0 THEN IF !D.NAME NE 'PS' THEN ypos = 0.5 ELSE ypos = 2.0 ; Save the current window index number. currentWindow = !D.Window ; This is the algorithm that makes this work. Reverse size of ; window if is window is taller than wider. IF((!D.Flags AND 256) NE 0) THEN BEGIN IF !D.X_Size LE !D.Y_Size THEN BEGIN Window, /Pixmap, /Free, XSize=!D.X_Size, YSize=!D.Y_Size ENDIF ELSE BEGIN Window, /Pixmap, /Free, XSize=!D.Y_Size, YSize=!D.X_Size ENDELSE pixID = !D.Window ENDIF ; Calculate a trial width. strTrialSize = initsize XYOUTS, xpos, ypos, ALIGN=0.5, theString, WIDTH=thisWidth, $ CHARSIZE=-strTrialSize, /NORMAL ; Three possibilities for comparison. CASE 1 OF ; Initial size is perfect. (thisWidth EQ targetWidth): BEGIN theSize = strTrialSize END ; Initial size is too big. (thisWidth GT targetWidth): BEGIN REPEAT BEGIN XYOUTS, xpos, ypos, ALIGN=0.5, theString, WIDTH=thisWidth, $ CHARSIZE=-strTrialSize, /NORMAL strTrialSize = strTrialSize - step ENDREP UNTIL thisWidth LE targetWidth theSize = strTrialSize END ; Initial size is too small. (thisWidth LT targetWidth): BEGIN REPEAT BEGIN XYOUTS, xpos, ypos, ALIGN=0.5, theString, WIDTH=thisWidth, $ CHARSIZE=-strTrialSize, /NORMAL strTrialSize = strTrialSize + step ENDREP UNTIL thisWidth GT targetWidth strTrialSize = strTrialSize - (step/2.0) ; Need a value slightly smaller than target. theSize = strTrialSize END ENDCASE ; Cleanup. !P.Font = thisFont IF currentWindow NE -1 THEN WSet, currentWindow IF N_Elements(pixID) NE 0 THEN WDelete, pixID RETURN, theSize END