~ubuntu-branches/ubuntu/intrepid/luatex/intrepid

« back to all changes in this revision

Viewing changes to src/texk/web2c/luatexdir/tex/postlinebreak.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2007-12-10 10:24:34 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20071210102434-9w9ljypghznwb4dy
Tags: 0.20.1-1
* new upstreams, add the announcements with changes to the debian dir
* call build.sh.linux with bash, not with sh, otherwise building breaks
  (thanks to Pascal de Bruijn <pmjdebruijn@gmail.com> from Ubuntu for
  letting us know) [np]
* update libpoppler patch
* change the texdoclua patch to use the new os.tmpdir with a template of
  /tmp/luatex.XXXXXX
* bump standards version to 3.7.3, no changes necessary
* convert copyright file to utf-8

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
*/
24
24
 
25
 
halfword 
 
25
static halfword 
26
26
do_push_dir_node (halfword p, halfword a ) {
27
27
  halfword n;
28
 
  assert (type(a)==whatsit_node && subtype(a)==dir_node);
29
28
  n = copy_node(a);
30
29
  vlink(n) = p; 
31
30
  return n;
32
31
}
33
32
 
34
 
halfword 
 
33
static halfword 
35
34
do_pop_dir_node ( halfword p ) {
36
35
  halfword n = vlink(p); 
37
 
  free_node(p,dir_node_size);
 
36
  flush_node(p);
38
37
  return n;
39
38
}
40
39
 
41
 
halfword add_dir_nodes (halfword r, halfword q) {
42
 
  halfword p;
43
 
  for (p=dir_ptr;p!=null;p=vlink(p)) {
44
 
    halfword tmp=new_dir(dir_dir(p)-64);
45
 
    couple_nodes(tmp,q);
46
 
    couple_nodes(r,tmp);
47
 
    r=vlink(r);
48
 
  }
49
 
  return r;
50
 
}
51
 
 
52
 
void
53
 
insert_dir_nodes_at_end (halfword *qq, halfword *rr, halfword final_par_glue) {
54
 
  halfword q,r; /* temporary registers for list manipulation */
55
 
  r = *rr;
56
 
  q = *qq;
57
 
  if (dir_ptr!=null) {
58
 
    if (vlink(r)==q) {
59
 
      assert(r!=null);
60
 
      *rr = add_dir_nodes(r,q);
61
 
    } else if (r==final_par_glue) {
62
 
      assert(alink(r)!=null && vlink(alink(r))==r);
63
 
      (void)add_dir_nodes(alink(r), q);
64
 
    } else {
65
 
      assert(q!=null);
66
 
      *qq = add_dir_nodes(q, vlink(q));
67
 
      *rr = *qq;
68
 
    }
69
 
  }
70
 
  return;
71
 
}
72
40
 
73
41
/* The total number of lines that will be set by |post_line_break|
74
42
is |best_line-prev_graf-1|. The last breakpoint is specified by
122
90
                         scaled first_indent,
123
91
                         halfword best_line ) {
124
92
 
 
93
  boolean have_directional = true;
125
94
  halfword q,r,s; /* temporary registers for list manipulation */
126
95
  halfword  p, k;
127
96
  scaled w;
144
113
     Node |r| is the passive node being moved from stack to stack.
145
114
  */
146
115
  q=break_node(best_bet); 
 
116
  /*used_discs = used_disc(best_bet);*/
 
117
  /*has_direction*/
147
118
  cur_p=null;
148
119
  do { 
149
120
    r=q; 
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. */
 
140
 
 
141
#if 0
 
142
        tprint("BEGIN OF LINE ");
 
143
        print_int(cur_break(cur_p));
 
144
        breadth_max=100000;
 
145
        depth_threshold=100000;
 
146
        show_node_list(temp_head);
 
147
#endif
169
148
    
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);
175
155
    }
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;
179
158
    }
180
 
    q=vlink(temp_head);
181
 
    while (q!=cur_break(cur_p)) {
182
 
      if (type(q)==whatsit_node && subtype(q)==dir_node) {
183
 
        if (dir_dir(q)>=0) {
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);
188
 
          }
189
 
        }
