(FILECREATED "17-Feb-87 09:42:32" {QV}<NOTECARDS>1.3K>NEXT>PMIPATCH015.;18 42802  

      changes to:  (VARS PMIPATCH015COMS)
		   (PROPS (NC.NoteCardsParameters LinkIconMaxWidthInPixels)
			  (NC.NoteCardsParameters LinkIconBorderWidth))
		   (FNS NC.LinkIconDisplayFn NC.SetLinkIconMaxWidth NC.SetLinkIconBorderWidth 
			NC.DrawInnerBox NC.LinkIconImageBoxFn NC.CreateLinkIconStrings)

      previous date: "13-Feb-87 09:56:52" {QV}<NOTECARDS>1.3K>NEXT>PMIPATCH015.;13)


(* Copyright (c) 1987 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT PMIPATCH015COMS)

(RPAQQ PMIPATCH015COMS ((* * pmi 2/13/87: Introducing Multi-line link icons! Adds two new 
			     user-setable global parameters which control how link text will display: 
			     LinkIconMultiLineMode - T for mult-lines, NIL for single lines, and 
			     LinkIconMaxWidthInPixels - maximum width in pixels of a link icon
			     (including bitmap, if displayed)
			     %. Fixes bug 201: Link image objects should wrap if title too long, and 
			     bug 248: Card titles wider than the screen mess up link icons. Also puts 
			     global parameter NC.LinkIconBorderWidth (LinkIconBorderWidth)
			     on the parameters menu so users can control border, including setting it 
			     to 0 for icons that blend smoothly with text.)
			  (* * New NCLINKS Globalvar)
			  (GLOBALVARS NC.LinkIconSpaceInterLine)
			  (* * New NCLINKS Initvar)
			  (INITVARS (NC.LinkIconSpaceInterLine 0))
			  (* * Change to NCLINKS Initvar)
			  (INITVARS (NC.LinkIconSpaceInnerX 3))
			  (* * Changes to NCLINKS functions)
			  (FNS NC.LinkIconDisplayFn NC.LinkIconImageBoxFn)
			  (* * New NCLINKS function)
			  (FNS NC.CreateLinkIconStrings)
			  (* * New NCPARAMETERS Globalvars)
			  (GLOBALVARS NC.LinkIconMultiLineMode NC.LinkIconMaxWidth)
			  (* * New NCPARAMETERS Initvars)
			  (INITVARS (NC.LinkIconMultiLineMode NIL)
				    (NC.LinkIconMaxWidth SCREENWIDTH))
			  (* * Additions to NCPARAMETERS props)
			  (PROPS (NC.NoteCardsParameters LinkIconMultiLineMode)
				 (NC.NoteCardsParameters LinkIconMaxWidthInPixels)
				 (NC.NoteCardsParameters LinkIconBorderWidth))
			  (* * New NCPARAMETERS functions)
			  (FNS NC.SetLinkIconMaxWidth NC.SetLinkIconBorderWidth)
			  (* * Changes to NCUTILITIES functions)
			  (FNS NC.DrawInnerBox)
			  (* * New NCUTILITIES function)
			  (FNS NC.ParseString)
			  (* * Only for the patch file. Do not integrate into the sources.)
			  (VARS (NC.NoteCardsParameters (PROPNAMES (QUOTE NC.NoteCardsParameters)))
				(NC.LinkIconSpaceInnerX 3))))
(* * pmi 2/13/87: Introducing Multi-line link icons! Adds two new user-setable global 
parameters which control how link text will display: LinkIconMultiLineMode - T for mult-lines, 
NIL for single lines, and LinkIconMaxWidthInPixels - maximum width in pixels of a link icon (
including bitmap, if displayed) %. Fixes bug 201: Link image objects should wrap if title too 
long, and bug 248: Card titles wider than the screen mess up link icons. Also puts global 
parameter NC.LinkIconBorderWidth (LinkIconBorderWidth) on the parameters menu so users can 
control border, including setting it to 0 for icons that blend smoothly with text.)

(* * New NCLINKS Globalvar)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.LinkIconSpaceInterLine)
)
(* * New NCLINKS Initvar)


(RPAQ? NC.LinkIconSpaceInterLine 0)
(* * Change to NCLINKS Initvar)


(RPAQ? NC.LinkIconSpaceInnerX 3)
(* * Changes to NCLINKS functions)

