marshall@software.ORG (Eric Marshall) (10/13/88)
Here is my first full NeWS application, the always popular *ruler*. Not just one ruler mind you, but three! The kind of rulers supported are English, Metric, and Unit. I almost forgot to mention that the ruler can be displayed either horizontally or vertically. Will the features ever stop? The only machine specific stuff about the ruler is the variable /units_per_inch, which is set to the number of units per inch :-) If your version of NeWS supports a correct default user space, set it to 72, otherwise figure the value out somehow. Sun NeWS 1.1 has the default user space set to be the monitor resolution, and the standard Sun monochrome monitor (which is what I have) has 83 pixels per inch. Enjoy. Eric Marshall Software Productivity Consortium 1880 North Campus Commons Drive Reston, VA 22091 (703) 391-1838 CSNET: marshall@software.org ARPANET: marshall%software.org@relay.cs.net OR @relay.cs.net:marshall@software.org ------------------------------------------------------------------------------ The OSF. Just say NO. ----- 8< ----- 8< ----- 8< ----- 8< ----- 8< ----- 8< ----- 8< ----- 8< ----- #! /usr/NeWS/bin/psh % % An English, Metric, and Unit ruler. % %% Sun NeWS 1.1 bug fixes -------------------------------------------- % default user space equals the device resolution rather than % 72 units per inch, standard Sun monochrome monitor resolution is /units_per_inch 83 def % work around show bug when using rotated text on monochrome % monitors, individually emit each character of the string /SHOW { { cvis show } forall } def %% Global Definitions ------------------------------------------------ % upper case letters are 17 units tall for 24 point Times-Bold % font (so says charpath and pathbbox) /half_text_height 8.5 def % kinds of rulers /english 1 def /metric 2 def /unit 3 def /ruler_kind unit def /horizontal_ruler? true def /ruler_width 0 def % logical width /ruler_height 0 def % logical height /ruler_menu [ (English) { /ruler_kind english store draw_ruler } (Metric) { /ruler_kind metric store draw_ruler } (Unit) { /ruler_kind unit store draw_ruler } (Vertical Ruler) { make_vertical_ruler } (Stretch Edge) { getfbclick pop pop /stretchwindowedge ThisWindow send } (Quit) { currentprocess killprocessgroup } ] /new DefaultMenu send def %% English Stuff ---------------------------------------------------------- /english_hash_distance units_per_inch 8 div def /english_unit_width units_per_inch def % % Draw the ruler markings for an English ruler. % /draw_english_markings { % draw_hash_labels? => - /draw_hash_labels? exch def /hash_counter 1 def /current_hash_label 1 def english_hash_distance english_hash_distance ruler_width english_unit_width add { /x exch def x 0 moveto 0 hash_counter 8 eq { % inch draw_hash_labels? { (Inch) draw_ruler_kind current_hash_label x draw_hash_label } if /current_hash_label current_hash_label 1 add def /hash_counter 0 def 20 } { hash_counter 4 eq { % 1/2 inch 12.5 } { hash_counter 2 mod 0 eq { % 1/4 inch 8 } { % 1/8 inch 5 } ifelse } ifelse } ifelse rlineto stroke /hash_counter hash_counter 1 add def } for } def %% Metric Stuff ---------------------------------------------------------- /metric_hash_distance units_per_inch 25.4 div def /metric_unit_width metric_hash_distance 50 mul def % % Draw the ruler markings for a Metric ruler. % /draw_metric_markings { % draw_hash_labels? => - /draw_hash_labels? exch def /hash_counter 1 def /current_hash_label 5 def metric_hash_distance metric_hash_distance ruler_width metric_unit_width add { /x exch def x 0 moveto 0 hash_counter 10 mod 0 eq { % centimeter hash_counter 50 eq { draw_hash_labels? { (CM) draw_ruler_kind current_hash_label x draw_hash_label } if /current_hash_label current_hash_label 5 add def /hash_counter 0 def } if 20 } { % millimeter 5 } ifelse rlineto stroke /hash_counter hash_counter 1 add def } for } def %% Unit Stuff ---------------------------------------------------------- /unit_hash_distance 10 def /unit_unit_width 100 def % % Draw the ruler markings for a Unit ruler. % /draw_unit_markings { % draw_hash_labels? => - /draw_hash_labels? exch def /hash_counter 1 def /current_hash_label 100 def unit_hash_distance unit_hash_distance ruler_width unit_unit_width add { /x exch def x 0 moveto 0 hash_counter 10 mod 0 eq { % 100 units 20 draw_hash_labels? { (Unit) draw_ruler_kind current_hash_label x draw_hash_label } if /current_hash_label current_hash_label 100 add def /hash_counter 0 def } { hash_counter 5 mod 0 eq { % 50 units 10 } { % 10 units 5 } ifelse } ifelse rlineto stroke /hash_counter hash_counter 1 add def } for } def %% Ruler Stuff ---------------------------------------------------------- % % Convert the horizontal ruler into a vertical ruler. % /make_vertical_ruler { % - => - /horizontal_ruler? false store % pivot the ruler about its center point /center_x win /FrameX get ruler_width 2 div add def /center_y win /FrameY get ruler_height 2 div add def center_x ruler_height 2 div sub center_y ruler_width 2 div sub ruler_height ruler_width /reshape win send % change menu entry back to "Horizontal Ruler" 3 (Horizontal Ruler) { make_horizontal_ruler } /changeitem ruler_menu send } def % % Convert the vertical ruler into a horizontal ruler. % /make_horizontal_ruler { % - => - /horizontal_ruler? true store % pivot the ruler about its center point /center_x win /FrameX get ruler_height 2 div add def /center_y win /FrameY get ruler_width 2 div add def center_x ruler_width 2 div sub center_y ruler_height 2 div sub ruler_width ruler_height /reshape win send % change menu entry back to "Vertical Ruler" 3 (Vertical Ruler) { make_vertical_ruler } /changeitem ruler_menu send } def % % Draw the kind of the ruler, English, Metric, or Unit. % /draw_ruler_kind { % ruler_kind => - gsave 10 ruler_height 2 idiv half_text_height sub moveto SHOW grestore } def % % Draw one of the ruler hash labels centered within the ruler. % /draw_hash_label { % x_position hash_label => - /x exch def /hash_label exch def /label_string 4 string def hash_label label_string cvs stringwidth pop /half_string_width exch 2 idiv def x half_string_width sub ruler_height 2 idiv half_text_height sub gsave moveto label_string SHOW grestore } def % % Draw the hash marks on the edge of the ruler. % /draw_hash_marks { % - => - 0 0 moveto % draw the bottom and top hash marks 1 1 2 { % invert the Y axis for the hash marks on the top 2 eq { 0 ruler_height translate [ 1 0 0 -1 0 0 ] concat false % draw_hash_labels? parameter to draw_XXX_markings routines } { true % draw_hash_labels? parameter to draw_XXX_markings routines } ifelse ruler_kind english eq { draw_english_markings } { ruler_kind metric eq { draw_metric_markings } { draw_unit_markings } ifelse } ifelse } for } def % % Draw the entire ruler. % /draw_ruler { % - => - win /ClientCanvas get setcanvas erasepage 0 strokecanvas % set up ruler for either horizontal or vertical display horizontal_ruler? { /ruler_width win /ClientWidth get store /ruler_height win /ClientHeight get store } { /ruler_width win /ClientHeight get store /ruler_height win /ClientWidth get store 0 ruler_width translate -90 rotate } ifelse draw_hash_marks } def %% Main ---------------------------------------------------------- /Times-Bold findfont 24 scalefont setfont /win framebuffer /new DefaultWindow send def { % remove the frame border, and redefine its associated methods /BorderLeft 0 def /BorderBottom 0 def /BorderRight 0 def /BorderTop 0 def /PaintFrame nullproc def /PaintFocus nullproc def /PaintClient { draw_ruler } def % redefine the menu /ClientMenu ruler_menu def } win send 150 450 850 90 /reshape win send /map win send