190
 
      }
191
 
      if (q==null || vlink(q)==0) {
192
 
        break;
193
 
      }
194
 
      q=vlink(q);
195
 
    }
196
159
 
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); 
 
167
    q = null;
202
168
    disc_break=false; 
203
169
    post_disc_break=false;
204
170
    glue_break = false;
205
171
 
206
 
    if (q!=null && type(q)==glue_node) {
207
 
      r=alink(q);
208
 
      assert(vlink(r)==q);
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));
213
 
        vlink(r)=s;
214
 
        vlink(s)=q;
 
172
    if (r==null) {
 
173
      for (r=temp_head; vlink(r)!=null; r=vlink(r));
 
174
      if (r==final_par_glue) {
 
175
        /* This should almost always be true... */
 
176
        /* TODO assert ? */
 
177
        q = r;
 
178
        /* |q| refers to the last node of the line (and paragraph) */
 
179
        r = alink(r);
215
180
      }
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;
221
 
    } else {
222
 
      if (q==null) { 
223
 
        q=temp_head;
224
 
        while (vlink(q)!=null)  
225
 
          q=vlink(q);
226
 
      } else if (type(q)==disc_node) {
227
 
        /* @<Change discretionary to compulsory and set |disc_break:=true|@>*/
228
 
        r = vlink(q);
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;
233
 
        }
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; 
242
 
          r=vlink(q);
243
 
        }
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; 
252
 
          q=alink(r);
253
 
        }
254
 
        disc_break=true;
255
 
      } else if (type(q)==kern_node) {
256
 
        width(q)=0;
257
 
      } else if (type(q)==math_node) {
258
 
        surround(q)=0;
259
 
      }
260
 
      r=q;
 
188
      /* |q| refers to the last node of the line */
 
189
      q = r;
 
190
      r=alink(r);
 
191
      assert(vlink(r)==q);
 
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);
 
195
      assert(a!=null);
 
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);
 
199
        do {
 
200
          halfword d;
 
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);
 
206
          v = vlink(d);
 
207
          a = alink(d);
 
208
          fprintf(stderr,"Up to disc [%d]<-[%d]->[%d] & link [%d]\n",(int)a,(int)d,(int)v,(int)vlink_no_break(d));
 
209
          assert(a!=null);
 
210
          couple_nodes(a,vlink_no_break(d));
 
211
          vlink_no_break(d)=null; 
 
212
          tlink_no_break(d)=null;
 
213
          flush_node(d); 
 
214
        } while (v==null);
 
215
        couple_nodes(r,v);
 
216
        fprintf(stderr,"Close list [%d]<->[%d] a=[%d]\n",(int)r,(int)v,(int)alink(r));
 
217
        a = alink(r);
 
218
      }
 
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;
 
223
      }
 
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; 
 
229
      }
 
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;
 
236
      }
 
237
      disc_break=true;
 
238
    } else if (type(r)==kern_node) {
 
239
      width(r)=0;
 
240
    } else if (type(r)==math_node) {
 
241
      surround(r)=0;
 
242
    }
 
243
 
 
244
    /* DIR: Adjust the dir stack based on dir nodes in this line; */
 
245
    /* TODO what about the previousparagraph ??? */
 
246
    if (have_directional) {
 
247
      halfword e;
 
248
      halfword p;
 
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)
 
251
          continue;
 
252
        if (dir_dir(e)>=0) {
 
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);
 
256
        }
 
257
      }
 
258
      assert(e==cur_break(cur_p)); 
 
259
 
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));
265
 
        vlink(r)=vlink(q);
266
 
        vlink(q)=r;
267
 
        q=r;
 
261
      e = vlink(r);
 
262
      for (p=dir_ptr; p!=null; p=vlink(p)) {
 
263
        halfword s=new_dir(dir_dir(p)-64);
 
264
        couple_nodes(r,s);
 
265
        try_couple_nodes(s,e);
 
266
        r=s;
268
267
      }
