166
137
discretionary node, we modify the list so that the discretionary break
167
138
is compulsory, and we set |disc_break| to |true|. We also append
168
139
the |left_skip| glue at the left of the line, unless it is zero. */
142
tprint("BEGIN OF LINE ");
143
print_int(cur_break(cur_p));
145
depth_threshold=100000;
146
show_node_list(temp_head);
170
149
/* DIR: Insert dir nodes at the beginning of the current line;*/
171
150
for (q=dir_ptr;q!=null;q=vlink(q)) {
172
halfword tmp=new_dir(dir_dir(q));
173
couple_nodes(tmp,vlink(temp_head));
151
halfword tmp = new_dir(dir_dir(q));
152
halfword nxt = vlink(temp_head);
174
153
couple_nodes(temp_head,tmp);
154
couple_nodes(tmp,nxt);
176
/* DIR: Adjust the dir stack based on dir nodes in this line; */
177
156
if (dir_ptr!=null) {
178
157
flush_node_list(dir_ptr); dir_ptr=null;
181
while (q!=cur_break(cur_p)) {
182
if (type(q)==whatsit_node && subtype(q)==dir_node) {
184
dir_ptr = do_push_dir_node(dir_ptr,q);
185
} else if (dir_ptr!=null) {
186
if (dir_dir(dir_ptr)==(dir_dir(q)+64)) {
187
dir_ptr = do_pop_dir_node(dir_ptr);
191
if (q==null || vlink(q)==0) {
197
/* Modify the end of the line to reflect the nature of the break and to include
198
\.{\\rightskip}; also set the proper value of |disc_break|; */
160
/* Modify the end of the line to reflect the nature of the break and to
161
include \.{\\rightskip}; also set the proper value of |disc_break|; */
199
162
/* At the end of the following code, |q| will point to the final node on the
200
list about to be justified. */
201
assert(q==cur_break(cur_p));
163
list about to be justified. In the meanwhile |r| will point to the
164
node we will use to insert end-of-line stuff after. |q==null| means
165
we use the final position of |r| */
166
r = cur_break(cur_p);
202
168
disc_break=false;
203
169
post_disc_break=false;
204
170
glue_break = false;
206
if (q!=null && type(q)==glue_node) {
209
/* @<DIR: Insert dir nodes at the end of the current line@>;*/
210
insert_dir_nodes_at_end(&q,&r,final_par_glue);
211
if (passive_right_box(cur_p)!=null) {
212
s=copy_node_list(passive_right_box(cur_p));
173
for (r=temp_head; vlink(r)!=null; r=vlink(r));
174
if (r==final_par_glue) {
175
/* This should almost always be true... */
178
/* |q| refers to the last node of the line (and paragraph) */
216
delete_glue_ref(glue_ptr(q));
217
glue_ptr(q)=right_skip;
218
subtype(q)=right_skip_code+1;
181
/* |r| refers to the node after which the dir nodes should be closed */
182
} else if (type(r)==glue_node) {
183
delete_glue_ref(glue_ptr(r));
184
glue_ptr(r)=right_skip;
185
subtype(r)=right_skip_code+1;
219
186
incr(glue_ref_count(right_skip));
220
187
glue_break = true;
224
while (vlink(q)!=null)
226
} else if (type(q)==disc_node) {
227
/* @<Change discretionary to compulsory and set |disc_break:=true|@>*/
229
if (vlink(no_break(q))!=null) {
230
flush_node_list(vlink(no_break(q)));
231
vlink(no_break(q))=null;
232
tlink(no_break(q))=null;
234
if (vlink(post_break(q))!=null) {
235
/* @<Transplant the post-break list@>;*/
236
/* We move the post-break list from inside node |q| to the main list by
237
re\-attaching it just before the present node |r|, then resetting |r|. */
238
couple_nodes(q,vlink(post_break(q)));
239
couple_nodes(tlink(post_break(q)),r);
240
vlink(post_break(q))=null;
241
tlink(post_break(q))=null;
244
if (vlink(pre_break(q))!=null) {
245
/* @<Transplant the pre-break list@>;*/
246
/* We move the pre-break list from inside node |q| to the main list by
247
re\-attaching it just after the present node |q|, then resetting |q|. */
248
couple_nodes(q,vlink(pre_break(q)));
249
couple_nodes(tlink(pre_break(q)),r);
250
vlink(pre_break(q))=null;
251
tlink(pre_break(q))=null;
255
} else if (type(q)==kern_node) {
257
} else if (type(q)==math_node) {
188
/* |q| refers to the last node of the line */
192
/* |r| refers to the node after which the dir nodes should be closed */
193
} else if (type(r)==disc_node) {
194
halfword a = alink(r);
196
halfword v = vlink(r);
197
if (v==null) { /* nested disc, let's unfold */
198
fprintf(stderr,"Nested disc [%d]<-[%d]->null\n",(int)a,(int)r);
201
while (alink(a)!=null) a = alink(a);
202
assert(type(a)==nesting_node);
203
assert(subtype(a)=no_break_head(0)); /* No_break */
204
d = a - subtype(a); /* MAGIC subtype is offset of nesting with disc */
205
assert(type(d)==disc_node);
208
fprintf(stderr,"Up to disc [%d]<-[%d]->[%d] & link [%d]\n",(int)a,(int)d,(int)v,(int)vlink_no_break(d));
210
couple_nodes(a,vlink_no_break(d));
211
vlink_no_break(d)=null;
212
tlink_no_break(d)=null;
216
fprintf(stderr,"Close list [%d]<->[%d] a=[%d]\n",(int)r,(int)v,(int)alink(r));
219
if (vlink_no_break(r)!=null) {
220
flush_node_list(vlink_no_break(r));
221
vlink_no_break(r)=null;
222
tlink_no_break(r)=null;
224
if (vlink_pre_break(r)!=null) {
225
couple_nodes(a,vlink_pre_break(r));
226
couple_nodes(tlink_pre_break(r),r);
227
vlink_pre_break(r)=null;
228
tlink_pre_break(r)=null;
230
if (vlink_post_break(r)!=null) {
231
couple_nodes(r,vlink_post_break(r));
232
couple_nodes(tlink_post_break(r),v);
233
vlink_post_break(r)=null;
234
tlink_post_break(r)=null;
235
post_disc_break = true;
238
} else if (type(r)==kern_node) {
240
} else if (type(r)==math_node) {
244
/* DIR: Adjust the dir stack based on dir nodes in this line; */
245
/* TODO what about the previousparagraph ??? */
246
if (have_directional) {
249
for(e=vlink(temp_head); e!=null && e!=cur_break(cur_p); e=vlink(e)) {
250
if (type(e)!=whatsit_node || subtype(e)!=dir_node)
253
dir_ptr = do_push_dir_node(dir_ptr,e);
254
} else if (dir_ptr!=null && dir_dir(dir_ptr)==(dir_dir(e)+64)) {
255
dir_ptr = do_pop_dir_node(dir_ptr);
258
assert(e==cur_break(cur_p));
261
260
/* @<DIR: Insert dir nodes at the end of the current line@>;*/
262
insert_dir_nodes_at_end(&q,&r,final_par_glue);
263
if (passive_right_box(cur_p)!=null) {
264
r=copy_node_list(passive_right_box(cur_p));
262
for (p=dir_ptr; p!=null; p=vlink(p)) {
263
halfword s=new_dir(dir_dir(p)-64);
265
try_couple_nodes(s,e);
270
/* at this point |q| is the rightmost breakpoint; the only exception is the case
271
of a discretionary break with non-empty |pre_break|, then |q| has been changed
272
to the last node of the |pre_break| list */
269
if (passive_right_box(cur_p)!=null) {
270
/* TODO: CHECK has |s| below a |alink| ? */
271
halfword s = copy_node_list(passive_right_box(cur_p));
272
halfword e = vlink(r);
274
try_couple_nodes(s,e);
280
/* Now [q] refers to the last node on the line */
282
/* FIXME from this point on we no longer keep alink() valid */
284
/* at this point |q| is the rightmost breakpoint; the only exception is
285
the case of a discretionary break with non-empty |pre_break|, then |q|
286
has been changed to the last node of the |pre_break| list */
273
287
if (pdf_protrude_chars > 0) {
275
289
if (disc_break && (is_char_node(q) || (type(q) != disc_node))) {