1 /*
2  * Copyright (C) 1991,1992 NEC Corporation.
3  */
4 #ifndef lint
5 static char rcsid[] =
6 	"$Id: justify.c,v 2.9 1994/04/19 10:16:43 uchida Exp $ (NEC)";
7 #endif
8 
9 #include <stdio.h>
10 #include "plain2.h"
11 /*
12  * Justification
13  *	"centering"  or "justify to right "
14  */
indType(begin,end)15 indType(begin, end)
16 int	begin;
17 int	end;
18 {
19 	register struct text	*textp;
20 	int	l;
21 	int	rightJstfy = 1;
22 	int	centering  = 1;
23 	int	sameIndentLines = 0;
24 	int	textCenter, textRight, margin;
25 	int	topIndent,  rightSpace;
26 	topIndent  = texts[begin]->indent;
27 	textCenter = rightMargin / 2;
28 	textRight  = rightMargin * 8 / 10;
29 	margin     = rightMargin / 8;
30 	if (!prevLine(begin)->blank || !nextLine(end - 1)->blank)
31 		return 0;
32 	for (l = begin; l < end; l++) {
33 		if ((textp = texts[l])->block)
34 			return 0;
35 		if (textp->indent <= topIndent
36 		    && textp->indent >= topIndent - 2)
37 			sameIndentLines++;
38 		if (textp->indent < textCenter
39 		    || textp->length < textRight)
40 			rightJstfy = 0;
41 		rightSpace = textp->indent
42 			+ textp->length - rightMargin;
43 		if (!textp->indent || rightSpace < -margin || rightSpace > margin)
44 			centering = 0;
45 		if (!rightJstfy && !centering)
46 			return IND_INDENT;
47 	}
48 	if (centering
49 	    && topIndent > rightMargin / 4
50 	    && (end - begin == 1 || sameIndentLines * 3 < (end - begin) * 2))
51 	    return IND_CENTER;
52 	if (rightJstfy)
53 		return IND_RIGHT;
54 	return IND_INDENT;
55 }
56 /*
57  * If given text block is justified, register block attribute as
58  * right/center justified.
59  */
markIfJustified(begin,end)60 markIfJustified(begin, end)
61 int	begin;
62 int	end;
63 {
64 	int	l;
65 	struct	textBlock	*tbp;
66 	DBG2(9, "markIfJustified (%d-%d)\n", begin, end);
67 	switch (indType(begin, end)) {
68 	    case IND_INDENT:
69 		return;
70 	    case IND_RIGHT:
71 		tbp = newTextBlock(begin, end, TB_RIGHT);
72 		break;
73 	    case IND_CENTER:
74 		tbp = newTextBlock(begin, end, TB_CENTER);
75 		break;
76 	    default:
77 		return;
78 	}
79 	for (l = begin; l < end; l++)
80 		texts[l]->block = tbp;
81 }
justified(begin,end)82 justified(begin, end)
83 int	begin;
84 int	end;
85 {
86 	int	rstat;
87 	int	l, rbegin;
88 	DBG2(8, "justified (%d-%d)\n", begin, end);
89 	rstat = 0;
90 	rbegin = begin;
91 	for (l = begin; l <= end; l++)
92 		if (rstat) {
93 			if (l >= end
94 			    || texts[l]->blank
95 			    || texts[l]->block != NULL) {
96 				markIfJustified(rbegin, l<end?l:end);
97 				rstat = 0;
98 			}
99 		}
100 		else {
101 			if (l >= end)
102 				break;
103 			else if (!texts[l]->blank
104 				 && texts[l]->block == NULL) {
105 				rbegin = l;
106 				rstat = 1;
107 			}
108 		}
109 }
110