269
268
    }
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);
 
273
      couple_nodes(r,s);
 
274
      try_couple_nodes(s,e);
 
275
      r=s;
 
276
    }
 
277
    if (q==null) {
 
278
      q = r;
 
279
    }
 
280
    /* Now [q] refers to the last node on the line */
 
281
 
 
282
    /* FIXME from this point on we no longer keep alink() valid */
 
283
 
 
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) {
274
288
      halfword ptmp;
275
289
      if (disc_break && (is_char_node(q) || (type(q) != disc_node))) {
277
291
        ptmp = p;
278
292
      } else {
279
293
        p = alink(q); /* get |vlink(p) = q| */
280
 
        assert(vlink(p)==q);
 
294
                assert(vlink(p)==q);
281
295
        ptmp = p;
282
296
        p = find_protchar_right(vlink(temp_head), p);
283
297
      }
284
298
      w = char_pw(p, right_side);
285
299
      if (w!=0) { /* we have found a marginal kern, append it after |ptmp| */
286
 
        k = new_margin_kern(-w, last_rightmost_char, right_side);
 
300
                k = new_margin_kern(-w, last_rightmost_char, right_side);
287
301
        vlink(k) = vlink(ptmp);
288
302
        vlink(ptmp) = k;
289
303
        if (ptmp == q) 
290
304
          q = vlink(q);
291
305
      }
292
306
    }
293
 
    /* if |q| was not a breakpoint at glue and has been reset to |rightskip| then
294
 
       we append |rightskip| after |q| now */
 
307
    /* if |q| was not a breakpoint at glue and has been reset to |rightskip|
 
308
       then we append |rightskip| after |q| now */
295
309
    if (!glue_break) {
296
310
      /* @<Put the \(r)\.{\\rightskip} glue after node |q|@>;*/
297
 
      r=new_param_glue(right_skip_code); 
 
311
      halfword r=new_param_glue(right_skip_code); 
298
312
      vlink(r)=vlink(q); 
299
313
      vlink(q)=r; 
300
314
      q=r;
301
315
    }
302
316
 
303
 
    /* /Modify the end of the line to reflect the nature of the break and to include
304
 
       \.{\\rightskip}; also set the proper value of |disc_break|; */
 
317
    /* /Modify the end of the line to reflect the nature of the break and to
 
318
       include \.{\\rightskip}; also set the proper value of |disc_break|; */
305
319
 
306
320
    /* Put the \(l)\.{\\leftskip} glue at the left and detach this line;*/
307
321
    /* The following code begins with |q| at the end of the list to be
309
323
       |vlink(temp_head)| pointing to the remainder of the paragraph, if any. */
310
324
    r=vlink(q); 
311
325
    vlink(q)=null; 
 
326
 
312
327
    q=vlink(temp_head); 
313
 
    vlink(temp_head)=r;
 
328
    try_couple_nodes(temp_head,r);
314
329
    if (passive_left_box(cur_p)!=null && passive_left_box(cur_p)!=0) {
315
330
      /* omega bits: */
316
331
      r=copy_node_list(passive_left_box(cur_p));
446
461
        }
447
462
      }
448
463
      if (pen!=0) {
449
 
        r=new_penalty(pen);
450
 
        vlink(cur_list.tail_field)=r; 
451
 
        cur_list.tail_field=r;
 
464
                r=new_penalty(pen);
 
465
                couple_nodes(cur_list.tail_field,r);
 
466
                cur_list.tail_field=r;
452
467
      }
453
468
    }
454
469
    /* /Append a penalty node, if a nonzero penalty is appropriate */
487
502
    }
488
503
  } while (cur_p!=null);
489
504
  if ((cur_line!=best_line)||(vlink(temp_head)!=null)) 
490
 
        confusion(maketexstring("line breaking"));
 
505
        tconfusion("line breaking");
491
506
  cur_list.pg_field=best_line-1;  /* prevgraf */
492
507
  cur_list.dirs_field=dir_ptr; /* dir_save */
 
508
  dir_ptr = null;
493
509
}
494
510