Back to index

texmacs  1.0.7.15
make_pages.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : make_pages.cpp
00004 * DESCRIPTION: Control routines for typesetting paragraphs
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "Format/page_item.hpp"
00013 #include "Format/stack_border.hpp"
00014 #include "pager.hpp"
00015 box format_stack (path ip, array<box> bx, array<space> ht, SI height,
00016                 bool may_stretch);
00017 #include "Boxes/construct.hpp"
00018 array<page_item> sub (array<page_item> l, path p, path q);
00019 SI stretch_space (space spc, double stretch);
00020 page_item access (array<page_item> l, path p);
00021 skeleton break_pages (array<page_item> l, space ph, int qual,
00022                     space fn_sep, space fnote_sep, space float_sep, font fn);
00023 box page_box (path ip, box b, tree page, SI width, SI height, SI left, SI top,
00024              SI bot, box header, box footer, SI head_sep, SI foot_sep);
00025 
00026 box
00027 pager_rep::pages_format (array<page_item> l, SI ht, SI tcor, SI bcor) {
00028   // cout << "Formatting insertion of height " << ht << LF;
00029   ht -= (tcor + bcor);
00030   int i, n= N(l);
00031   array<box>   bs;
00032   array<space> spc;
00033   for (i=0; i<n; i++) {
00034     page_item item= l[i];
00035     if (item->type == PAGE_CONTROL_ITEM) {
00036       if (is_tuple (item->t, "env_page")) {
00037        if (((item->t[1] == PAGE_THIS_HEADER) ||
00038             (item->t[1] == PAGE_THIS_FOOTER)) &&
00039            (item->t[2] == "")) style (item->t[1]->label)= " ";
00040        else if (item->t[1] == PAGE_NR)
00041          page_offset= as_int (item->t[2]->label)- N(pages)- 1;
00042        else style (item->t[1]->label)= copy (item->t[2]);
00043       }
00044     }
00045     else {
00046       bs  << item->b;
00047       spc << item->spc;
00048     }
00049   }
00050   ASSERT (N(bs) != 0, "zero lines in insertion");
00051   box b= format_stack (ip, bs, spc, ht, true);
00052   return vcorrect_box (b->ip, b, tcor, bcor);
00053 }
00054 
00055 box
00056 pager_rep::pages_format (insertion ins) {
00057   if (is_tuple (ins->type, "multi-column")) {
00058     // cout << "Format multicolumn " << ins->sk << LF << LF << INDENT;
00059     int col, nr_cols= N (ins->sk), real_nr_cols= as_int (ins->type[1]);
00060     SI w= (text_width + col_sep) / real_nr_cols;
00061     array<box> bs (nr_cols);
00062     array<SI>  x  (nr_cols);
00063     array<SI>  y  (nr_cols);
00064     for (col=0; col<nr_cols; col++) {
00065       bs[col]= pages_format (ins->sk[col]);
00066       x [col]= col * w;
00067       y [col]= 0;
00068     }
00069     // cout << UNINDENT << "Formatted multicolumn" << LF;
00070     return scatter_box (ip, bs, x, y);
00071   }
00072   else {
00073     array<page_item> sub_l= sub (l, ins->begin, ins->end);
00074     SI ht= stretch_space (ins->ht, ins->stretch);
00075     return pages_format (sub_l, ht, ins->top_cor, ins->bot_cor);
00076   }
00077 }
00078 
00079 box
00080 pager_rep::pages_format (pagelet pg) {
00081   // cout << "Formatting pagelet " << (N(pages)+1)
00082   //      << " stretch " << pg->stretch
00083   //      << " height " << stretch_space (pg->ht, pg->stretch) << LF << INDENT;
00084   if (N (pg->ins) == 0) {
00085     if (N(pages) == 0) return empty_box (ip);
00086     return empty_box (pages[N(pages)-1]->find_rip());
00087   }
00088   else if (N (pg->ins) == 1) {
00089     insertion ins= pg->ins[0];
00090     // cout << ins << " stretch " << ins->stretch
00091     //      << " height " << stretch_space (ins->ht, ins->stretch) << LF;
00092     //      << UNINDENT << "Formatted pagelet " << (N(pages)+1) << LF << LF;
00093     return pages_format (ins);
00094   }
00095   else {
00096     int i, n= N(pg->ins);
00097     array<box> bs (n);
00098     array<SI>  bx (n);
00099     array<SI>  by (n);
00100     SI y= 0, fnote_y= MAX_SI;
00101     for (i=0; i<n; i++) {
00102       insertion ins= pg->ins[i];
00103       // cout << ins << " at " << y << " stretch " << ins->stretch
00104       //      << " height " << stretch_space (ins->ht, ins->stretch) << LF;
00105       bs[i]= pages_format (ins);
00106       bx[i]= 0;
00107       by[i]= y;
00108       y -= bs[i]->h();
00109       if (i < n-1) {
00110        insertion next= pg->ins[i+1];
00111        if (ins->type != next->type) {
00112          if (is_tuple (next->type, "footnote")) {
00113            // cout << "sep " << stretch_space (fnote_sep, ins->stretch) << LF;
00114            y -= stretch_space (fnote_sep, ins->stretch);
00115            fnote_y= y;
00116          }
00117          else if (is_tuple (ins->type, "float")) {
00118            if (!is_tuple (next->type, "float")) {
00119              // cout << "sep " << stretch_space(float_sep, ins->stretch) << LF;
00120              y -= stretch_space (float_sep, ins->stretch);
00121            }
00122          }
00123          else if (is_tuple (ins->type, "multi-column") ||
00124                  is_tuple (next->type, "multi-column")) {
00125            page_item item= access (l, path_dec (ins->end));
00126            // cout << "sep " << stretch_space (item->spc, ins->stretch) << LF;
00127            y -= stretch_space (item->spc, ins->stretch);
00128          }
00129        }
00130        if (is_tuple (ins->type, "footnote"))
00131          if (is_tuple (next->type, "footnote")) {
00132            page_item item= access (l, path_dec (ins->end));
00133            SI sep= stretch_space (item->spc + fn_sep, ins->stretch);
00134            // cout << "sep " << sep << LF;
00135            y -= sep;
00136          }
00137        if (is_tuple (next->type, "float")) {
00138          // cout << "sep " << stretch_space (float_sep, ins->stretch) << LF;
00139          y -= stretch_space (float_sep, ins->stretch);
00140        }
00141       }
00142     }
00143     if (fnote_y != MAX_SI) {
00144       bs << line_box (decorate(), 0, 0, fnote_bl, 0, env->fn->wline, env->col);
00145       bx << 0;
00146       by << (fnote_y + env->fn->sep);
00147     }
00148     // cout << UNINDENT << "Formatted pagelet " << (N(pages)+1) << LF << LF;
00149     return scatter_box (ip, bs, bx, by);
00150   }
00151 }
00152 
00153 box
00154 pager_rep::pages_make_page (pagelet pg) {
00155   box sb= pages_format (pg);
00156   box lb= move_box (ip, sb, 0, 0);
00157   SI  left= (N(pages)&1)==0? odd: even;
00158   env->write (PAGE_NR, as_string (N(pages)+1+page_offset));
00159   env->write (PAGE_THE_PAGE, style[PAGE_THE_PAGE]);
00160   tree page_t= env->exec (compound (PAGE_THE_PAGE));
00161   box header= make_header (N (pg->ins) == 0);
00162   box footer= make_footer (N (pg->ins) == 0);
00163   return page_box (ip, lb, page_t,
00164                  width, height, left, top, top+ text_height,
00165                  header, footer, head_sep, foot_sep);
00166 }
00167 
00168 void
00169 pager_rep::pages_make () {
00170   space ht (text_height- may_shrink, text_height, text_height+ may_extend);
00171   skeleton sk=
00172     break_pages (l, ht, quality, fn_sep, fnote_sep, float_sep, env->fn);
00173   int i, n= N(sk);
00174   for (i=0; i<n; i++)
00175     pages << pages_make_page (sk[i]);
00176 }
00177 
00178 void
00179 pager_rep::papyrus_make () {
00180   space ht (MAX_SI >> 1);
00181   skeleton sk=
00182     break_pages (l, ht, quality, fn_sep, fnote_sep, float_sep, env->fn);
00183   if (N(sk) != 1) {
00184     cerr << "Number of pages: " << N(sk) << "\n";
00185     FAILED ("unexpected situation");
00186   }
00187 
00188   box sb= pages_format (sk[0]);
00189   box b = move_box (ip, sb, 0, 0);
00190   SI left  = (odd+even) >> 1;
00191   SI height= top + bot + b->h();
00192   array<box> bs   (1); bs   [0]= b;
00193   array<SI>  bs_x (1); bs_x [0]= left;
00194   array<SI>  bs_y (1); bs_y [0]= -top;
00195   box pb= page_box (ip, "?", width, height,
00196                   bs, bs_x, bs_y, 0, 0, 0);
00197   pages << pb;
00198 }