1 /* propfont.c - editor text drawing for proportional fonts.
2 Copyright (C) 1997 Paul Sheer
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 #if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK)
26 /* this file definatively relies on int being 32 bits or more */
28 int option_long_whitespace
= 0;
30 #define MAX_LINE_LEN 1024
31 #define CACHE_WIDTH 256
32 #define CACHE_HEIGHT 128
37 cache_type data
[CACHE_WIDTH
];
41 /* background colors: marked is refers to mouse highlighting, highlighted refers to a found string. */
42 extern unsigned long edit_abnormal_color
, edit_marked_abnormal_color
;
43 extern unsigned long edit_highlighted_color
, edit_marked_color
;
44 extern unsigned long edit_normal_background_color
;
46 /* foreground colors */
47 extern unsigned long edit_normal_foreground_color
, edit_bold_color
;
48 extern unsigned long edit_italic_color
;
51 extern unsigned long edit_cursor_color
;
53 extern int EditExposeRedraw
;
60 cache_type s
, unsigned long *fg
, unsigned long *bg
)
62 int fgp
, bgp
, underlined
= 0;
63 fgp
= (s
& 0xFF000000UL
) >> 24;
64 /* NO_COLOR would give fgp == 255 */
66 *fg
= color_palette (fgp
);
68 *fg
= edit_normal_foreground_color
;
69 bgp
= (s
& 0x00FF0000) >> 16;
73 *bg
= color_palette (bgp
);
75 *bg
= edit_normal_background_color
;
76 if (!(s
& 0xFFFFFF00UL
)) /* check this first as an optimization */
78 if (s
& (MOD_ABNORMAL
* 256)) {
79 *bg
= edit_abnormal_color
;
80 if (s
& (MOD_MARKED
* 256))
81 *bg
= edit_marked_abnormal_color
;
82 } else if (s
& (MOD_HIGHLIGHTED
* 256)) {
83 *bg
= edit_highlighted_color
;
84 } else if (s
& (MOD_MARKED
* 256)) {
85 *bg
= edit_marked_color
;
87 if (s
& (MOD_BOLD
* 256))
88 *fg
= edit_bold_color
;
89 if (s
& (MOD_ITALIC
* 256))
90 *fg
= edit_italic_color
;
91 if (s
& (MOD_INVERSE
* 256)) {
96 if (*bg
== COLOR_BLACK
)
97 *bg
= color_palette (1);
103 #define set_style_color(s,f,b) set_style_color(win,s,f,b)
108 static inline int next_tab_pos (int x
)
110 return x
+= tab_width
- x
% tab_width
;
113 /* this now properly uses ctypes */
114 static inline int convert_to_long_printable (int c
, unsigned char *t
)
119 return FONT_PER_CHAR
[c
];
122 if (option_long_whitespace
) {
126 return FONT_PER_CHAR
[' '] + FONT_PER_CHAR
[' '];
130 return FONT_PER_CHAR
[' '];
133 if (option_international_characters
&& FONT_PER_CHAR
[c
]) {
136 return FONT_PER_CHAR
[c
];
139 t
[0] = ("0123456789ABCDEF")[c
>> 4];
140 t
[1] = ("0123456789ABCDEF")[c
& 0xF];
143 return FONT_PER_CHAR
[t
[0]] + FONT_PER_CHAR
[t
[1]] + FONT_PER_CHAR
[t
[2]];
148 return FONT_PER_CHAR
[t
[0]] + FONT_PER_CHAR
[t
[1]];
151 /* same as above but just gets the length */
152 static inline int width_of_long_printable (int c
)
155 return FONT_PER_CHAR
[c
];
157 if (option_long_whitespace
)
158 return FONT_PER_CHAR
[' '] + FONT_PER_CHAR
[' '];
160 return FONT_PER_CHAR
[' '];
162 if (option_international_characters
&& FONT_PER_CHAR
[c
])
163 return FONT_PER_CHAR
[c
];
165 return FONT_PER_CHAR
[(unsigned char) ("0123456789ABCDEF")[c
>> 4]] + FONT_PER_CHAR
[(unsigned char) ("0123456789ABCDEF")[c
& 0xF]] + FONT_PER_CHAR
[(unsigned char) 'h'];
166 return FONT_PER_CHAR
['^'] + FONT_PER_CHAR
[c
+ '@'];
169 int edit_width_of_long_printable (int c
)
171 return width_of_long_printable (c
);
174 /* returns x pixel pos of char at offset *q with x not more than l */
175 static int calc_text_pos (WEdit
* edit
, long b
, long *q
, int l
)
179 c
= edit_get_byte (edit
, b
);
183 if (x
> edit
->max_column
)
184 edit
->max_column
= x
;
187 xn
= next_tab_pos (x
);
190 xn
= x
+ width_of_long_printable (c
);
199 if (x
> edit
->max_column
)
200 edit
->max_column
= x
;
205 /* calcs pixel length of the line beginning at b up to upto */
206 static int calc_text_len (WEdit
* edit
, long b
, long upto
)
211 if (x
> edit
->max_column
)
212 edit
->max_column
= x
;
215 c
= edit_get_byte (edit
, b
);
218 if (x
> edit
->max_column
)
219 edit
->max_column
= x
;
223 x
= next_tab_pos (x
);
226 x
+= width_of_long_printable (c
);
233 /* If pixels is zero this returns the count of pixels from current to upto. */
234 /* If upto is zero returns index of pixels across from current. */
235 long edit_move_forward3 (WEdit
* edit
, long current
, int pixels
, long upto
)
237 CPushFont ("editor", 0);
239 current
= calc_text_len (edit
, current
, upto
);
242 calc_text_pos (edit
, current
, &q
, pixels
);
249 extern int column_highlighting
;
251 /* gets the characters style (eg marked, highlighted) from its position in the edit buffer */
252 static inline cache_type
get_style_fast (WEdit
* edit
, long q
, int c
)
256 if (!(isprint (c
) || (option_international_characters
&& FONT_PER_CHAR
[c
])))
257 if (c
!= '\n' && c
!= '\t')
258 s
|= MOD_ABNORMAL
* 256;
259 edit_get_syntax_color (edit
, q
, (int *) &fg
, (int *) &bg
);
260 return s
| ((fg
& 0xFF) << 24) | ((bg
& 0xFF) << 16);
263 /* gets the characters style (eg marked, highlighted) from its position in the edit buffer */
264 static inline cache_type
get_style (WEdit
* edit
, long q
, int c
, long m1
, long m2
, int x
)
268 if (q
== edit
->curs1
)
269 s
|= MOD_CURSOR
* 256;
270 if (q
>= m1
&& q
< m2
) {
271 if (column_highlighting
) {
272 if ((x
>= edit
->column1
&& x
< edit
->column2
)
273 || (x
>= edit
->column2
&& x
< edit
->column1
))
274 s
|= MOD_INVERSE
* 256;
276 s
|= MOD_MARKED
* 256;
279 if (q
== edit
->bracket
)
281 if (q
>= edit
->found_start
&& q
< edit
->found_start
+ edit
->found_len
)
282 s
|= MOD_HIGHLIGHTED
* 256;
283 if (!(isprint (c
) || (option_international_characters
&& FONT_PER_CHAR
[c
])))
284 if (c
!= '\n' && c
!= '\t')
285 s
|= MOD_ABNORMAL
* 256;
286 edit_get_syntax_color (edit
, q
, (int *) &fg
, (int *) &bg
);
287 return s
| ((fg
& 0xFF) << 24) | ((bg
& 0xFF) << 16);
290 static void convert_text (WEdit
* edit
, long q
, cache_type
* p
, int x
, int x_max
, int row
)
295 unsigned char *r
, text
[4];
296 int book_mark_colors
[10], book_mark
;
297 eval_marks (edit
, &m1
, &m2
);
298 book_mark
= book_mark_query_all (edit
, edit
->start_line
+ row
, book_mark_colors
);
299 last
= q
+ (x_max
- x
) / 2 + 2; /* for optimization, we say that the last character
300 of this line cannot have an offset greater than this.
301 This can be used to rule out uncommon text styles,
302 like a character with a cursor, or selected text */
304 int the_end
= 0, book_mark_cycle
= 0;
306 c
= edit_get_byte (edit
, q
);
308 *p
= get_style (edit
, q
, c
, m1
, m2
, x
);
311 *p
= (*p
& 0x0000FFFF) | (book_mark_colors
[book_mark_cycle
++ % book_mark
] << 16);
321 t
= next_tab_pos (x
);
325 x
+= FONT_PER_CHAR
[' '];
330 x
= next_tab_pos (x
);
335 x
+= convert_to_long_printable (c
, text
);
351 } else if ((m2
< q
|| m1
> last
) && (edit
->curs1
< q
|| edit
->curs1
> last
) && \
352 (edit
->found_start
+ edit
->found_len
< q
|| edit
->found_start
> last
) &&
353 (edit
->bracket
< q
|| edit
->bracket
> last
)) {
355 c
= edit_get_byte (edit
, q
);
356 *p
= get_style_fast (edit
, q
, c
);
361 if (x
> edit
->max_column
)
362 edit
->max_column
= x
;
367 t
= next_tab_pos (x
);
371 x
+= FONT_PER_CHAR
[' '];
376 x
= next_tab_pos (x
);
380 x
+= convert_to_long_printable (c
, text
);
398 c
= edit_get_byte (edit
, q
);
399 *p
= get_style (edit
, q
, c
, m1
, m2
, x
);
404 if (x
> edit
->max_column
)
405 edit
->max_column
= x
;
410 t
= next_tab_pos (x
);
414 x
+= FONT_PER_CHAR
[' '];
419 x
= next_tab_pos (x
);
423 x
+= convert_to_long_printable (c
, text
);
440 if (x
> edit
->max_column
)
441 edit
->max_column
= x
;
445 void edit_set_cursor (Window win
, int x
, int y
, int bg
, int fg
, int width
, char t
)
448 gdk_gc_set_foreground (win
->gc
, &win
->color
[18]);
449 gdk_draw_rectangle (win
->text_area
, win
->gc
, 0, x
, y
+ FONT_OVERHEAD
, width
- 1, FONT_HEIGHT
- 1);
451 CSetColor (edit_cursor_color
);
452 CLine (win
, x
, y
+ FONT_OVERHEAD
,
453 x
, y
+ FONT_HEIGHT
- 1); /* non focussed cursor form */
454 CLine (win
, x
+ 1, y
+ FONT_OVERHEAD
,
455 x
+ width
- 1, y
+ FONT_OVERHEAD
);
456 set_cursor_position (win
, x
, y
, width
, FONT_HEIGHT
, CURSOR_TYPE_EDITOR
, t
, bg
, fg
); /* widget library's flashing cursor */
460 static inline int next_tab (int x
, int scroll_right
)
462 return next_tab_pos (x
- scroll_right
- EDIT_TEXT_HORIZONTAL_OFFSET
) - x
+ scroll_right
+ EDIT_TEXT_HORIZONTAL_OFFSET
;
465 static int draw_tab (Window win
, int x
, int y
, cache_type s
, int scroll_right
)
471 unsigned long fg
, bg
;
473 l
= next_tab (x
, scroll_right
);
475 set_style_color (s
, &fg
.pixel
, &bg
.pixel
);
476 gdk_gc_set_foreground (win
->gc
, &bg
);
477 gdk_draw_rectangle (win
->text_area
, win
->gc
, 1, x
, y
+ FONT_OVERHEAD
, l
, FONT_HEIGHT
);
478 /* if we printed a cursor: */
479 if (s
& (MOD_CURSOR
* 256))
480 edit_set_cursor (win
, x
, y
, bg
.pixel
, fg
.pixel
, FONT_PER_CHAR
[' '], ' ');
482 set_style_color (s
, &fg
, &bg
);
484 CRectangle (win
, x
, y
+ FONT_OVERHEAD
, l
, FONT_HEIGHT
);
485 /* if we printed a cursor: */
486 if (s
& (MOD_CURSOR
* 256))
487 edit_set_cursor (win
, x
, y
, bg
, fg
, FONT_PER_CHAR
[' '], ' ');
496 static inline void draw_space (Window win
, int x
, int y
, cache_type s
, int l
)
501 unsigned long fg
, bg
;
504 set_style_color (s
, &fg
.pixel
, &bg
.pixel
);
505 gdk_gc_set_foreground (win
->gc
, &bg
);
506 gdk_draw_rectangle (win
->text_area
, win
->gc
, 1, x
, y
+ FONT_OVERHEAD
, l
, FONT_HEIGHT
);
508 set_style_color (s
, &fg
, &bg
);
510 CRectangle (win
, x
, y
+ FONT_OVERHEAD
, l
, FONT_HEIGHT
);
511 /* if we printed a cursor: */
512 if (s
& (MOD_CURSOR
* 256))
513 edit_set_cursor (win
, x
, y
, bg
, fg
, FONT_PER_CHAR
[' '], ' ');
520 gdk_draw_image_text (GdkDrawable
*drawable
,
528 GdkWindowPrivate
*drawable_private
;
529 GdkFontPrivate
*font_private
;
530 GdkGCPrivate
*gc_private
;
532 g_return_if_fail (drawable
!= NULL
);
533 g_return_if_fail (font
!= NULL
);
534 g_return_if_fail (gc
!= NULL
);
535 g_return_if_fail (text
!= NULL
);
537 drawable_private
= (GdkWindowPrivate
*) drawable
;
538 if (drawable_private
->destroyed
)
540 gc_private
= (GdkGCPrivate
*) gc
;
541 font_private
= (GdkFontPrivate
*) font
;
543 if (font
->type
== GDK_FONT_FONT
)
545 XFontStruct
*xfont
= (XFontStruct
*) font_private
->xfont
;
546 XSetFont(drawable_private
->xdisplay
, gc_private
->xgc
, xfont
->fid
);
547 if ((xfont
->min_byte1
== 0) && (xfont
->max_byte1
== 0))
549 XDrawImageString (drawable_private
->xdisplay
, drawable_private
->xwindow
,
550 gc_private
->xgc
, x
, y
, text
, text_length
);
554 XDrawImageString16 (drawable_private
->xdisplay
, drawable_private
->xwindow
,
555 gc_private
->xgc
, x
, y
, (XChar2b
*) text
, text_length
/ 2);
558 else if (font
->type
== GDK_FONT_FONTSET
)
560 XFontSet fontset
= (XFontSet
) font_private
->xfont
;
561 XmbDrawImageString (drawable_private
->xdisplay
, drawable_private
->xwindow
,
562 fontset
, gc_private
->xgc
, x
, y
, text
, text_length
);
565 g_error("undefined font type\n");
571 static int draw_string (Window win
, int x
, int y
, cache_type s
, unsigned char *text
, int length
)
576 unsigned long fg
, bg
;
580 set_style_color (s
, &fg
.pixel
, &bg
.pixel
);
581 gdk_gc_set_background (win
->gc
, &bg
);
582 gdk_gc_set_foreground (win
->gc
, &fg
);
583 gdk_draw_image_text (win
->text_area
, GTK_WIDGET (win
)->style
->font
, win
->gc
, x
+ FONT_OFFSET_X
, y
+ FONT_OFFSET_Y
, text
, length
);
585 underlined
= set_style_color (s
, &fg
, &bg
);
586 CSetBackgroundColor (bg
);
588 CImageText (win
, x
+ FONT_OFFSET_X
, y
+ FONT_OFFSET_Y
, (char *) text
, length
);
589 l
= CTextWidth ((char *) text
, length
);
592 inc
= FONT_MEAN_WIDTH
* 2 / 3;
593 CSetColor (color_palette (18));
595 CLine (win
, x
, y
+ FONT_HEIGHT
+ FONT_OVERHEAD
- 1 - h
, x
+ min (l
, inc
- (x
% inc
) - 1), y
+ FONT_HEIGHT
+ FONT_OVERHEAD
- 1 - h
);
597 for (i
= inc
- min (l
, (x
% inc
)); i
< l
; i
+= inc
) {
598 CLine (win
, x
+ i
, y
+ FONT_HEIGHT
+ FONT_OVERHEAD
- 1 - h
, x
+ min (l
, i
+ inc
- 1), y
+ FONT_HEIGHT
+ FONT_OVERHEAD
- 1 - h
);
603 /* if we printed a cursor: */
605 if (s
& (MOD_CURSOR
* 256))
606 edit_set_cursor (win
, x
, y
, bg
.pixel
, fg
.pixel
, FONT_PER_CHAR
[*text
], *text
);
607 return x
+ gdk_text_width (GTK_WIDGET (win
)->style
->font
, text
, length
);
609 if (s
& (MOD_CURSOR
* 256))
610 edit_set_cursor (win
, x
, y
, bg
, fg
, FONT_PER_CHAR
[*text
], *text
);
615 #define STYLE_DIFF (*cache != *line \
616 || ((*cache | *line) & (MOD_CURSOR * 256)) \
617 || !*cache || !*line)
619 int get_ignore_length (cache_type
*cache
, cache_type
*line
)
622 for (i
= 0; i
< CACHE_WIDTH
; i
++, line
++, cache
++) {
629 static inline size_t lwstrnlen (const cache_type
*s
, size_t count
)
631 const cache_type
*sc
;
632 for (sc
= s
; count
-- && *sc
!= 0; ++sc
);
636 static inline size_t lwstrlen (const cache_type
*s
)
638 const cache_type
*sc
;
639 for (sc
= s
; *sc
!= 0; ++sc
);
643 int get_ignore_trailer (cache_type
*cache
, cache_type
*line
, int length
)
646 int cache_len
, line_len
;
647 cache_len
= lwstrnlen (cache
, CACHE_WIDTH
);
648 line_len
= lwstrlen (line
);
650 if (line_len
> cache_len
)
651 for (i
= line_len
- 1; i
>= cache_len
&& i
>= length
; i
--)
655 for (i
= cache_len
- 1, line
= line
+ i
, cache
= cache
+ i
; i
> length
; i
--, line
--, cache
--)
662 /* erases trailing bit of old line if a new line is printed over a longer old line */
663 static void cover_trail (Window win
, int x_start
, int x_new
, int x_old
, int y
)
665 if (x_new
< EDIT_TEXT_HORIZONTAL_OFFSET
)
666 x_new
= EDIT_TEXT_HORIZONTAL_OFFSET
;
667 if (x_new
< x_old
) { /* no need to print */
669 gdk_gc_set_foreground (win
->gc
, &win
->color
[1]);
670 gdk_draw_rectangle (win
->text_area
, win
->gc
, 1, x_new
, y
+ FONT_OVERHEAD
, x_old
- x_new
, FONT_HEIGHT
);
672 CSetColor (edit_normal_background_color
);
673 CRectangle (win
, x_new
, y
+ FONT_OVERHEAD
, x_old
- x_new
, FONT_HEIGHT
+ (FONT_OVERHEAD
!= 0 && !FIXED_FONT
));
677 gdk_gc_set_foreground (win
->gc
, &win
->color
[1]);
679 CSetColor (edit_normal_background_color
);
682 /* true type fonts print stuff out of the bounding box (aaaaaaaaarrrgh!!) */
684 if (FONT_OVERHEAD
&& x_new
> EDIT_TEXT_HORIZONTAL_OFFSET
)
686 gdk_draw_line (win
->text_area
, win
->gc
, max (x_start
, EDIT_TEXT_HORIZONTAL_OFFSET
), y
+ FONT_HEIGHT
+ FONT_OVERHEAD
, x_new
- 1, y
+ FONT_HEIGHT
+ FONT_OVERHEAD
);
688 CLine (win
, max (x_start
, EDIT_TEXT_HORIZONTAL_OFFSET
), y
+ FONT_HEIGHT
+ FONT_OVERHEAD
, x_new
- 1, y
+ FONT_HEIGHT
+ FONT_OVERHEAD
);
692 cache_type mode_spacing
= 0;
694 #define NOT_VALID (-2000000000)
696 void edit_draw_proportional (void *data
,
697 void (*converttext
) (void *, long, cache_type
*, int, int, int),
698 int calctextpos (void *, long, long *, int),
708 static struct cache_line lines
[CACHE_HEIGHT
];
709 static Window last
= 0;
710 cache_type style
, line
[MAX_LINE_LEN
], *p
;
711 unsigned char text
[128];
712 int x0
, x
, ignore_text
= 0, ignore_trailer
= 2000000000, j
, i
;
715 tab_width
= tabwidth
;
716 if (option_long_whitespace
)
717 tab_width
= tabwidth
*= 2;
721 /* if its not the same window, reset the screen rememberer */
722 if (last
!= win
|| !win
) {
724 for (i
= 0; i
< CACHE_HEIGHT
; i
++) {
725 lines
[i
].x0
= NOT_VALID
;
732 /* get point to start drawing */
733 x0
= (*calctextpos
) (data
, b
, &q
, -scroll_right
+ x_offset
);
734 /* q contains the offset in the edit buffer */
736 /* translate this line into printable characters with a style (=color) high byte */
737 (*converttext
) (data
, q
, line
, x0
, x_max
- scroll_right
- EDIT_TEXT_HORIZONTAL_OFFSET
, row
);
739 /* adjust for the horizontal scroll and border */
740 x0
+= scroll_right
+ EDIT_TEXT_HORIZONTAL_OFFSET
;
743 /* is some of the line identical to that already printed so that we can ignore it? */
744 if (!EditExposeRedraw
) {
745 if (lines
[row
].x0
== x0
&& row
< CACHE_HEIGHT
) { /* i.e. also && lines[row].x0 != NOT_VALID */
746 ignore_text
= get_ignore_length (lines
[row
].data
, line
);
748 ignore_trailer
= get_ignore_trailer (lines
[row
].data
, line
, ignore_text
);
755 if ((*p
& 0x80) && (*p
& mode_spacing
)) {
756 #ifdef STILL_TO_BE_SUPPORTED
757 x
+= edit_insert_pixmap (win
, x
, y
, *p
& 0x7F);
758 /* the pixmap will be clipped, if it's taller than the
759 current font, else centred top to bottom */
766 if ((*p
& 0xFF) == '\t') {
768 if (j
> ignore_text
&& j
< ignore_trailer
+ 1)
769 x
= draw_tab (win
, x
, y
, *p
, scroll_right
);
771 x
+= next_tab (x
, scroll_right
);
775 style
= *p
& 0xFFFFFF00UL
;
778 text
[i
++] = (unsigned char) *p
++;
780 if (j
== ignore_text
|| j
== ignore_trailer
)
782 } while (i
< 128 && *p
&& style
== (*p
& 0xFFFFFF00UL
) && (*p
& 0xFF) != '\t');
784 if (style
& mode_spacing
) {
786 for (k
= 0; k
< i
; k
++) {
787 draw_space (win
, x
, y
, (0xFFFFFF00UL
- mode_spacing
) & style
, text
[k
]);
791 if (j
> ignore_text
&& j
< ignore_trailer
+ 1)
792 x
= draw_string (win
, x
, y
, style
, text
, i
);
795 x
+= gdk_text_width (GTK_WIDGET(win
)->style
->font
, text
, i
);
797 x
+= CTextWidth ((char *) text
, i
);
804 if (!EditExposeRedraw
|| EditClear
)
805 cover_trail (win
, x0
, x
, lines
[row
].x1
, y
);
806 memcpy (&(lines
[row
].data
[ignore_text
]),
807 &(line
[ignore_text
]),
808 (min (j
, CACHE_WIDTH
) - ignore_text
) * sizeof (cache_type
));
810 lines
[row
].data
[min (j
, CACHE_WIDTH
)] = 0;
814 if (EditExposeRedraw
)
821 void edit_draw_this_line_proportional (WEdit
* edit
, long b
, int row
, int start_column
, int end_column
)
824 if (row
< 0 || row
>= edit
->num_widget_lines
)
827 if (row
+ edit
->start_line
> edit
->total_lines
)
828 b
= edit
->last_byte
+ 1; /* force b out of range of the edit buffer for blanks lines */
830 if (end_column
> CWidthOf (edit
->widget
))
831 end_column
= CWidthOf (edit
->widget
);
833 edit_get_syntax_color (edit
, b
- 1, &fg
, &bg
);
835 edit_draw_proportional (edit
,
836 (void (*) (void *, long, cache_type
*, int, int, int)) convert_text
,
837 (int (*) (void *, long, long *, int)) calc_text_pos
,
838 edit
->start_col
, CWindowOf (edit
->widget
),
839 end_column
, b
, row
, row
* FONT_PIX_PER_LINE
+ EDIT_TEXT_VERTICAL_OFFSET
,
840 EditExposeRedraw
? start_column
: 0, FONT_PER_CHAR
[' '] * TAB_SIZE
);
844 /*********************************************************************************/
845 /* The remainder is for the text box widget */
846 /*********************************************************************************/
848 static inline int nroff_printable (int c
)
854 static int calc_text_pos_str (unsigned char *text
, long b
, long *q
, int l
)
856 int x
= 0, c
= 0, xn
= 0, d
;
866 xn
= next_tab_pos (x
);
872 xn
= x
- FONT_PER_CHAR
[d
];
875 if (!nroff_printable (c
))
877 xn
= x
+ FONT_PER_CHAR
[c
];
889 int prop_font_strcolmove (unsigned char *str
, int i
, int column
)
892 CPushFont ("editor", 0);
893 calc_text_pos_str (str
, i
, &q
, column
* FONT_MEAN_WIDTH
);
900 /* b is the beginning of the line. l is the length in pixels up to a point
901 on some character which is unknown. The character pos is returned in
902 *q and the characters pixel x pos from b is return'ed. */
903 int calc_text_pos2 (CWidget
* w
, long b
, long *q
, int l
)
906 CPushFont ("editor", 0);
907 r
= calc_text_pos_str ((unsigned char *) w
->text
, b
, q
, l
);
912 int highlight_this_line
;
914 /* this is for the text widget (i.e. nroff formatting) */
915 void convert_text2 (CWidget
* w
, long q
, cache_type
*line
, int x
, int x_max
, int row
)
921 m1
= min (w
->mark1
, w
->mark2
);
922 m2
= max (w
->mark1
, w
->mark2
);
930 *p
|= 0xFFFF0000UL
; /* default background colors */
931 if (highlight_this_line
)
932 *p
|= MOD_HIGHLIGHTED
* 256;
933 if (q
>= m1
&& q
< m2
)
934 *p
|= MOD_MARKED
* 256;
939 if (highlight_this_line
) {
941 x
+= FONT_PER_CHAR
[' '];
948 i
= next_tab_pos (x
) - x
;
952 i
-= FONT_PER_CHAR
[' '];
958 x
= next_tab_pos (x
);
966 x
-= FONT_PER_CHAR
[d
];
968 *p
|= MOD_ITALIC
* 256;
970 *p
|= MOD_BOLD
* 256;
974 if (!nroff_printable (c
)) {
976 *p
|= MOD_ABNORMAL
* 256;
978 x
+= FONT_PER_CHAR
[c
];