Back to index

texmacs  1.0.7.15
Functions
stacker.cpp File Reference
#include "Stack/stacker.hpp"
#include "Boxes/construct.hpp"
#include "merge_sort.hpp"

Go to the source code of this file.

Functions

static int get_pos (array< SI > a, SI which)
static SI shove_in (box b1, box b2, SI hor_sep, SI top, SI bot)
static void shove (page_item &item1, page_item &item2, stack_border sb, stack_border sb2)
void merge_stack (array< page_item > &l, stack_border &sb, array< page_item > l2, stack_border sb2)
box typeset_as_stack (edit_env env, tree t, path ip)

Function Documentation

static int get_pos ( array< SI a,
SI  which 
) [static]

Definition at line 41 of file stacker.cpp.

                                {
  int step, test;
  step= test= N(a)>>1;
  while (a[test] != which) {
    step= step >> 1;
    if (step==0) {
      if (which < a[test]) return test-1;
      else return test+1;
    }
    else {
      if (which < a[test]) test= max (0, test- step);
      else test= min (N(a)-1, test+ step);
    }
  }
  return test;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void merge_stack ( array< page_item > &  l,
stack_border sb,
array< page_item l2,
stack_border  sb2 
)

Definition at line 219 of file stacker.cpp.

{
  int i= N(l)-1, j=0;
  while ((i >= 0) && (l[i]->type != PAGE_LINE_ITEM)) i--;
  while ((j < N(l2)) && (l2[j]->type != PAGE_LINE_ITEM)) j++;

  if (j >= N(l2)) {
    // no real lines in l2
    sb->vspc_after = max (sb->vspc_after, sb2->vspc_after);
    sb->nobr_after = sb->nobr_after || sb2->nobr_after;
  }
  else {
    if (i < 0) {
      // no real lines in l1
      sb->height_before  = sb2->height_before;
      sb->sep_before     = sb2->sep_before;
      sb->ver_sep_before = sb2->ver_sep_before;
      sb->hor_sep_before = sb2->hor_sep_before;
      sb->top            = sb2->top;
      sb->vspc_before    = max (sb->vspc_before, sb2->vspc_before);
      sb->nobr_before    = sb->nobr_before || sb2->nobr_before;
      //sb->vspc_before    = sb2->vspc_before;
      //sb->nobr_before    = sb2->nobr_before;
    }
    else {
      // normal case
      l[i]= copy (l[i]);
      shove (l[i], l2[j], sb, sb2);
      l[i]->spc= l[i]->spc + max (sb->vspc_after, sb2->vspc_before);
      if (sb->nobr_after || sb2->nobr_before) l[i]->penalty= HYPH_INVALID;
    }
    sb->height    = sb2->height;
    sb->sep       = sb2->sep;
    sb->ver_sep   = sb2->ver_sep;
    sb->hor_sep   = sb2->hor_sep;
    sb->bot       = sb2->bot;
    sb->vspc_after= sb2->vspc_after;
    sb->nobr_after= sb2->nobr_after;
  }

  l << l2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void shove ( page_item item1,
page_item item2,
stack_border  sb,
stack_border  sb2 
) [static]

Definition at line 125 of file stacker.cpp.

                                                                              {
  SI  height = max (sb->height , sb2->height_before );
  SI  sep    = max (sb->sep    , sb2->sep_before    );
  SI  hor_sep= max (sb->hor_sep, sb2->hor_sep_before);
  SI  ver_sep= max (sb->ver_sep, sb2->ver_sep_before);
  SI  bot    = sb->bot;
  SI  top    = sb2->top;

  box b1= item1->b, b2= item2->b;
  // cout << "Shove: " << sb->height << ", " << sb2->height_before
  // << "; " << b1->y1 << ", " << b2->y2
  // << "; " << top << ", " << bot << LF;

  while (true) {
    int type= b1->get_type ();
    if ((type == MOVE_BOX) && (b1->sx(0) == 0)) b1= b1[0];
    else if ((type == STACK_BOX) && (N(b1)>0)) {
      int i= N(b1)-1;
      while ((i >= 1) && (b1[i]->h() == 0)) i--;
      b1= b1[i];
    }
    else break;
  }
  while (true) {
    int type= b2->get_type ();
    if ((type == MOVE_BOX) && (b2->sx(0) == 0)) b2= b2[0];
    else if ((type == STACK_BOX) && (N(b2)>0)) {
      int i= 0, n= N(b2);
      while ((i < n-1) && (b2[i]->h() == 0)) i++;
      b2= b2[i];
    }
    else break;
  }

  if ((b2->y2- b1->y1) < (height- max (sep, ver_sep))) {
    // enough place
    // cout << "  Normal" << LF;
    item1->spc= item1->spc + space (height- (b2->y2- b1->y1));
  }
  else {
    SI sh= shove_in (b1, b2, hor_sep, top, bot);
    //cout << "  Shove: " << sh << LF;
    //cout << "    b1= " << b1 << "\n";
    //cout << "    b2= " << b2 << "\n";
    if (sh == 0 ||
       b1->get_type() == SCROLL_BOX ||
       b2->get_type() == SCROLL_BOX)
    {
      SI h= max (height, max (b2->y2, b2->y2 - b1->y1 - (top - bot)));
      item1->spc= item1->spc + space (h- (b2->y2- b1->y1));
    }
    else {
      // collisions
      SI h= max (height, sh + ver_sep);
      item1->spc= item1->spc + space (h- (b2->y2- b1->y1));
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SI shove_in ( box  b1,
box  b2,
SI  hor_sep,
SI  top,
SI  bot 
) [static]

Definition at line 59 of file stacker.cpp.

                                                      {
  // quick test whether there are collisions
  int i, j;
  SI min1= PLUS_INFINITY, max1= MINUS_INFINITY;
  SI min2= PLUS_INFINITY, max2= MINUS_INFINITY;
  for (i=0; i<N(b1); i++)
    if (b1[i]->w() > 0) {
      if (b1->sx1(i) < min1) min1= b1->sx1(i);
      if (b1->sx2(i) > max1) max1= b1->sx2(i);
    }
  for (i=0; i<N(b2); i++)
    if (b2[i]->w() > 0) {
      if (b2->sx1(i) < min2) min2= b2->sx1(i);
      if (b2->sx2(i) > max2) max2= b2->sx2(i);
    }
  if ((max1 + hor_sep < min2) || (max2 + hor_sep < min1)) return 0;

  // longer determination of height after shoving
  array<SI> hpos;
  for (i=0; i<N(b1); i++)
    if (b1[i]->w() > 0)
      hpos << (b1->sx1(i)- hor_sep) << (b1->sx2(i)+ hor_sep);
  for (i=0; i<N(b2); i++) 
    if (b2[i]->w() > 0)
      hpos << (b2->sx1(i)- hor_sep) << (b2->sx2(i)+ hor_sep);
  merge_sort (hpos);  

  int n= N(hpos)-1;
  array<SI> vpos1 (n);
  array<SI> vpos2 (n);
  for (i=0; i<n; i++) {
    vpos1[i]= bot;
    vpos2[i]= top;
  }

  for (i=0; i<N(b1); i++) {
    SI  y    = b1->sy1(i);
    int start= get_pos (hpos, b1->sx1(i)- hor_sep);
    int end  = get_pos (hpos, b1->sx2(i)+ hor_sep);
    if (end>n) end= n;
    for (j=start; j<end; j++)
      vpos1[j]= min (vpos1[j], y);
  }
  for (i=0; i<N(b2); i++) {
    SI  y    = b2->sy2(i);
    int start= get_pos (hpos, b2->sx1(i)- hor_sep);
    int end  = get_pos (hpos, b2->sx2(i)+ hor_sep);
    if (end>n) end= n;
    for (j=start; j<end; j++)
      vpos2[j]= max (vpos2[j], y);
  }

  SI m= vpos2[0]-vpos1[0];
  for (i=1; i<n; i++)
    m= max (m, vpos2[i]-vpos1[i]);
  return m;
}

Here is the call graph for this function:

Here is the caller graph for this function:

box typeset_as_stack ( edit_env  env,
tree  t,
path  ip 
)

Definition at line 344 of file stacker.cpp.

                                                 {
  // cout << "Typeset as stack " << t << "\n";
  int i, n= N(t);
  stacker sss= tm_new<stacker_rep> ();
  SI sep       = env->get_length (PAR_SEP);
  SI hor_sep   = env->get_length (PAR_HOR_SEP);
  SI ver_sep   = env->get_length (PAR_VER_SEP);
  SI height    = env->as_length (string ("1fn"))+ sep;
  SI bot       = 0;
  SI top       = env->fn->yx;
  sss->set_env_vars (height, sep, hor_sep, ver_sep, bot, top);
  for (i=0; i<n; i++)
    sss->print (typeset_as_concat (env, t[i], descend (ip, i)));

  n= N(sss->l);
  array<box> lines_bx (n);
  array<SI>  lines_ht (n);
  for (i=0; i<n; i++) {
    page_item item= copy (sss->l[i]);
    lines_bx[i]= item->b;
    lines_ht[i]= item->spc->def;
  }

  tm_delete (sss);
  box b= stack_box (ip, lines_bx, lines_ht);
  SI dy= n==0? 0: b[0]->y2;
  return move_box (ip, stack_box (ip, lines_bx, lines_ht), 0, dy);
}

Here is the call graph for this function:

Here is the caller graph for this function: