Viewing contents of file '../idllib/contrib/windt/text_width.pro'
;+
; NAME:
;
; TEXT_WIDTH
;
; PURPOSE:
;
; Function to determine the actual displayed width
; (approximately!) of a string of text, in normalized character
; units, accounting for the fact that non-equal spacing is used
; when such a string is displayed on a plot using XYOUTS.
;
; This function is used, for example, by the PLOT_TEXT and
; LEGEND procedures to ~correctly draw a box around displayed
; text.
;
; CALLING SEQUENCE:
;
; Result=TEXT_WIDTH(TEXT_STRING)
;
; INPUTS:
;
; TEXT_STRING - a string of text
;
; KEYWORD PARAMETERS:
;
; FONT - Set to an integer from 3 to 20 (corresponding to the
; Hershey vector font sets,) referring to the font that
; will be used to display the text. (Any font commands
; embedded in the text string are ignored.)
;
; RESTRICTIONS:
;
; This function hardly works perfectly, especially when the text
; string contains a mix of fonts; superscripts and subscripts
; will really mess things up as well. But it comes close in
; many instances.
;
; PROCEDURE:
;
; A table of normalized character widths (determined using the
; !3 font) is used to determine the width of the text string.
; In order to account for the use of IDL font manipulation
; commands, the '!' symbol and the character immediately
; following it are not counted, except for the case of two
; consecutive '!' symbols.
;
; EXAMPLE:
;
; Determine the width of a text string:
;
; width=TEXT_WIDTH('!3This is some displayed text',font=3)
;
; MODIFICATION HISTORY:
;
; David L. Windt, Bell Labs, October 1997
; windt@bell-labs.com
;
;-
function text_width,text_string,font=font
on_error,2
;; make a table of normalized widths for every character from #32 to
;; #127, as determined using the !3 font set.
c_ids=bindgen(128-32)+32B
widths=$
[.91,.27,.84,1.095,1.05,1.26,1.37,.42,.74,.74,.84,1.37, $
.525,1.365,.525,1.15, $
1.05,1.05,1.05,1.05,1.05,1.05,1.05,1.05,1.05,1.05, $
.525,.525,1.26,1.365,1.26,.95,1.42, $
.95,1.1,1.1,1.1,1.,.95,1.1,1.16,.415,.84,1.1,.9]
widths=[widths, $
1.26,1.16,1.16,1.1,1.16,1.1,1.05,.845,1.16,.95,1.26,1.05, $
.95,1.05,.74,.75,.74,.53,.95,.42,1.,1.,.95,1., $
.95,.63,1.,1.,.42,.52,.89,.42,1.57,1.,1.,1., $
1.,.68,.89,.63,1.,.845,1.15,.895,.85,.89, $
.74,.52,.74,.53,1.]
;; sp ! " # $ % & ' ( ) * +
;; , - . /
;; 0 1 2 3 4 5 6 7 8 9
;; : ; < = > ? @
;; A B C D E F G H I J K L
;; M N O P Q R S T U V W X
;; Y Z [ \ ] ^ _ ' a b c d
;; e f g h i j k l m n o p
;; q r s t u v w x y z
;; { | } ^
;; compute average character width:
st=stdev(widths,avg)
;; initialize values:
width=0.
last_was_bang=0
for i=0,strlen(text_string)-1 do begin
character=byte(strmid(text_string,i,1))
wh=where(character(0) eq c_ids,count)
case 1 of
;; other character? add avg. width
count eq 0: if last_was_bang then last_was_bang=0 $
else width=width+avg
;; '!' character: count the width of this character
;; if the last character was also a '!', otherwise
;; just set the last_was_bang flag.
character(0) eq 33B: if last_was_bang then $
width=width+widths(wh(0)) $
else last_was_bang=1
;; otherwise just add character width:
else: if last_was_bang then last_was_bang=0 $
else width=width+widths(wh(0))
endcase
endfor
;; make some attempt to scale for different font sets:
if keyword_set(font) then begin
case font of
4: width=width*1.04
5: width=width*1.03
6: width=width*1.09
7: width=width*1.1
8: width=width*1.14
9: width=width*1.16
10: width=width*1.45
11: width=width*1.07
12: width=width*.97
13: width=width*.96
14: width=width*1.12
15: width=width*1.12
16: width=width*1.21
17: width=width*1.08
18: width=width*1.14
19: ;;
20: width=width*.87
else: ;;
endcase
endif
;; adjust for output using PostScript hardware fonts:
if (!d.name eq 'PS') and (!p.font eq 0) then width=width*.925
return,width
end