Important: The information in this document is obsolete and should not be used for new development.
Using Line-Drawing Picture Comments
Line-drawing picture comments, listed in Table B-1 on page B-8, provide your application with the ability to draw dashed lines (as described in the next section) and to display fractional line widths (as described in "Using Fractional Line Widths" on page B-36).Drawing Dashed Lines
Your application may use dashed lines frequently, particularly if it is a spreadsheet or accounting application. You can use theDashedLine
picture comment to draw dashed lines on capable printers without drawing each individual dash. You use theDashedStop
picture comment to tell the printer driver when you are finished sending dashed line information.When you use the
DashedLine
comment, the printer driver draws the indicated lines or rectangles. You should pass a handle to aTDashedLineRec
record in thedataHandle
parameter of thePicComment
procedure. You use aTDashedLineRec
record to specify how the dashed line should look. Here is how you should declare these as Pascal data structures:
TYPE TDashedLineHdl = ^TDashedLinePtr; TDashedLinePtr = ^TDashedLineRec; TDashedLineRec = PACKED RECORD offset: SignedByte; {offset} centered: SignedByte; {reserved; set to 0} intervals: ARRAY[0..0] OF SignedByte; {points for drawing and not } { drawing dashes} END;Use theoffset
field to specify an offset as with the PostScriptsetdash
operator.The
centered
field is reserved and should be set to 0. Your application must center the dashed lines.In the
intervals
field, specify an array of dash intervals describing the number of points drawn for a dash and the number of points not drawn between them.You must provide both a QuickDraw and a picture comment version of the dashed line. The code in Listing B-9 uses the
PostScriptBegin
andPostScriptEnd
picture comments to hide QuickDraw code from PostScript, and it uses pattern mode 23 to render PostScript drawing invisible in QuickDraw.Listing B-9 Using the
DashedLine
picture comment
PROCEDURE DashDemo; CONST magicPen = 23; cx = 280; {center along x-axis} cy = 280; {center along y-axis} r0 = 200; {radius} VAR dashHdl: TDashedLineHdl; i: Integer; a, rad: Extended; BEGIN PenSize(2,2); {First the PostScript picture comment version. Pattern mode } { 23 makes the line drawing invisible to QuickDraw.} PenMode(magicPen); dashHdl := TDashedLineHdl(NewHandle(SizeOf(TDashedLineRec))); IF dashHdl <> NIL THEN WITH dashHdl^^ DO BEGIN offset := 4; {just for fun} centered := 0; {currently ignored--set to 0} intervals[0] := 2; {number of interval specs} intervals[1] := 4; {this means 4 points on ...} intervals[2] := 6; {... and 6 points off} PicComment(DashedLine, SizeOf(TDashedLineRec), Handle(dashHdl)); END; rad := 3.14159 / 180; {conversion degrees -> radians} FOR i := 0 TO 9 DO BEGIN {draw some dashed lines} a := i * 20 * rad; MoveTo(cx, cy); Line(round(r0 * cos(a)), - round(r0 * sin(a))); END; PicComment(DashedStop, 0, NIL); {that's enough!} DisposeHandle(Handle(dashHdl)); PenMode(srcOr); {no magic any more} {Now, the QuickDraw version. The PostScript driver must } { ignore it, so enclose it between PostScriptBegin and } { PostScriptEnd comments.} PicComment(PostScriptBegin, 0, NIL); PenSize(2,2); FOR i := 0 TO 9 DO BEGIN MoveTo(cx,cy); MyDashedQDLine(round(r0 * cos(i * 20 * rad)), - round(r0 * sin(i * 20 * rad)), dashHdl); END; PicComment(PostScriptEnd, 0, NIL); END;Using Fractional Line Widths
Your application may need lines as thin as possible or thinner than the screen can display, especially if it is a desktop publishing, spreadsheet, or design application. You can draw hairlines (lines that are less than 1/72 of an inch wide) with printer drivers that support theSetLineWidth
picture comment. Your application passes the printer driver a scaling factor (such as 1/4) that the driver applies to the pen size when rendering the picture.QuickDraw and the PostScript language define 1 point to be 1/72 of an inch, so there are exactly 72 points per inch on the Macintosh screen. The resolution of a PostScript device such as the 300-dpi LaserWriter printer is about four times that of the screen, so the driver can render lines that are approximately 1/4 of a point thick, which is about 1/288 of an inch.
When you specify the
SetLineWidth
picture comment in thekind
parameter of thePicComment
procedure, you also specify aTLineWidthHdl
handle (a handle to a data structure of typeTLineWidth
) in thedataHandle
parameter. TheTLineWidth
data structure is defined by thePoint
data type. Here is how you should declare these as Pascal data types in your application:
TLineWidthHdl = ^TLineWidthPtr; TLineWidthPtr = ^TLineWidth; TLineWidth = Point; {v = numerator, h = denominator}Use the vertical coordinate of the point as the numerator and the horizontal coordinate as the denominator of the scaling factor: the driver multiplies the horizontal and vertical components of the pen by the scaling factor to obtain the new pen width. For example, if you have a pen size of (1,2) and yourSetLineWidth
picture comment uses 2 for the horizontal and 7 for the vertical, the pen size will then be (7/2) 1 pixel wide and
(7/2) 2 pixels high.In Figure B-9, the original pen size is 1 point. The first scaling factor is 5.0 or (5,1), which gives the pen a width of 5 points. The second scaling factor, applied to the new pen width, is 0.2 or (1,5), which gives the pen a width of 1 point again.
Figure B-9 Changing the pen width using the
SetLineWidth
picture comment
TheSetLineWidth
picture comment is implemented by all PostScript LaserWriter printer drivers and by some QuickDraw printer drivers. However, not all QuickDraw printer drivers supportSetLineWidth
, and there is no backup solution for cases where it is not supported. Among QuickDraw printer drivers that do supportSetLineWidth
, some drivers emulate PostScript printer drivers, while others--such as the QuickDraw LaserWriter SC driver--implementSetLineWidth
differently.The difference between the implementations of the
SetLineWidth
comment by the PostScript LaserWriter driver and the QuickDraw LaserWriter SC driver is apparent as soon asSetLineWidth
is used a second time. The PostScript driver keeps an internal line-scaling factor, which is initialized to 1.0 when a job is started. Each number passed throughSetLineWidth
is multiplied by the current internal scaling factor to get the effective scaling factor for the pen size. The LaserWriter SC driver, on the other hand, replaces its current scaling factor for the pen size by the new value passed throughSetLineWidth
.To support both implementations, you must always use an additional
SetLineWidth
picture comment to reset the PostScript driver line width to 1.0 before scaling to a new value width, as illustrated by the following lines of code:
PicComment(SetLineWidth, SizeOf(TLineWidth), Handle(1/oldLineWidth)); PicComment(SetLineWidth, SizeOf(TLineWidth), Handle(newLineWidth));For example, suppose your application set the line width to 0.25, and now it needs a line width of 0.5. The following twoSetLineWidth
comments have the desired effect on all PostScript and QuickDraw drivers that implement theSetLineWidth
comment.
Current line width,
PS driverCurrent line width,
QD driverValue passed along with SetLineWidth
New line width,
PS driverNew line width,
QD driver0.25 0.25 4/1 1.0 4.0 1.0 4.0 1/2 0.5 0.5 The sample code in Listing B-10 gives the expected results on PostScript LaserWriter and QuickDraw printer drivers that implement the
SetLineWidth
comment.Listing B-10 Using the
SetLineWidth
picture comment
PROCEDURE MySetNewLineWidth(oldWidth,newWidth: TLineWidth); VAR tempWidthH: TLineWidthHdl; BEGIN tempWidthH := TLineWidthHdl(NewHandle(SizeOf(TLineWidth))); tempWidthH^^.v := oldWidth.h; tempWidthH^^.h := oldWidth.v; PicComment(SetLineWidth, SizeOf(TLineWidth), Handle(tempWidthH)); tempWidthH^^ := newWidth; PicComment(SetLineWidth, SizeOf(TLineWidth), Handle(tempWidthH)); DisposeHandle(Handle(tempWidthH)); END; PROCEDURE MyLineWidthDemo; CONST y0 = 50; {top left of demo} x0 = 50; d0 = 440; {length of horizontal lines} e0 = 5; {distance between lines} kN = 5; {number of lines} VAR oldWidth,newWidth: TLineWidth; i,j,y: Integer; BEGIN PenNormal; y := y0; SetPt(oldWidth,1,1); {initial line width = 1.0} FOR i := 1 TO 5 DO BEGIN SetPt(newWidth,4,i); {want to set it to i/4 = 0.25, 0.50, 0.75 ...} SetNewLineWidth(oldWidth,newWidth); MoveTo(x0, y); Line(d0, 0); y := y + e0; oldWidth := newWidth; END; END;