(DEFINEQ

(NC.LinkIconDisplayFn
  (LAMBDA (ImageObj ImageStream StreamType TextStream Scale)
                                                             (* pmi: "13-Feb-87 14:19")

          (* * Display a link icon)



          (* * rht 11/13/84: Made width of box lines also scale dependent.)



          (* * rht 12/4/84: Hacked so type-dependent icons come out optionally to left of text.)



          (* * rht 2/9/85: Changed to use new display mode format.)



          (* * fgh 2/5/86 Added call to NC.FetchLinkIconAttachedBitMap)



          (* * rht & fgh 5/9/86: Massive hacking to display coords, etc.)



          (* * fgh 5/9/86 Added DSPFONT kludge after TypeIcon BITBLT to get around bug in PRESS BITBLT.
	  Bug reported as AR %#5630.0)



          (* * rht 5/10/86: Rearranged order of expressions a bit and added arg to call to NC.FetchLinkIconAttachedBitMap in 
	  order to get a bitmap with correct height for the box we're drawing.)



          (* * rht 8/7/86: Now passes Scale argument to NC.FetchLinkIconAttachedBitMap. Also uses the Title and Label args if
	  non-nil. If not, then recomputes them more sensibly.)



          (* * rht 8/25/86: Fixed improperly placed comment.)



          (* * pmi 2/11/87: Overhauled to accommodate multi-line link icons)


    (DECLARE (GLOBALVARS NC.LinkIconMultiLineMode NC.LinkIconMaxWidth NC.LinkIconSpaceInnerX 
			     NC.LinkIconSpaceOuterX NC.LinkIconAttachBitmapFlg NC.LinkIconSpaceInnerY 
			     NC.LinkIconSpaceOuterY NC.LinkIconSpaceInterLine NC.LinkIconBorderWidth 
			     NC.LinkIconShowLinkTypeFlg NC.LinkIconShowTitleFlg))
    (RESETLST (RESETSAVE NIL (BQUOTE (DSPFONT , (DSPFONT NC.LinkIconFont ImageStream)
						      , ImageStream)))
		(PROG ((Scale (DSPSCALE NIL ImageStream))
			 (Link (NC.FetchLinkFromLinkIcon ImageObj))
			 Font FontHeight FontAscent FontDescent Left Bottom Top ShowTitleFlg 
			 LinkDisplayMode AttachBitmapFlg DisplayType Window Card Title Label 
			 LinkIconString LinkIconStrings BoxWidth BoxHeight ImageBox Icon 
			 ScaledIconHeight ScaledIconWidth XPosition ScaledBorderWidth 
			 ScaledSpaceInnerX ScaledSpaceOuterX ScaledSpaceInnerY ScaledSpaceOuterY 
			 ScaledSpaceInterLine HalfScaledSpaceInterLine)
		        (SETQ Font (DSPFONT NIL ImageStream))
		        (SETQ FontHeight (FONTHEIGHT Font))

          (* * Determine what type of Display to do)


		        (SETQ DisplayType (fetch (Link DisplayMode) of Link))
		        (SETQ ShowTitleFlg (fetch (LINKDISPLAYMODE SHOWTITLEFLG) of DisplayType)
			  )
		        (SETQ Card (if (EQ ShowTitleFlg (QUOTE SOURCE))
					 then (fetch (Link SourceCard) of Link)
				       else (fetch (Link DestinationCard) of Link)))
		        (SETQ LinkDisplayMode (fetch (LINKDISPLAYMODE SHOWLINKTYPEFLG)
						   of DisplayType))
		        (SETQ AttachBitmapFlg (fetch (LINKDISPLAYMODE ATTACHBITMAPFLG)
						   of DisplayType))
		        (SETQ AttachBitmapFlg (if (EQ AttachBitmapFlg (QUOTE FLOAT))
						    then NC.LinkIconAttachBitmapFlg
						  else AttachBitmapFlg))

          (* * Construct the text for the link icon)


		        (SETQ Title (if (AND ShowTitleFlg (OR (NEQ ShowTitleFlg
									     (QUOTE FLOAT))
								      NC.LinkIconShowTitleFlg))
					  then (NC.RetrieveTitle Card)
					else NIL))
		        (SETQ Label (AND (COND
					       ((EQ LinkDisplayMode (QUOTE FLOAT))
						 NC.LinkIconShowLinkTypeFlg)
					       (T LinkDisplayMode))
					     (fetch (Link Label) of Link)))
		        (SETQ LinkIconString (CONCAT (COND
							   (Label (CONCAT "<" Label ">"))
							   (T ""))
							 (COND
							   ((AND Label Title)
							     " ")
							   (T ""))
							 (OR Title "")))

          (* * Make temporaries of scaled variables)


		        (SETQ ScaledBorderWidth (TIMES Scale NC.LinkIconBorderWidth))
		        (SETQ ScaledSpaceInnerX (TIMES Scale NC.LinkIconSpaceInnerX))
		        (SETQ ScaledSpaceOuterX (TIMES Scale NC.LinkIconSpaceOuterX))
		        (SETQ ScaledSpaceInnerY (TIMES Scale NC.LinkIconSpaceInnerY))
		        (SETQ ScaledSpaceOuterY (TIMES Scale NC.LinkIconSpaceOuterY))
		        (SETQ ScaledSpaceInterLine (TIMES Scale NC.LinkIconSpaceInterLine))
		        (SETQ HalfScaledSpaceInterLine (IQUOTIENT ScaledSpaceInterLine 2))

          (* * Set up the icon, if displayed)


		        (SETQ ImageBox (IMAGEOBJPROP ImageObj (QUOTE BOUNDBOX)))
		        (if AttachBitmapFlg
			    then 

          (* * Attached icon)



          (* * Use an estimate of the width and height to tell if the box contains more than one line of text)


				   (if NC.LinkIconMultiLineMode
				       then 

          (* * Multi-line link icons are enabled)


					      (SETQ ApproxBoxWidth (PLUS ScaledSpaceOuterX 
									     ScaledBorderWidth 
									     ScaledSpaceInnerX
									     (STRINGWIDTH 
										   LinkIconString 
											    Font)
									     ScaledSpaceInnerX 
									     ScaledBorderWidth 
									     ScaledSpaceOuterX))
					      (SETQ ApproxBoxHeight
						(PLUS ScaledSpaceOuterY ScaledBorderWidth 
							ScaledSpaceInnerY FontHeight 
							ScaledSpaceInnerY ScaledBorderWidth 
							ScaledSpaceOuterY))
					      (if ImageBox
						  then 

          (* * The image box has already been calculated. Use the box height to determine if Multi-line or Single line.
	  Calculate the correct bitmap.)


							 (SETQ BoxHeight (fetch (IMAGEBOX
										      YSIZE)
									      of ImageBox))
							 (if (GREATERP BoxHeight ApproxBoxHeight)
							     then 
                                                             (* Calculate height for Multi-line icon)
								    (SETQ ScaledIconHeight
								      (PLUS ScaledBorderWidth 
									      ScaledSpaceInnerY 
									      FontHeight 
									 HalfScaledSpaceInterLine))
							   else 
                                                             (* Calculate height for Single line icon)
								  (SETQ ScaledIconHeight
								    (PLUS ScaledBorderWidth 
									    ScaledSpaceInnerY 
									    FontHeight 
									    ScaledSpaceInnerY 
									    ScaledBorderWidth)))
							 (SETQ Icon (
							     NC.FetchLinkIconAttachedBitMap Card 
										 ScaledIconHeight 
											    Scale))
							 (SETQ ScaledIconHeight
							   (TIMES Scale (BITMAPHEIGHT Icon)))
							 (SETQ ScaledIconWidth (TIMES
							     Scale
							     (BITMAPWIDTH Icon)))
						else 

          (* * The image box must be calculated)


						       (if (GREATERP ApproxBoxWidth 
									 NC.LinkIconMaxWidth)
							   then 
                                                             (* Calculate Multi-line icon)
								  (SETQ ScaledIconHeight
								    (PLUS ScaledBorderWidth 
									    ScaledSpaceInnerY 
									    FontHeight 
									 HalfScaledSpaceInterLine))
								  (SETQ Icon (
								   NC.FetchLinkIconAttachedBitMap
								      Card ScaledIconHeight Scale))
								  (SETQ ScaledIconHeight
								    (TIMES Scale (BITMAPHEIGHT
									       Icon)))
								  (SETQ ScaledIconWidth
								    (TIMES Scale (BITMAPWIDTH
									       Icon)))
							 else 
                                                             (* Calculate Single line icon)
								(SETQ ScaledIconHeight
								  (PLUS ScaledBorderWidth 
									  ScaledSpaceInnerY 
									  FontHeight 
									  ScaledSpaceInnerY 
									  ScaledBorderWidth))
								(SETQ Icon (
								   NC.FetchLinkIconAttachedBitMap
								    Card ScaledIconHeight Scale))
								(SETQ ScaledIconHeight
								  (TIMES Scale (BITMAPHEIGHT
									     Icon)))
								(SETQ ScaledIconWidth
								  (TIMES Scale (BITMAPWIDTH
									     Icon)))

          (* * Now see if total width, including the icon, will still fit if this is a Single line)


								(if (GREATERP (PLUS 
										   ApproxBoxWidth 
										  ScaledIconWidth)
										  NC.LinkIconMaxWidth)
								    then 
                                                             (* Now it doesn't fit. Calculate Multi-line icon)
									   (SETQ ScaledIconHeight
									     (PLUS 
										ScaledBorderWidth 
										ScaledSpaceInnerY 
										     FontHeight 
									 HalfScaledSpaceInterLine))
									   (SETQ Icon
									     (
								   NC.FetchLinkIconAttachedBitMap
									       Card ScaledIconHeight 
									       Scale))
									   (SETQ ScaledIconHeight
									     (TIMES Scale
										      (BITMAPHEIGHT
											Icon)))
									   (SETQ ScaledIconWidth
									     (TIMES Scale
										      (BITMAPWIDTH
											Icon))))))
				     else 

          (* * Multi-line link icons are disabled)


					    (SETQ ScaledIconHeight (PLUS ScaledBorderWidth 
									     ScaledSpaceInnerY 
									     FontHeight 
									     ScaledSpaceInnerY 
									     ScaledBorderWidth))
					    (SETQ Icon (NC.FetchLinkIconAttachedBitMap Card 
										 ScaledIconHeight 
											   Scale))
					    (SETQ ScaledIconHeight (TIMES Scale (BITMAPHEIGHT
										Icon)))
					    (SETQ ScaledIconWidth (TIMES Scale (BITMAPWIDTH
									       Icon))))
			  else 

          (* * No attached icon)


				 (SETQ Icon NIL)
				 (SETQ ScaledIconHeight 0)
				 (SETQ ScaledIconWidth 0))

          (* * If the width of the icon is greater than the LinkIconMaxWidth set by the user, set the icon to NIL because we 
	  can't print it.)


		        (if (AND Icon (GREATERP ScaledIconWidth NC.LinkIconMaxWidth))
			    then (SETQ Icon NIL)
				   (SETQ ScaledIconHeight 0)
				   (SETQ ScaledIconWidth 0)
				   (SETQ LinkIconStrings (LIST ""))
			  else 

          (* * Have the text parsed into separate lines)


				 (SETQ LinkIconStrings (NC.CreateLinkIconStrings Link 
										   LinkIconString 
										     Icon ImageStream)
				   ))

          (* * Get the image box info for this icon)


		        (SETQ ImageBox
			  (OR ImageBox
				(NC.LinkIconImageBoxFn ImageObj ImageStream NIL NIL NIL DisplayType 
							 Title Label LinkIconString Icon 
							 LinkIconStrings)))

          (* * Compute all the size values.)


		        (SETQ Bottom (PLUS (DIFFERENCE (DSPYPOSITION NIL ImageStream)
							     (fetch (IMAGEBOX YDESC)
								of ImageBox))
					       ScaledSpaceOuterY))
		        (SETQ BoxHeight (DIFFERENCE (fetch (IMAGEBOX YSIZE) of ImageBox)
							(PLUS ScaledSpaceOuterY ScaledSpaceOuterY)))
		        (SETQ Top (PLUS Bottom BoxHeight))
		        (SETQ Left (PLUS (DSPXPOSITION NIL ImageStream)
					     ScaledSpaceOuterX))
		        (SETQ BoxWidth (DIFFERENCE (fetch (IMAGEBOX XSIZE) of ImageBox)
						       (PLUS ScaledSpaceOuterX ScaledSpaceOuterX)))

          (* * Put out the icon bitmap for the appropriate type, but only if the width of the icon does not exceed the 
	  LinkIconMaxWidth set by the user.)


		        (if Icon
			    then (BITBLT Icon 0 0 ImageStream Left (DIFFERENCE Top 
										 ScaledIconHeight))

          (* DSPFONT is a kludge to get around bug in PRESS BITBLT which sets the width of a space char to NIL.
	  Bug reported as AR %#5630.0)


				   (DSPFONT Font ImageStream))
		        (if (AND Icon (NOT (OR Label Title)))
			    then                           (* Quit because just a typeicon)
				   (RETURN))

          (* * Enter the appropriate text.)


		        (SETQ XPosition (PLUS Left (if Icon
							   then ScaledIconWidth
							 else ScaledBorderWidth)
						  ScaledSpaceInnerX))
		        (DSPXPOSITION XPosition ImageStream)
		        (SETQ FontDescent (FONTDESCENT Font))
		        (if LinkIconStrings
			    then (if (GREATERP (LENGTH LinkIconStrings)
						     1)
				       then (SETQ FontAscent (FONTASCENT Font))
					      (SETQ BottomOfLine (DIFFERENCE Top
										 (PLUS 
										ScaledBorderWidth 
										ScaledSpaceInnerY 
										       FontAscent)))
					      (SETQ XPosition (PLUS Left ScaledSpaceInnerX 
									ScaledBorderWidth))
					      (for String in LinkIconStrings
						 do (DSPYPOSITION BottomOfLine ImageStream)
						      (PRIN1 String ImageStream)
						      (SETQ BottomOfLine
							(DIFFERENCE BottomOfLine
								      (PLUS FontDescent 
									     ScaledSpaceInterLine 
									      FontAscent)))
						      (DSPXPOSITION XPosition ImageStream))

          (* * Draw the box.)


					      (NC.DrawInnerBox Left Bottom BoxWidth BoxHeight 
								 ScaledBorderWidth NIL ImageStream 
								 Icon ScaledIconWidth 
								 ScaledIconHeight)
				     else (DSPYPOSITION (PLUS Bottom ScaledBorderWidth 
								    ScaledSpaceInnerY FontDescent)
							    ImageStream)
					    (PRIN1 (CAR LinkIconStrings)
						     ImageStream)

          (* * Draw the box.)


					    (NC.DrawInnerBox (PLUS Left ScaledIconWidth)
							       Bottom
							       (DIFFERENCE BoxWidth ScaledIconWidth)
							       BoxHeight ScaledBorderWidth NIL 
							       ImageStream Icon)))))))

(NC.LinkIconImageBoxFn
  (LAMBDA (ImageObj ImageStream CurrentX RightMargin DummyArg DisplayType Title Label LinkIconString 
		    Icon LinkIconStrings)                    (* pmi: "13-Feb-87 12:18")

          (* * rht 9/20/84: Now scales result before returning by proper amount depending on stream type.
	  e.g. for PRESS and INTERPRESS.)



          (* * rht 11/13/84: In computation of XSIZE, extra width is figured using characters in the font, "nn", rather than 
	  absolute pixel count.)



          (* * rht 2/9/85: Now uses new displaymode format.)



          (* * rht 5/9/86: Note that RightMargin non-nil signals a TEdit stream.)



          (* * rht & fgh 5/9/86: Massive hacking to display coords, etc.)



          (* * rht 5/10/86: Rearranged order of expressions a bit and added arg to call to NC.FetchLinkIconAttachedBitMap in 
	  order to get a bitmap with correct height for the box we're drawing.)



          (* * rht 8/7/86: Now passes Scale argument to NC.FetchLinkIconAttachedBitMap. Also uses the Title and Label args if
	  non-nil. If not, then recomputes them more sensibly.)



          (* * rht 8/25/85: Fixed improperly placed comment.)



          (* * rg 11/18/86: Added TotalEdgeSpaceY to local vars declaration)



          (* * pmi 2/6/87: Overhauled to accommodate multi-line link icons)


    (DECLARE (GLOBALVARS NC.LinkIconMultiLineMode NC.LinkIconMaxWidth NC.LinkIconSpaceInnerX 
			     NC.LinkIconSpaceOuterX NC.LinkIconAttachBitmapFlg NC.LinkIconSpaceInnerY 
			     NC.LinkIconSpaceOuterY NC.LinkIconSpaceInterLine NC.LinkIconBorderWidth 
			     NC.LinkIconShowLinkTypeFlg NC.LinkIconShowTitleFlg))
    (RESETLST (RESETSAVE NIL (BQUOTE (DSPFONT , (DSPFONT NC.LinkIconFont ImageStream)
						      , ImageStream)))
		(LET ((Link (NC.FetchLinkFromLinkIcon ImageObj))
		      (Scale (DSPSCALE NIL ImageStream))
		      (StringWidth 0)
		      Card Font FontHeight ShowTitleFlg AttachBitmapFlg LinkDisplayMode 
		      ApproxBoxWidth ScaledIconHeight ScaledIconWidth NumberOfLines YSize 
		      ScaledBorderWidth ScaledSpaceInnerX ScaledSpaceOuterX ScaledSpaceInnerY 
		      ScaledSpaceOuterY ScaledSpaceInterLine HalfScaledSpaceInterLine TotalEdgeSpaceY)
		     (SETQ Font (DSPFONT NIL ImageStream))
		     (SETQ FontHeight (FONTHEIGHT Font))

          (* * Determine what type of Display to do)


		     (OR DisplayType (SETQ DisplayType (fetch (Link DisplayMode) of Link)))
		     (SETQ ShowTitleFlg (fetch (LINKDISPLAYMODE SHOWTITLEFLG) of DisplayType))
		     (SETQ Card (if (EQ ShowTitleFlg (QUOTE SOURCE))
				      then (fetch (Link SourceCard) of Link)
				    else (fetch (Link DestinationCard) of Link)))
		     (SETQ LinkDisplayMode (fetch (LINKDISPLAYMODE SHOWLINKTYPEFLG) of 
										      DisplayType))
		     (SETQ AttachBitmapFlg (fetch (LINKDISPLAYMODE ATTACHBITMAPFLG) of 
										      DisplayType))
		     (SETQ AttachBitmapFlg (if (EQ AttachBitmapFlg (QUOTE FLOAT))
						 then NC.LinkIconAttachBitmapFlg
					       else AttachBitmapFlg))

          (* * Construct the text for the link icon)


		     (if (NOT LinkIconString)
			 then (OR Title (SETQ Title (if (AND ShowTitleFlg
								       (OR (NEQ ShowTitleFlg
										    (QUOTE FLOAT))
									     NC.LinkIconShowTitleFlg))
							      then (NC.RetrieveTitle Card)
							    else NIL)))
				(OR Label (SETQ Label (AND (if (EQ LinkDisplayMode
									     (QUOTE FLOAT))
								     then 
								       NC.LinkIconShowLinkTypeFlg
								   else LinkDisplayMode)
								 (fetch (Link Label) of Link))))
				(SETQ LinkIconString (CONCAT (COND
								   (Label (CONCAT "<" Label ">"))
								   (T ""))
								 (COND
								   ((AND Label Title)
								     " ")
								   (T ""))
								 (OR Title ""))))

          (* * Make temporaries of scaled vars.)


		     (SETQ ScaledBorderWidth (TIMES Scale NC.LinkIconBorderWidth))
		     (SETQ ScaledSpaceInnerX (TIMES Scale NC.LinkIconSpaceInnerX))
		     (SETQ ScaledSpaceOuterX (TIMES Scale NC.LinkIconSpaceOuterX))
		     (SETQ ScaledSpaceInnerY (TIMES Scale NC.LinkIconSpaceInnerY))
		     (SETQ ScaledSpaceOuterY (TIMES Scale NC.LinkIconSpaceOuterY))
		     (SETQ ScaledSpaceInterLine (TIMES Scale NC.LinkIconSpaceInterLine))
		     (SETQ HalfScaledSpaceInterLine (IQUOTIENT ScaledSpaceInterLine 2))

          (* *)


		     (SETQ TotalEdgeSpaceY (PLUS ScaledBorderWidth ScaledSpaceOuterY 
						     ScaledSpaceInnerY))
		     (SETQ YSize (PLUS TotalEdgeSpaceY TotalEdgeSpaceY FontHeight))

          (* * Set up the icon, if displayed)


		     (if AttachBitmapFlg
			 then 

          (* * Attached icon)



          (* * Use an estimate of the width to tell if the box contains more than one line of text)


				(if NC.LinkIconMultiLineMode
				    then 

          (* * Multi-line link icons are enabled)


					   (SETQ ApproxBoxWidth (PLUS ScaledSpaceOuterX 
									  ScaledBorderWidth 
									  ScaledSpaceInnerX
									  (STRINGWIDTH 
										   LinkIconString 
											 Font)
									  ScaledSpaceInnerX 
									  ScaledBorderWidth 
									  ScaledSpaceOuterX))

          (* * The image box must be calculated)


					   (if (GREATERP ApproxBoxWidth NC.LinkIconMaxWidth)
					       then        (* Calculate Multi-line icon)
						      (SETQ ScaledIconHeight
							(PLUS ScaledBorderWidth ScaledSpaceInnerY 
								FontHeight HalfScaledSpaceInterLine))
						      (SETQ Icon (NC.FetchLinkIconAttachedBitMap
							  Card ScaledIconHeight Scale))
						      (SETQ ScaledIconHeight (TIMES Scale
											(
										     BITMAPHEIGHT
											  Icon)))
						      (SETQ ScaledIconWidth (TIMES Scale
										       (BITMAPWIDTH
											 Icon)))
					     else          (* Calculate Single line icon)
						    (SETQ ScaledIconHeight
						      (PLUS ScaledBorderWidth ScaledSpaceInnerY 
							      FontHeight ScaledSpaceInnerY 
							      ScaledBorderWidth))
						    (SETQ Icon (NC.FetchLinkIconAttachedBitMap
							Card ScaledIconHeight Scale))
						    (SETQ ScaledIconHeight (TIMES Scale
										      (BITMAPHEIGHT
											Icon)))
						    (SETQ ScaledIconWidth (TIMES Scale
										     (BITMAPWIDTH
										       Icon)))

          (* * Now see if total width, including the icon, will still fit if this is a Single line)


						    (if (GREATERP (PLUS ApproxBoxWidth 
									      ScaledIconWidth)
								      NC.LinkIconMaxWidth)
							then 
                                                             (* Now it doesn't fit. Calculate Multi-line icon)
							       (SETQ ScaledIconHeight
								 (PLUS ScaledBorderWidth 
									 ScaledSpaceInnerY FontHeight 
									 HalfScaledSpaceInterLine))
							       (SETQ Icon (
								   NC.FetchLinkIconAttachedBitMap
								   Card ScaledIconHeight Scale))
							       (SETQ ScaledIconHeight
								 (TIMES Scale (BITMAPHEIGHT
									    Icon)))
							       (SETQ ScaledIconWidth
								 (TIMES Scale (BITMAPWIDTH Icon)))
							  ))
				  else 

          (* * Multi-line link icons are disabled)


					 (SETQ ScaledIconHeight (PLUS ScaledBorderWidth 
									  ScaledSpaceInnerY 
									  FontHeight 
									  ScaledSpaceInnerY 
									  ScaledBorderWidth))
					 (SETQ Icon (NC.FetchLinkIconAttachedBitMap Card 
										 ScaledIconHeight 
											Scale))
					 (SETQ ScaledIconHeight (TIMES Scale (BITMAPHEIGHT
									     Icon)))
					 (SETQ ScaledIconWidth (TIMES Scale (BITMAPWIDTH Icon)))
				      )
		       else 

          (* * No attached icon)


			      (SETQ Icon NIL)
			      (SETQ ScaledIconHeight 0)
			      (SETQ ScaledIconWidth 0))

          (* * If the width of the icon is greater than the LinkIconMaxWidth set by the user, set the icon to NIL because we 
	  can't print it.)


		     (if (AND Icon (GREATERP ScaledIconWidth NC.LinkIconMaxWidth))
			 then (SETQ Icon NIL)
				(SETQ ScaledIconHeight 0)
				(SETQ ScaledIconWidth 0)
				(SETQ LinkIconStrings (LIST ""))
		       else 

          (* * Have the text parsed into separate lines)


			      (SETQ LinkIconStrings (NC.CreateLinkIconStrings Link LinkIconString 
										  Icon ImageStream)))
		     (if LinkIconStrings
			 then (SETQ NumberOfLines (LENGTH LinkIconStrings))
				(if (GREATERP NumberOfLines 1)
				    then (SETQ StringWidth (PLUS (STRINGWIDTH (CAR 
										  LinkIconStrings)
										      Font)
								       ScaledIconWidth))

          (* * Find the longest string for the width of the box)


					   (for String in (CDR LinkIconStrings) bind 
										  PartStringWidth
					      when (GREATERP (SETQ PartStringWidth
								   (STRINGWIDTH String Font))
								 StringWidth)
					      do (SETQ StringWidth PartStringWidth))
					   (SETQ YSize (PLUS TotalEdgeSpaceY TotalEdgeSpaceY
								 (TIMES NumberOfLines FontHeight)
								 (TIMES (SUB1 NumberOfLines)
									  ScaledSpaceInterLine)))
				  else (SETQ StringWidth (PLUS (STRINGWIDTH (CAR 
										  LinkIconStrings)
										    Font)
								     ScaledIconWidth))))
		     (create IMAGEBOX
			       XSIZE ←(MIN (PLUS StringWidth ScaledSpaceOuterX ScaledSpaceOuterX 
						     ScaledSpaceInnerX ScaledSpaceInnerX
						     (if Icon
							 then ScaledBorderWidth
						       else (PLUS ScaledBorderWidth 
								      ScaledBorderWidth)))
					     (PLUS (TIMES Scale NC.LinkIconMaxWidth)
						     ScaledSpaceOuterX ScaledSpaceOuterX))
			       YSIZE ← YSize
			       YDESC ←(COND
				 (RightMargin                (* This is in a TEdittextstream)
					      (PLUS (FONTDESCENT Font)
						      TotalEdgeSpaceY))
				 (T 0))
			       XKERN ← 0)))))
)
(* * New NCLINKS function)

(DEFINEQ

(NC.CreateLinkIconStrings
  (LAMBDA (Link LinkIconString Icon ImageStream)             (* pmi: "13-Feb-87 12:18")

          (* * pmi 2/9/87: First written to parse the text for a link icon into multiple lines)


    (DECLARE (GLOBALVARS NC.LinkIconMaxWidth NC.LinkIconMultiLineMode NC.LinkIconBorderWidth 
			     NC.LinkIconSpaceInnerX))
    (PROG ((Scale (DSPSCALE NIL ImageStream))
	     (LinkIconLines NIL)
	     (ThisString "")
	     RemainingLineWidth Font ScaledBorderWidth ScaledSpaceInnerX TotalEdgeSpaceX LineWidth 
	     StringLength CharsPtr NumberOfLines StringList String StringWidth Char CharWidth 
	     CurrentWidth EndPtr)
	    (SETQ Font (DSPFONT NIL ImageStream))

          (* * Make temporaries of scaled vars.)


	    (SETQ ScaledBorderWidth (TIMES Scale NC.LinkIconBorderWidth))
	    (SETQ ScaledSpaceInnerX (TIMES Scale NC.LinkIconSpaceInnerX))
	    (SETQ TotalEdgeSpaceX (PLUS ScaledBorderWidth ScaledBorderWidth ScaledSpaceInnerX 
					    ScaledSpaceInnerX))

          (* * Width of text in link icon)


	    (SETQ LineWidth (DIFFERENCE (TIMES Scale NC.LinkIconMaxWidth)
					    TotalEdgeSpaceX))

          (* * If there isn't even enough room for the bitmap, give up.)


	    (if Icon
		then (SETQ RemainingLineWidth (PLUS (DIFFERENCE LineWidth
									(TIMES Scale (BITMAPWIDTH
										   Icon)))
							  ScaledBorderWidth))
	      else (SETQ RemainingLineWidth LineWidth))

          (* * Turn the text into a string list of words and spaces)


	    (if NC.LinkIconMultiLineMode
		then 

          (* * Calculate multiple lines of text)


		       (SETQ StringList (NC.ParseString LinkIconString))
		       (SETQ String (CAR StringList))
		       (SETQ NumberOfLines 0) 

          (* * Determine the line breaks)


		       (while StringList
			  do (if (AND (STREQUAL (SUBSTRING String 1 1)
							(QUOTE " "))
					    (STREQUAL ThisString ""))
				   then 

          (* * The "word" is a space or spaces and we are at the beginning of the line. In this case we want to throw away 
	  the spaces.)


					  (SETQ StringList (CDR StringList))
					  (if StringList
					      then (SETQ String (CAR StringList)))
				 else (SETQ StringWidth (STRINGWIDTH String Font))
					(if (LESSP StringWidth RemainingLineWidth)
					    then 

          (* * The word or spaces will fit on the remainder of the line)


						   (SETQ ThisString (CONCAT ThisString String))
						   (SETQ RemainingLineWidth (DIFFERENCE 
									       RemainingLineWidth 
										      StringWidth))
						   (SETQ StringList (CDR StringList))
						   (if StringList
						       then (SETQ String (CAR StringList))
						     else (SETQ LinkIconLines (NCONC1 
										    LinkIconLines 
										       ThisString)))
					  elseif (EQ StringWidth RemainingLineWidth)
					    then 

          (* * The word or spaces will exactly fit on the remainder of the line)


						   (SETQ ThisString (CONCAT ThisString String))
						   (SETQ LinkIconLines (NCONC1 LinkIconLines 
										   ThisString))
						   (SETQ ThisString "")
						   (SETQ RemainingLineWidth LineWidth)
						   (SETQ NumberOfLines (ADD1 NumberOfLines))
						   (SETQ StringList (CDR StringList))
						   (if StringList
						       then (SETQ String (CAR StringList)))
					  elseif (STREQUAL ThisString "")
					    then 

          (* * We have a word that is too long for the line, and we are at the beginning of the line)


						   (SETQ CurrentWidth 0)
						   (SETQ EndPtr (for I from 1
								     to (NCHARS String)
								     do (SETQ Char
									    (SUBSTRING String I I))
									  (SETQ CurrentWidth
									    (PLUS CurrentWidth
										    (STRINGWIDTH
										      Char Font)))
									  (if (GREATERP 
										     CurrentWidth 
									       RemainingLineWidth)
									      then
									       (RETURN
										 (SUB1 I)))))
						   (if (EQ EndPtr 0)
						       then 

          (* * This character won't fit on this line, so give up)


							      (OR LinkIconLines (SETQ 
								      LinkIconLines (LIST "")))
							      (RETURN)
						     else (SETQ ThisString
							      (CONCAT ThisString
									(SUBSTRING String 1 EndPtr))
							      ))
						   (SETQ LinkIconLines (NCONC1 LinkIconLines 
										   ThisString))
						   (SETQ String (SUBSTRING String (ADD1 EndPtr))
						     )
						   (SETQ ThisString "")
						   (SETQ RemainingLineWidth LineWidth)
						   (SETQ NumberOfLines (ADD1 NumberOfLines))
					  elseif (STREQUAL (SUBSTRING String 1 1)
							       (QUOTE " "))
					    then 

          (* * We have spaces at the end of the line which can be thrown away)


						   (SETQ LinkIconLines (NCONC1 LinkIconLines 
										   ThisString))
						   (SETQ ThisString "")
						   (SETQ RemainingLineWidth LineWidth)
						   (SETQ NumberOfLines (ADD1 NumberOfLines))
						   (SETQ StringList (CDR StringList))
						   (if StringList
						       then (SETQ String (CAR StringList)))
					  else 

          (* * We have a word that won't fit on the remainder of the line, so we must start it on the next line)


						 (SETQ LinkIconLines (NCONC1 LinkIconLines 
										 ThisString))
						 (SETQ ThisString "")
						 (SETQ RemainingLineWidth LineWidth)
						 (SETQ NumberOfLines (ADD1 NumberOfLines)))))
	      elseif (LESSP (STRINGWIDTH LinkIconString Font)
				RemainingLineWidth)
		then 

          (* * Calculate single line of text. The string will fit as is)


		       (SETQ LinkIconLines (LIST LinkIconString))
	      else 

          (* * Calculate single line of text. We have to chop the string down to fit in one line)


		     (SETQ StringLength (NCHARS LinkIconString))
		     (SETQ CharsPtr 1)
		     (SETQ LinkIconLines (LIST (while (ILEQ CharsPtr StringLength)
						      do (if (LESSP (SETQ CharWidth
									    (STRINGWIDTH
									      (NTHCHAR 
										   LinkIconString 
											 CharsPtr)
									      Font))
									  RemainingLineWidth)
							       then (SETQ RemainingLineWidth
									(DIFFERENCE 
									       RemainingLineWidth 
										      CharWidth))
								      (SETQ CharsPtr (ADD1 
											 CharsPtr))
							     elseif (EQ CharsPtr 1)
							       then (RETURN "")
							     else (RETURN (SUBSTRING
										LinkIconString 1
										(SUB1 CharsPtr))))
						      finally (RETURN (SUBSTRING LinkIconString 
										       1
										       (SUB1 
											 CharsPtr)))))
		       ))
	    (RETURN LinkIconLines))))
)
(* * New NCPARAMETERS Globalvars)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.LinkIconMultiLineMode NC.LinkIconMaxWidth)
)
(* * New NCPARAMETERS Initvars)


(RPAQ? NC.LinkIconMultiLineMode NIL)

(RPAQ? NC.LinkIconMaxWidth SCREENWIDTH)
(* * Additions to NCPARAMETERS props)


(PUTPROPS NC.NoteCardsParameters LinkIconMultiLineMode NC.LinkIconMultiLineMode)

(PUTPROPS NC.NoteCardsParameters LinkIconMaxWidthInPixels (NC.LinkIconMaxWidth EVAL 
									   NC.SetLinkIconMaxWidth NIL)
)

(PUTPROPS NC.NoteCardsParameters LinkIconBorderWidth (NC.LinkIconBorderWidth EVAL 
									NC.SetLinkIconBorderWidth NIL)
)
(* * New NCPARAMETERS functions)

(DEFINEQ

(NC.SetLinkIconMaxWidth
  (LAMBDA NIL                                                (* pmi: "13-Feb-87 14:33")
    (DECLARE (GLOBALVARS NC.LinkIconMaxWidth))
    (LET ((MaxScreenSpace (DIFFERENCE SCREENWIDTH 18))
	  NewLinkIconMaxWidth InspectWindow)
         (SETQ NewLinkIconMaxWidth (OR (RNUMBER "Maximum Width of Link Icons (in Pixels)" NIL 
						      NIL NIL T NIL)
					   NC.LinkIconMaxWidth))
         (if (GREATERP NewLinkIconMaxWidth MaxScreenSpace)
	     then (NC.PrintMsg (if (SETQ InspectWindow (for Window in (OPENWINDOWS)
								  when (WINDOWPROP Window
										       (QUOTE
											 
									       NoteCardsInspector))
								  do (RETURN Window)))
				       then (GETPROMPTWINDOW InspectWindow 1)
				     else NIL)
				   T "You are limited to screen width of " MaxScreenSpace)
		    MaxScreenSpace
	   else NewLinkIconMaxWidth))))

(NC.SetLinkIconBorderWidth
  (LAMBDA NIL                                                (* pmi: "13-Feb-87 14:33")
    (DECLARE (GLOBALVARS NC.LinkIconBorderWidth))
    (LET ((MaxBorderWidth 20)
	  NewLinkIconBorderWidth InspectWindow)
         (SETQ NewLinkIconBorderWidth (OR (RNUMBER "Width of Link Icon Borders (in Pixels)" NIL 
							 NIL NIL T NIL)
					      NC.LinkIconBorderWidth))
         (if (GREATERP NewLinkIconBorderWidth MaxBorderWidth)
	     then (NC.PrintMsg (if (SETQ InspectWindow (for Window in (OPENWINDOWS)
								  when (WINDOWPROP Window
										       (QUOTE
											 
									       NoteCardsInspector))
								  do (RETURN Window)))
				       then (GETPROMPTWINDOW InspectWindow 1)
				     else NIL)
				   T "You are limited to a maximum border width of " MaxBorderWidth)
		    MaxBorderWidth
	   else NewLinkIconBorderWidth))))
)
(* * Changes to NCUTILITIES functions)

(DEFINEQ

(NC.DrawInnerBox
  (LAMBDA (Left Bottom Width Height LineWidth Operation ImageStream SkipLeftEdgeFlg ScaledIconWidth 
		ScaledIconHeight)                            (* pmi: "13-Feb-87 12:48")

          (* * Draw a box that fits exactly inside the region given. Omit the left edge if SkipLeftEdgeFlg non-nil.)



          (* * pmi & rht 2/10/87: Changed to not overwrite corners of the box.)



          (* * pmi 2/11/87: Updated for Multi-line link icons. If multi-line, does not draw box edge in upper left corner 
	  where bitmap is placed.)


    (if (AND (GREATERP Width 0)
		 (GREATERP Height 0))
	then (LET ((TrueWidth (SUB1 Width))
		     (TrueHeight (SUB1 Height))
		     (HalfBorderWidth (FIX (TIMES LineWidth .5)))
		     (Offset (if (EVENP LineWidth)
				 then -1
			       else 0))
		     Right Top)
		    (SETQ Right (PLUS Left TrueWidth))
		    (SETQ Top (PLUS Bottom TrueHeight))
		    (LET ((CenterLeft (PLUS Left HalfBorderWidth Offset))
			  (CenterBottom (PLUS Bottom HalfBorderWidth))
			  (CenterRight (DIFFERENCE Right HalfBorderWidth))
			  (CenterTop (DIFFERENCE Top HalfBorderWidth))
			  (InnerBottom (PLUS Bottom LineWidth))
			  (InnerRight (DIFFERENCE Right LineWidth))
			  (InnerTop (DIFFERENCE Top LineWidth)))
		         (if (EVENP LineWidth)
			     then (SETQ CenterBottom (SUB1 CenterBottom)))
		         (if SkipLeftEdgeFlg
			     then (if ScaledIconWidth
					then (DRAWLINE Left CenterBottom Right CenterBottom 
							   LineWidth Operation ImageStream)
					       (DRAWLINE CenterRight InnerBottom CenterRight Top 
							   LineWidth Operation ImageStream)
					       (DRAWLINE InnerRight CenterTop (PLUS Left 
										  ScaledIconWidth)
							   CenterTop LineWidth Operation ImageStream)
					       (DRAWLINE CenterLeft (DIFFERENCE Top 
										 ScaledIconHeight)
							   CenterLeft InnerBottom LineWidth Operation 
							   ImageStream)
				      else (DRAWLINE Left CenterBottom Right CenterBottom 
							 LineWidth Operation ImageStream)
					     (DRAWLINE CenterRight InnerBottom CenterRight Top 
							 LineWidth Operation ImageStream)
					     (DRAWLINE InnerRight CenterTop Left CenterTop 
							 LineWidth Operation ImageStream))
			   else (DRAWLINE Left CenterBottom Right CenterBottom LineWidth 
					      Operation ImageStream)
				  (DRAWLINE CenterRight InnerBottom CenterRight Top LineWidth 
					      Operation ImageStream)
				  (DRAWLINE InnerRight CenterTop Left CenterTop LineWidth Operation 
					      ImageStream)
				  (DRAWLINE CenterLeft InnerTop CenterLeft InnerBottom LineWidth 
					      Operation ImageStream)))))))
)
(* * New NCUTILITIES function)

(DEFINEQ

(NC.ParseString
  (LAMBDA (String)                                           (* pmi: " 6-Feb-87 10:47")

          (* * Parses a sting into words and "white space." Example: String = "This   is a  test   " would result in 
	  ("This" "   " "is" "  " "test" "    "))


    (COND
      ((STRINGP String)
	(PROG (StringLength SpacesPtr CharsPtr SubString StringList)
	        (SETQ StringLength (NCHARS String))
	        (SETQ SpacesPtr 1)
	        (SETQ CharsPtr 1)
	        (while (ILEQ SpacesPtr StringLength)
		   do 

          (* * Gather up adjacent spaces)


			(while (AND (EQ (NTHCHAR String SpacesPtr)
					      (QUOTE % ))
					(ILEQ SpacesPtr StringLength))
			   do (SETQ SpacesPtr (ADD1 SpacesPtr)))
			(if (SETQ SubString (SUBSTRING String CharsPtr (SUB1 SpacesPtr)))
			    then (SETQ StringList (CONS SubString StringList)))
			(SETQ CharsPtr SpacesPtr) 

          (* * Gather up adjacent characters)


			(while (AND (NEQ (NTHCHAR String CharsPtr)
					       (QUOTE % ))
					(ILEQ CharsPtr StringLength))
			   do (SETQ CharsPtr (ADD1 CharsPtr)))
			(if (SETQ SubString (SUBSTRING String SpacesPtr (SUB1 CharsPtr)))
			    then (SETQ StringList (CONS SubString StringList)))
			(SETQ SpacesPtr CharsPtr))
	        (RETURN (REVERSE StringList))))
      (T String))))
)
(* * Only for the patch file. Do not integrate into the sources.)


(RPAQ NC.NoteCardsParameters (PROPNAMES (QUOTE NC.NoteCardsParameters)))

(RPAQQ NC.LinkIconSpaceInnerX 3)
(PUTPROPS PMIPATCH015 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3512 28132 (NC.LinkIconDisplayFn 3522 . 17560) (NC.LinkIconImageBoxFn 17562 . 28130)) (
28166 35461 (NC.CreateLinkIconStrings 28176 . 35459)) (36153 38103 (NC.SetLinkIconMaxWidth 36163 . 
37131) (NC.SetLinkIconBorderWidth 37133 . 38101)) (38149 40989 (NC.DrawInnerBox 38159 . 40987)) (41027
 42532 (NC.ParseString 41037 . 42530)))))
STOP