4 * Author: Teemu Rantanen <tvr@cs.hut.fi>
5 * Copyright (c) 1992 Teemu Rantanen
8 * Created: Tue Mar 3 02:54:45 1992 tvr
9 * Last modified: Tue May 12 04:26:29 1992 tvr
14 #include <sys/types.h>
19 #include "../HText/HText.h"
21 #include "XlFormatText.h"
23 int xl_calc_position();
24 int xl_character_width();
26 #define MAX(a, b) ((a) > (b) ? (a) : (b))
29 * Set up how to format text (current left and right margins)
31 void xl_set_margins(p, left, right, c_l, c_r, x, y, low_y, m)
42 case MARGIN_START_STYLE:
43 i = xl_object_mode(p);
45 *c_l = xl_calc_position(p, I_LEFT, left, right);
47 *x = xl_calc_position(p, I_LEFT | I_FIRST, left, right);
53 if (i & STYLE_CHANGE_REGION_ON_TAB) {
55 *c_r = xl_calc_position(p, I_MIDDLE_L, left, right);
59 *c_r = xl_calc_position(p, I_RIGHT, left, right);
65 case MARGIN_HANDLE_P_OBJECT:
66 if (xl_object_mode(p) & STYLE_CHANGE_REGION_ON_TAB) {
68 *c_l = xl_calc_position(p, I_MIDDLE_R, left, right);
69 *c_r = xl_calc_position(p, I_RIGHT, left, right);
71 *x = xl_calc_position(p, I_MIDDLE_R | I_FIRST, left, right);
78 printf("xl_set_margins(): normal tab ... barf\n");
85 printf("xl_set_margins: illegal mode\n");
92 * Check how many objects belongs to this line.
94 int xl_check_objects(pp, x_corner, y, right)
100 HTextObject_t *p, *p_old;
116 if (!p || (p->paragraph)) {
117 r |= FORMAT_REGION_ENDS;
128 if (p_old && (p_old->style != p->style)) {
129 r |= FORMAT_NEW_STYLE;
130 r |= FORMAT_REGION_ENDS;
135 if ((x + p->width) >= right) {
136 r |= FORMAT_NEXT_OBJECT_TOO_LONG;
144 x += p->width + xl_wordgap(p);
155 * Return pointer to where to go on.
166 * Set new x-koordinate if line of objects is not 'leftified'
167 * Set new y coordinate above all objects.
169 void xl_modify_objects(p_start, p_end, right, mode)
170 HTextObject_t *p_start;
171 HTextObject_t *p_end;
175 HTextObject_t *p = p_start;
176 HTextObject_t *p_last;
184 if (p_start == p_end) {
187 if (!p_start->paragraph) {
188 printf("zero object ?\n");
195 p_last = p_end->prev;
199 for (p_last = p; p_last->next; p_last = p_last->next);
203 switch (xl_object_style(p_start)) {
212 offset = (right - (p_last->x + p_last->width)) / 2;
214 for (p; p != p_end; p = p->next) {
221 printf("Style not supported yet\n");
225 *newy = p_start->y + xl_lineheightandgap(p_start, p_end);
231 * width is a request which can be denied (in case of ftp-text for
233 * Maximum width used on the page is returned. Everything else on the screen
234 * is formatted using given width.
236 int XlFormatText(leftmargin, width, topmargin, vwidth, vheight, htext)
237 int leftmargin, width;
239 int *vwidth, *vheight;
244 int max_right_position = leftmargin;
247 * Current x,y coordinates.
252 * When there are many regions next to other, store starting
253 * upper and lower levels
259 * current format region
267 HTextObject_t *p = htext->first;
269 HTextObject_t *p_start = 0;
272 * Should check ascend (if there is any text)
276 low_y = high_y = y = topmargin;
278 xl_set_margins(p, leftmargin, leftmargin + width,
279 ¤t_left, ¤t_right,
280 &x, &y, low_y, MARGIN_START_STYLE);
295 * What objects are on this line ?
299 mode = xl_check_objects(&p, &x, y, current_right);
302 * Check for zero objects. This prevents endless loop and makes
303 * sure this object will be modified
305 if ((p == p_start) && p && !p->paragraph &&
306 (mode & FORMAT_NEXT_OBJECT_TOO_LONG)) {
307 mode |= FORMAT_ONLY_OBJECT_TOO_LONG;
311 * Update object positions if needs justifying etc
313 xl_modify_objects(p_start, p, current_right, mode);
316 * Check maximum object x position
320 ((p->prev->x + p->prev->width) > max_right_position)) {
321 max_right_position = p->prev->x + p->prev->width;
323 if (xl_object_mode(p_start) & STYLE_RAW) {
325 * Raw style HTextObject paragraphs
328 if (p && p_start->paragraph) {
332 switch (p_start->paragraph) {
339 y += xl_linespace(p_start, p);
341 low_y = high_y = MAX(y, high_y);
353 for (pp = p_start; pp != p; pp = pp->next) {
354 switch (pp->paragraph) {
366 x += xl_character_width(p_start) * i;
371 int cl = xl_character_width(p_start);
373 i = ((x - leftmargin) % (cl * 8));
388 if (mode & FORMAT_NEXT_OBJECT_TOO_LONG) {
390 y += xl_linespace(p_start, p);
392 high_y = MAX(y, high_y);
394 if (mode & FORMAT_ONLY_OBJECT_TOO_LONG) {
400 * Check paragraph objects
402 if (p_start->paragraph) {
403 switch (p_start->paragraph) {
408 y += xl_linespace(p_start, p);
412 high_y = MAX(y, high_y);
417 printf("XlFormatText(): there should not be newlines in htext\n");
421 case HTEXT_PARAGRAPH:
424 y += xl_linespace(p_start, p);
425 y += xl_paragraphspace(p_start, p);
431 xl_set_margins(p, leftmargin, leftmargin + width,
432 ¤t_left, ¤t_right,
433 &x, &y, low_y, MARGIN_START_STYLE);
438 xl_set_margins(p, leftmargin, leftmargin + width,
439 ¤t_left, ¤t_right, &x, &y,
440 low_y, MARGIN_HANDLE_P_OBJECT);
444 printf("format: dont understand continued objects here\n");
456 * Make sure paragraph endings happen
458 if (p && (p->style != p_start->style)) {
459 mode |= FORMAT_NEW_STYLE;
462 * Check for new style
464 if (mode & FORMAT_NEW_STYLE) {
466 * Make sure one and only line is advanced always
470 high_y += xl_linespace(p_start, p);
472 high_y += xl_stylespace(p_start, p);
478 if (high_y_old == high_y) {
479 high_y += xl_linespace(p_start, p);
482 high_y += xl_stylespace_before(p, p);
484 high_y += xl_stylespace(p_start, p);
491 xl_set_margins(p, leftmargin, leftmargin + width,
492 ¤t_left, ¤t_right,
493 &x, &y, low_y, MARGIN_START_STYLE);
499 * Check region ending
501 /* tab sivulle tai tab sivulleyl|s depending on object and so on */
503 /* set regions with margin_handle_p_object */
504 /* check where to start (y, x). x = regionstart or tab */
506 if ((mode & FORMAT_REGION_ENDS) && p) {
512 case HTEXT_PARAGRAPH:
513 high_y += xl_lineheightandgap(p_start, p);
517 xl_set_margins(p, leftmargin, leftmargin + width,
518 ¤t_left, ¤t_right,
519 &x, &y, low_y, MARGIN_START_STYLE);
523 /*high_y += xl_lineheightandgap(p_start, p);*/
530 xl_set_margins(p, leftmargin, leftmargin + width,
531 ¤t_left, ¤t_right, &x, &y, low_y,
532 MARGIN_HANDLE_P_OBJECT);
536 printf("format: dont understand continued objects here\n");
549 if (mode & FORMAT_NEW_STYLE) {
552 xl_set_margins(p, leftmargin, leftmargin + width,
553 ¤t_left, ¤t_right,
554 &x, &y, low_y, MARGIN_START_STYLE);
559 * Give width and height to caller
564 y += xl_linespace(p_start, p);
568 *vwidth = MAX(max_right_position, width);