5 * Hooks for adding tab support to WASTE
8 * Mark Alldritt (original code)
9 * Dan Crevier (line breaks)
10 * John Daub (maintenance)
11 * Jonathan Kew (variable-width tabs)
12 * Marco Piovanelli (?)
13 * Bert Seltzer (horizontal scrolling)
18 #include "WETabHooks.h"
20 #define FIXROUND(f) ((SInt16) (((f) + 0x00008000) >> 16))
21 #define BSL(A, B) (((SInt32) (A)) << (B))
23 static const Point kOneToOneScaling
= { 1, 1 } ;
25 pascal void _WETabDrawText
30 JustStyleCode styleRunPosition
,
34 #pragma unused ( slop, styleRunPosition )
42 SInt16 tabSize
= WEGetTabSize(we
);
44 WEGetDestRect(&destRect
, we
);
45 destLeft
= (SInt16
) destRect
.left
;
47 for ( ii
= 0; ii
< textLength
; ii
++ )
49 if (pText
[ii
] == '\t')
51 DrawText(pText
, beginChar
, ii
- beginChar
);
53 /* advance the pen to the next tab stop */
55 tabWidth
= tabSize
- (penPos
.h
- destLeft
) % tabSize
;
56 MoveTo(penPos
.h
+ tabWidth
, penPos
.v
);
61 DrawText(pText
, beginChar
, textLength
- beginChar
);
64 pascal SInt32 _WETabPixelToChar
71 JustStyleCode styleRunPosition
,
81 SInt16 tabSize
= WEGetTabSize(we
);
83 /* loop through every character in the segment looking for tabs */
84 for ( ii
= 0; ii
< textLength
; ii
++ )
86 /* exit now if width has gone negative */
87 /* (i.e., if we have found which glyph was hit) */
94 if (pText
[ii
] == '\t')
96 /* calculate the width of the sub-segment preceding the tab */
98 offset
+= PixelToChar((char *)pText
+ beginChar
, ii
- beginChar
, slop
,
99 lastWidth
, (Boolean
*) edge
, width
, styleRunPosition
,
100 kOneToOneScaling
, kOneToOneScaling
);
103 /* hit point past sub-segment? */
106 /* increment hPos by width of sub-segment preceding the tab */
107 hPos
+= (lastWidth
- *width
);
109 /* calculate the width of the tab "glyph" (as a Fixed value) */
110 tabWidth
= BSL(tabSize
- FIXROUND(hPos
) % tabSize
, 16);
112 /* increment hPos by width of tab character */
115 /* hit point within tab glyph? */
116 if (*width
< tabWidth
)
118 /* yes: determine which half of tab glyph was hit */
119 if (*width
> (tabWidth
>> 1))
121 *edge
= kTrailingEdge
; /* second (trailing) edge of tab */
126 *edge
= kLeadingEdge
; /* first (leading) edge of tab */
129 /* returning -1 (as Fixed) in width means we're finished */
134 /* hit point is past tab: keep looping */
138 } /* if (*width >= 0) */
142 /* no more tabs in this segment: process the last sub-segment */
146 offset
+= PixelToChar((char *)pText
+ beginChar
, textLength
- beginChar
, slop
,
147 lastWidth
, (Boolean
*) edge
, width
, styleRunPosition
,
148 kOneToOneScaling
, kOneToOneScaling
);
151 /* round width to nearest integer value */
152 /* this is supposed to fix an incompatibility with the WorldScript Power Adapter */
153 *width
= (*width
+ 0x00008000) & 0xFFFF0000;
158 pascal SInt16 _WETabCharToPixel
165 JustStyleCode styleRunPosition
,
171 SInt32 beginChar
= 0;
175 SInt16 totalWidth
= 0;
176 SInt16 tabSize
= WEGetTabSize(we
);
178 WEGetDestRect(&destRect
, we
);
179 destLeft
= (SInt16
) destRect
.left
;
181 /* measure text up to offset, if offset is within this segment,
182 otherwise to textLength */
183 if (offset
> textLength
)
188 for ( ii
= 0; ii
< offset
; ii
++ )
190 if (pText
[ii
] == '\t')
192 /* calculate the pixel width of the subsegment preceding the tab */
193 width
= TextWidth(pText
, beginChar
, ii
- beginChar
);
197 /* calculate tab width */
198 width
= tabSize
- (hPos
- destLeft
) % tabSize
;
202 /* go to next subsegment */
207 /* calculate width of remaining characters */
208 width
= CharToPixel((char *)pText
+ beginChar
, textLength
- beginChar
, slop
,
209 offset
- beginChar
, direction
, styleRunPosition
,
210 kOneToOneScaling
, kOneToOneScaling
);
216 pascal StyledLineBreakCode _WETabLineBreak
228 SInt32 beginChar
= textStart
;
232 StyledLineBreakCode breakCode
= smBreakOverflow
;
233 SInt16 tabSize
= WEGetTabSize(we
);
235 WEGetDestRect(&destRect
, we
);
236 destWidth
= (SInt16
) (destRect
.right
- destRect
.left
);
238 for ( ii
= textStart
; ii
< textEnd
; ii
++ )
240 if (pText
[ii
] == 0x0D)
242 /* found a <return>, so stop looking ahead for tabs */
246 if (pText
[ii
] == '\t')
248 /* do previous "segment" */
249 breakCode
= StyledLineBreak((char *)pText
, textLength
, beginChar
, ii
, 0, textWidth
, textOffset
);
250 if ((breakCode
!= smBreakOverflow
) || (ii
>= textLength
))
256 /* calculate tab width (as a Fixed value) */
257 tabWidth
= BSL(tabSize
- (destWidth
- FIXROUND(*textWidth
)) % tabSize
, 16);
259 /* if tabWidth > pixelWidth we break in tab */
260 /* don't move tab to next line */
261 if (tabWidth
> *textWidth
)
263 breakCode
= smBreakWord
;
264 *textOffset
= ii
+ 1;
269 *textWidth
-= tabWidth
;
274 /* do last sub-segment */
275 if ((ii
- beginChar
>= 0) && (breakCode
== smBreakOverflow
))
277 breakCode
= StyledLineBreak((char *)pText
, textLength
, beginChar
, ii
, 0, textWidth
, textOffset
);