void tex::package(int c) { scal d; scal h; ptr p; d = box_max_depth; unsave(); save_ptr -= 3; if (mode == -HMODE) { cur_box = hpack(link(head), saved(2), saved(1)); } else { cur_box = vpackage(link(head), saved(2), saved(1), d); if (c == VTOP_CODE) { h = 0; p = list_ptr(cur_box); if (p != null && type(p) <= RULE_NODE) h = box_height(p); box_depth(cur_box) += box_height(cur_box) - h; box_height(cur_box) = h; } } pop_nest(); box_end(saved(0)); }
ptr tex::prune_page_top(ptr p) { mcell m; ptr prev_p; ptr q, s, t; t = (ptr)&m; prev_p = t; link(t) = p; while (p != null) { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: q = new_skip_param(SPLIT_TOP_SKIP_CODE); link(prev_p) = q; link(q) = p; s = glue_ptr(q); if (glue_width(s) > box_height(p)) { glue_width(s) -= box_height(p); } else { glue_width(s) = 0; } p = null; break; case WHATSIT_NODE: case MARK_NODE: case INS_NODE: prev_p = p; p = link(p); break; case GLUE_NODE: case KERN_NODE: case PENALTY_NODE: q = p; p = link(p); link(q) = null; link(prev_p) = p; flush_node_list(q); break; default: confusion("pruning"); break; } } return (link(t)); }
static void draw_zerolines(t_psdata out, real x0, real y0, real w, int nmat, t_matrix mat[], t_psrec *psr) { real xx, yy, dy, xx00, yy00; int i, x, y; xx00 = x0-1.5; yy00 = y0-1.5; ps_linewidth(out, psr->zerolinewidth); for (i = 0; (i < nmat); i++) { dy = box_height(&(mat[i]), psr); /* mat[i].axis_x and _y were already set by draw_boxes */ if (psr->X.lineatzero) { ps_rgb(out, linecolors[psr->X.lineatzero]); for (x = 0; (x < mat[i].nx); x++) { xx = xx00+(x+0.7)*psr->xboxsize; /* draw lines whenever tick label almost zero (e.g. next trajectory) */ if (x != 0 && x < mat[i].nx-1 && abs(mat[i].axis_x[x]) < 0.1*abs(mat[i].axis_x[x+1]-mat[i].axis_x[x]) ) { ps_line (out, xx, yy00, xx, yy00+dy+2); } } } if (psr->Y.lineatzero) { ps_rgb(out, linecolors[psr->Y.lineatzero]); for (y = 0; (y < mat[i].ny); y++) { yy = yy00+(y+0.7)*psr->yboxsize; /* draw lines whenever tick label almost zero (e.g. next trajectory) */ if (y != 0 && y < mat[i].ny-1 && abs(mat[i].axis_y[y]) < 0.1*abs(mat[i].axis_y[y+1]-mat[i].axis_y[y]) ) { ps_line (out, xx00, yy, xx00+w+2, yy); } } } yy00 += box_height(&(mat[i]), psr)+box_dh(psr)+box_dh_top(IS_ONCE, psr); } }
tex::box_t::box_t() { type(this) = HLIST_NODE; subtype(this) = MIN_QUARTERWORD; box_width(this) = 0; box_depth(this) = 0; box_height(this) = 0; shift_amount(this) = 0; list_ptr(this) = 0; glue_sign(this) = NORMAL; glue_order(this) = NORMAL; glue_set(this) = 0.0; }
static void box_dim(int nmat,t_matrix mat[],t_matrix *mat2,t_psrec *psr, int elegend,bool bFrame, real *w,real *h,real *dw,real *dh) { int i,maxytick; real ww,hh,dww,dhh; hh=dww=dhh=0; maxytick=0; ww=0; for(i=0; (i<nmat); i++) { ww=max(ww,mat[i].nx*psr->xboxsize); hh+=box_height(&(mat[i]),psr); maxytick=max(maxytick,mat[i].nx); } if (bFrame) { if (mat[0].label_y[0]) dww+=2.0*(psr->Y.fontsize+DDD); if (psr->Y.major > 0) dww += psr->Y.majorticklen + DDD + psr->Y.tickfontsize*(log(maxytick)/log(10.0)); else if (psr->Y.minor > 0) dww+=psr->Y.minorticklen; if (mat[0].label_x[0]) dhh+=psr->X.fontsize+2*DDD; if (/* fool emacs auto-indent */ (elegend==elBoth && (mat[0].legend[0] || mat2[0].legend[0])) || (elegend==elFirst && mat[0].legend[0]) || (elegend==elSecond && mat2[0].legend[0]) ) dhh+=2*(psr->legfontsize*FUDGE+2*DDD); else dhh+=psr->legfontsize*FUDGE+2*DDD; if (psr->X.major > 0) dhh+=psr->X.tickfontsize*FUDGE+2*DDD+psr->X.majorticklen; else if (psr->X.minor > 0) dhh+=psr->X.minorticklen; hh+=(nmat-1)*box_dh(psr); hh+=box_dh_top(TRUE,psr); if (nmat>1) hh+=(nmat-1)*box_dh_top(FALSE,psr); } *w=ww; *h=hh; *dw=dww; *dh=dhh; }
bool tex::insert_box(ptr p) { bool wait; ptr q, r, t; int n; q = link(page_ins_head); while (subtype(q) != subtype(p)) q = link(q); if (best_ins_ptr(q) == null) return TRUE; wait = FALSE; r = last_ins_ptr(q); link(r) = ins_ptr(p); if (best_ins_ptr(q) == p) { if (type(q) == SPLIT_UP && broken_ins(q) == p && broken_ptr(q) != null) { while (link(r) != broken_ptr(q)) r = link(r); link(r) = null; split_top_skip = split_top_ptr(p); ins_ptr(p) = prune_page_top(broken_ptr(q)); if (ins_ptr(p) != null) { t = vpack(ins_ptr(p), 0, ADDITIONAL); ins_height(p) = box_height(t) + box_depth(t); free_node(t, BOX_NODE_SIZE); wait = TRUE; } } best_ins_ptr(q) = null; n = subtype(q); t = list_ptr(box(n)); free_node(box(n), BOX_NODE_SIZE); box(n) = vpack(t, 0, ADDITIONAL); } else { while (link(r) != null) r = link(r); last_ins_ptr(q) = r; } return wait; }
void tex::append_to_vlist(ptr b) { scal d; ptr p; append_to_vlist_called=true; if (prev_depth > IGNORE_DEPTH) { d = glue_width(baseline_skip) - prev_depth - box_height(b); if (d < line_skip_limit) { p = new_param_glue(LINE_SKIP_CODE); } else { p = new_skip_param(BASELINE_SKIP_CODE); glue_width(glue_ptr(p)) = d; } tail_append(p); } tail_append(b); prev_depth = box_depth(b); }
void tex::show_box1(ptr p) { if (tex::type(p) == HLIST_NODE) print_esc("h"); else if (tex::type(p) == VLIST_NODE) print_esc("v"); else print_esc("unset"); print("box("); print_scaled(box_height(p)); print("+") ; print_scaled(box_depth(p)); print(")x") ; print_scaled(box_width(p)); if (tex::type(p) == UNSET_NODE) { if (unset_span_count(p) != MIN_QUARTERWORD) { print(" ("); print_int(unset_span_count(p)+1); print(" columns)"); } if (unset_stretch(p) != 0) { print(", stretch "); print_glue(unset_stretch(p), glue_order(p), null_str); } if (unset_shrink(p) != 0) { print(", shrink "); print_glue(unset_shrink(p), glue_sign(p), null_str); } } else { show_glue_set(p); if (shift_amount(p) != 0) { print(", shifted "); print_scaled(shift_amount(p)); } } node_list_display(list_ptr(p)); }
void ps_mat(char *outf,int nmat,t_matrix mat[],t_matrix mat2[], bool bFrame,bool bDiag,bool bFirstDiag, bool bTitle,bool bTitleOnce,bool bYonce,int elegend, real size,real boxx,real boxy,char *m2p,char *m2pout, int mapoffset) { char *libm2p; char buf[256],*legend; t_psdata out; t_psrec psrec,*psr; int W,H; int i,j,x,y,col,leg=0; real x0,y0,xx; real w,h,dw,dh; int nmap1=0,nmap2=0,leg_nmap; t_mapping *map1=NULL,*map2=NULL,*leg_map; bool bMap1,bNextMap1,bDiscrete; libm2p = m2p ? strdup(libfn(m2p)) : m2p; get_params(libm2p,m2pout,&psrec); psr=&psrec; if (psr->X.major <= 0 ) tick_spacing((mat[0].flags & MAT_SPATIAL_X) ? mat[0].nx + 1 : mat[0].nx, mat[0].axis_x, psr->X.offset, 'X', &(psr->X.major), &(psr->X.minor) ); if (psr->X.minor <= 0 ) psr->X.minor = psr->X.major / 2; if (psr->Y.major <= 0) tick_spacing((mat[0].flags & MAT_SPATIAL_Y) ? mat[0].ny + 1 : mat[0].ny, mat[0].axis_y, psr->Y.offset, 'Y', &(psr->Y.major), &(psr->Y.minor) ); if (psr->Y.minor <= 0) psr->Y.minor = psr->Y.major / 2; if (boxx>0) { psr->xboxsize=boxx; psr->yboxsize=boxx; } if (boxy>0) psr->yboxsize=boxy; if (psr->xboxsize==0) { psr->xboxsize = size/mat[0].nx; printf("Set the x-size of the box to %.3f\n",psr->xboxsize); } if (psr->yboxsize==0) { psr->yboxsize = size/mat[0].nx; printf("Set the y-size of the box to %.3f\n",psr->yboxsize); } nmap1=0; for (i=0; (i<nmat); i++) if (mat[i].nmap>nmap1) { nmap1=mat[i].nmap; map1=mat[i].map; leg=i+1; } if (leg!=1) printf("Selected legend of matrix # %d for display\n",leg); if (mat2) { nmap2=0; for (i=0; (i<nmat); i++) if (mat2[i].nmap>nmap2) { nmap2=mat2[i].nmap; map2=mat2[i].map; leg=i+1; } if (leg!=1) printf("Selected legend of matrix # %d for second display\n",leg); } if ( (mat[0].legend[0]==0) && psr->legend ) strcpy(mat[0].legend, psr->leglabel); bTitle = bTitle && mat[nmat-1].title[0]; bTitleOnce = bTitleOnce && mat[nmat-1].title[0]; psr->bTitle = bTitle; psr->bTitleOnce = bTitleOnce; psr->bYonce = bYonce; /* Set up size of box for nice colors */ box_dim(nmat,mat,mat2,psr,elegend,bFrame,&w,&h,&dw,&dh); /* Set up bounding box */ W=w+dw; H=h+dh; /* Start box at */ x0=dw; y0=dh; x = W+psr->xoffs; y = H+psr->yoffs; if (bFrame) { x += 5*DDD; y += 4*DDD; } out=ps_open(outf,0,0,x,y); ps_linewidth(out,psr->linewidth); ps_init_rgb_box(out,psr->xboxsize,psr->yboxsize); ps_init_rgb_nbox(out,psr->xboxsize,psr->yboxsize); ps_translate(out,psr->xoffs,psr->yoffs); if (bFrame) { ps_comment(out,"Here starts the BOX drawing"); draw_boxes(out,x0,y0,w,nmat,mat,psr); } for(i=0; (i<nmat); i++) { if (bTitle || (bTitleOnce && i==nmat-1) ) { /* Print title, if any */ ps_rgb(out,BLACK); ps_strfont(out,psr->titfont,psr->titfontsize); if (!mat2 || (strcmp(mat[i].title,mat2[i].title) == 0)) strcpy(buf,mat[i].title); else sprintf(buf,"%s / %s",mat[i].title,mat2[i].title); ps_ctext(out,x0+w/2,y0+box_height(&(mat[i]),psr)+psr->titfontsize, buf,eXCenter); } sprintf(buf,"Here starts the filling of box #%d",i); ps_comment(out,buf); for(x=0; (x<mat[i].nx); x++) { int nexty; int nextcol; xx=x0+x*psr->xboxsize; ps_moveto(out,xx,y0); y=0; bMap1 = (!mat2 || (x<y || (x==y && bFirstDiag))); if ((bDiag) || (x!=y)) col = mat[i].matrix[x][y]; else col = -1; for(nexty=1; (nexty<=mat[i].ny); nexty++) { bNextMap1 = (!mat2 || (x<nexty || (x==nexty && bFirstDiag))); /* TRUE: upper left -> map1 */ /* FALSE: lower right -> map2 */ if ((nexty==mat[i].ny) || (!bDiag && (x==nexty))) nextcol = -1; else nextcol=mat[i].matrix[x][nexty]; if ( (nexty==mat[i].ny) || (col!=nextcol) || (bMap1!=bNextMap1) ) { if (col >= 0) if (bMap1) ps_rgb_nbox(out,&(mat[i].map[col].rgb),nexty-y); else ps_rgb_nbox(out,&(mat2[i].map[col].rgb),nexty-y); else ps_moverel(out,0,psr->yboxsize); y=nexty; bMap1=bNextMap1; col=nextcol; } } } y0+=box_height(&(mat[i]),psr)+box_dh(psr)+box_dh_top(IS_ONCE,psr); } if (psr->X.lineatzero || psr->Y.lineatzero) { /* reset y0 for first box */ y0=dh; ps_comment(out,"Here starts the zero lines drawing"); draw_zerolines(out,x0,y0,w,nmat,mat,psr); } if (elegend!=elNone) { ps_comment(out,"Now it's legend time!"); ps_linewidth(out,psr->linewidth); if ( mat2==NULL || elegend!=elSecond ) { bDiscrete = mat[0].bDiscrete; legend = mat[0].legend; leg_nmap = nmap1; leg_map = map1; } else { bDiscrete = mat2[0].bDiscrete; legend = mat2[0].legend; leg_nmap = nmap2; leg_map = map2; } if (bDiscrete) leg_discrete(out,psr->legfontsize,DDD,legend, psr->legfontsize,psr->legfont,leg_nmap,leg_map); else { if ( elegend!=elBoth ) leg_continuous(out,x0+w/2,w/2,DDD,legend, psr->legfontsize,psr->legfont,leg_nmap,leg_map, mapoffset); else leg_bicontinuous(out,x0+w/2,w,DDD,mat[0].legend,mat2[0].legend, psr->legfontsize,psr->legfont,nmap1,map1,nmap2,map2); } ps_comment(out,"Were there, dude"); } ps_close(out); }
static void draw_boxes(t_psdata ps,real x0,real y0,real w, int nmat,t_matrix mat[],t_psrec *psr) { char buf[12]; char *mylab; real xxx; char **xtick,**ytick; real xx,yy,dy,xx00,yy00,offset_x,offset_y; int i,j,x,y,ntx,nty,strlength; /* Only necessary when there will be no y-labels */ strlength = 0; /* Draw the box */ ps_rgb(ps,BLACK); ps_linewidth(ps,psr->boxlinewidth); yy00=y0; for(i=0; (i<nmat); i++) { dy=box_height(&(mat[i]),psr); ps_box(ps,x0-1,yy00-1,x0+w+1,yy00+dy+1); yy00+=dy+box_dh(psr)+box_dh_top(IS_ONCE,psr); } /* Draw the ticks on the axes */ ps_linewidth(ps,psr->ticklinewidth); xx00=x0-1; yy00=y0-1; for (i=0; (i<nmat); i++) { if (mat[i].flags & MAT_SPATIAL_X) { ntx = mat[i].nx + 1; offset_x = 0.1; } else { ntx = mat[i].nx; offset_x = 0.6; } if (mat[i].flags & MAT_SPATIAL_Y) { nty = mat[i].ny + 1; offset_y = 0.1; } else { nty = mat[i].ny; offset_y = 0.6; } snew(xtick,ntx); for(j=0; (j<ntx); j++) { sprintf(buf,"%g",mat[i].axis_x[j]); xtick[j]=strdup(buf); } ps_strfont(ps,psr->X.tickfont,psr->X.tickfontsize); for(x=0; (x<ntx); x++) { xx = xx00 + (x + offset_x)*psr->xboxsize; if ( ( bRmod(mat[i].axis_x[x], psr->X.offset, psr->X.major) || (psr->X.first && (x==0))) && ( (i == 0) || box_do_all_x_maj_ticks(psr) ) ) { /* Longer tick marks */ ps_line (ps,xx,yy00,xx,yy00-psr->X.majorticklen); /* Plot label on lowest graph only */ if (i == 0) ps_ctext(ps,xx, yy00-DDD-psr->X.majorticklen-psr->X.tickfontsize*0.8, xtick[x],eXCenter); } else if ( bRmod(mat[i].axis_x[x], psr->X.offset, psr->X.minor) && ( (i == 0) || box_do_all_x_min_ticks(psr) ) ){ /* Shorter tick marks */ ps_line(ps,xx,yy00,xx,yy00-psr->X.minorticklen); } else if ( bRmod(mat[i].axis_x[x], psr->X.offset, psr->X.major) ) { /* Even shorter marks, only each X.major */ ps_line(ps,xx,yy00,xx,yy00-(psr->boxspacing/2)); } } ps_strfont(ps,psr->Y.tickfont,psr->Y.tickfontsize); snew(ytick,nty); for(j=0; (j<nty); j++) { sprintf(buf,"%g",mat[i].axis_y[j]); ytick[j]=strdup(buf); } for(y=0; (y<nty); y++) { yy = yy00 + (y + offset_y)*psr->yboxsize; if ( bRmod(mat[i].axis_y[y], psr->Y.offset, psr->Y.major) || (psr->Y.first && (y==0))) { /* Major ticks */ strlength=max(strlength,(int)strlen(ytick[y])); ps_line (ps,xx00,yy,xx00-psr->Y.majorticklen,yy); ps_ctext(ps,xx00-psr->Y.majorticklen-DDD, yy-psr->Y.tickfontsize/3.0,ytick[y],eXRight); } else if ( bRmod(mat[i].axis_y[y], psr->Y.offset, psr->Y.minor) ) { /* Minor ticks */ ps_line(ps,xx00,yy,xx00-psr->Y.minorticklen,yy); } } sfree(xtick); sfree(ytick); /* Label on Y-axis */ if (!psr->bYonce || i==nmat/2) { if (strlen(psr->Y.label) > 0) mylab = psr->Y.label; else mylab = mat[i].label_y; if (strlen(mylab) > 0) { ps_strfont(ps,psr->Y.font,psr->Y.fontsize); ps_flip(ps,TRUE); xxx=x0-psr->X.majorticklen-psr->X.tickfontsize*strlength-DDD; ps_ctext(ps,yy00+box_height(&mat[i],psr)/2.0,612.5-xxx, mylab,eXCenter); ps_flip(ps,FALSE); } } yy00+=box_height(&(mat[i]),psr)+box_dh(psr)+box_dh_top(IS_ONCE,psr); } /* Label on X-axis */ if (strlen(psr->X.label) > 0) mylab = psr->X.label; else mylab = mat[0].label_x; if (strlen(mylab) > 0) { ps_strfont(ps,psr->X.font,psr->X.fontsize); ps_ctext(ps,x0+w/2,y0-DDD-psr->X.majorticklen-psr->X.tickfontsize*FUDGE- psr->X.fontsize,mylab,eXCenter); } }
void assemble_timederivative( DeviceType const & device, viennashe::config const & conf, SHEQuantity const & quan, SHEQuantity const & quan_old, MatrixType & A, VectorType & b, ElementType const & elem, std::size_t index_H, CouplingMatrixType const & identity_matrix, QuantityPotential const & quan_pot, QuantityPotentialOld const & quan_pot_old) { (void)quan_pot; (void)quan_pot_old; //avoid unused parameter warnings typedef typename viennagrid::result_of::point<typename DeviceType::mesh_type>::type PointType; const double rtime = (conf.time_step_size() > 0.0) ? 1.0 / conf.time_step_size() : 0.0; const bool with_full_newton = (conf.nonlinear_solver().id() == viennashe::solvers::nonlinear_solver_ids::newton_nonlinear_solver); if (rtime == 0.0) return; //stationary const long row_index = quan.get_unknown_index(elem, index_H); if (row_index < 0) return; //no unknown here bool odd_assembly = detail::is_odd_assembly(elem, viennagrid::cells(device.mesh())[0]); //if (odd_assembly) // return; viennashe::math::harmonics_iteration_type harmonics_it_id = (odd_assembly ? viennashe::math::ODD_HARMONICS_ITERATION_ID : viennashe::math::EVEN_HARMONICS_ITERATION_ID); if (! with_full_newton ) { const long expansion_order = static_cast<long>(quan.get_expansion_order(elem, index_H)); double box_volume = viennagrid::volume(elem); if (odd_assembly) box_volume *= detail::cell_connection_length(device.mesh(), elem, viennagrid::cells(device.mesh())[0]) / PointType::dim; //const double Z = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), elem, index_H); // // Assemble the df/dH term: \pm q * dphi/dt * f(H_{n \pm 1}, t_{k+1}) // /* const double dphi = detail::potential_difference_to_old_timestep(elem, quan_pot, quan_pot_old); // new - old const double q = viennashe::physics::constants::q; const viennashe::carrier_type_id carrier_id = quan.get_carrier_type_id(); const double polarity = (carrier_id == ELECTRON_TYPE_ID) ? -1.0 : 1.0; const long col_index_minus = quan.get_unknown_index(elem, index_H - 1); if (col_index_minus >= 0 ) { double Z_lower = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), elem, index_H - 1); // from box integration const double coeff = polarity * Z_lower * box_volume; viennashe::util::add_block_matrix(A, row_index, col_index_minus, - 0.5 * q * coeff * dphi * rtime , identity_matrix, viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id), viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id) ); } const long col_index_plus = quan.get_unknown_index(elem, index_H + 1); if (col_index_plus >= 0 ) { double Z_upper = averaged_density_of_states(quan, conf.dispersion_relation(quan.get_carrier_type_id()), elem, index_H + 1); const double coeff = polarity * Z_upper * box_volume; viennashe::util::add_block_matrix(A, row_index, col_index_plus, + 0.5 * q * coeff * dphi * rtime , identity_matrix, viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id), viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id) ); } */ // // df/dt term // const double height = box_height(quan, elem, index_H); const double coeff = height * box_volume; viennashe::util::add_block_matrix(A, std::size_t(row_index), std::size_t(row_index), coeff * rtime, identity_matrix, viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id), viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id) ); viennashe::util::subtract_folded_block_vector(b, std::size_t(row_index), -coeff * rtime, identity_matrix, viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id), viennashe::math::spherical_harmonics_iterator(expansion_order, harmonics_it_id), quan_old.get_values(elem,index_H)); } else if (with_full_newton) { log::warning() << "* simulator(): !! WARNING !! Time dependence is not available for Newton iterations! Skipping df/dt " << std::endl; } }
void tex::build_page () { int pi=0, b, c; ptr p, q, r; #define INF_SHRINK_PAGE "Infinite glue shrinkage found on current page" if (link(contrib_head) == null || output_active) return; do { p = link(contrib_head); if (last_glue != null) delete_glue_ref(last_glue); last_penalty = 0; last_kern = 0; if (type(p) == GLUE_NODE) { last_glue = glue_ptr(p); add_glue_ref(last_glue); } else { last_glue = null; if (type(p) == PENALTY_NODE) { last_penalty = penalty(p); } else if (type(p) == KERN_NODE) { last_kern = kern_width(p); } } switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: if (page_contents < BOX_THERE) { if (page_contents == EMPTY) { freeze_page_specs(BOX_THERE); } else { page_contents = BOX_THERE; } q = new_skip_param(TOP_SKIP_CODE); link(q) = p; link(contrib_head) = q; r = glue_ptr(q); if (glue_width(r) > box_height(p)) { glue_width(r) -= box_height(p); } else { glue_width(r) = 0; } continue; } else { page_total += page_depth + box_height(p); page_depth = box_depth(p); goto contribute; } case GLUE_NODE: if (page_contents < BOX_THERE) { goto done; } else if (precedes_break(page_tail)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (page_contents < BOX_THERE) { goto done; } else if (link(p) == null) { return; } else if (type(link(p)) == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: if (page_contents < BOX_THERE) { goto done; } else { pi = penalty(p); } break; case WHATSIT_NODE: goto contribute; case MARK_NODE: goto contribute; case INS_NODE: insert_page(p); goto contribute; default: confusion("page"); break; } if (pi < INF_PENALTY) { b = page_badness(); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { c = pi; } else if (b < INF_BAD) { c = b + pi + insert_penalties; } else { c = DEPLORABLE; } } else { c = b; } if (insert_penalties >= 10000) c = AWFUL_BAD; if (tracing_pages > 0) show_page_stats(b, pi, c); if (c <= least_page_cost) { best_page_break = p; best_size = page_goal; least_page_cost = c; r = link(page_ins_head); while (r != page_ins_head) { best_ins_ptr(r) = last_ins_ptr(r); r = link(r); } } if (c == AWFUL_BAD || pi <= EJECT_PENALTY) { fire_up(p); if (output_active) return; continue; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto contribute; } update_heights: if (type(p) == KERN_NODE) { page_total += page_depth + kern_width(p); } else { q = glue_ptr(p); page_so_far[2 + stretch_order(q)] += stretch(q); page_shrink += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_PAGE); help_inf_shrink_page(); error(); r = new_spec(q); shrink_order(r) = NORMAL; delete_glue_ref(q); q = glue_ptr(p) = r; } page_total += page_depth + glue_width(q); } page_depth = 0; contribute: if (page_depth > page_max_depth) { page_total = page_total + page_depth - page_max_depth; page_depth = page_max_depth; } page_tail = link(page_tail) = p; link(contrib_head) = link(p); link(p) = null; continue; done: link(contrib_head) = link(p); link(p) = null; flush_node_list(p); } while (link(contrib_head) != null); if (nest_ptr == nest) { tail = contrib_head; } else { contrib_tail = contrib_head; } }
ptr tex::vert_break(ptr p, scal h, scal d) { int b; ptr q; ptr r; int t; int pi=0; ptr prev_p; scal prev_dp; ptr best_place=0; int least_cost; #define INF_SHRINK_BOX "Infinite glue shrinkage found in box being split" prev_p = p; least_cost = AWFUL_BAD; do_all_six(set_height_zero); prev_dp = 0; loop { if (p == null) { pi = EJECT_PENALTY; } else { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: cur_height += prev_dp + box_height(p); prev_dp = box_depth(p); goto not_found; case WHATSIT_NODE: goto not_found; case GLUE_NODE: if (precedes_break(prev_p)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (link(p) == null) { t = PENALTY_NODE; } else { t = type(link(p)); } if (t == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: pi = penalty(p); break; case MARK_NODE: case INS_NODE: goto not_found; default: confusion("vertbreak"); } } if (pi < INF_PENALTY) { b = vert_badness(h); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { b = pi; } else if (b < INF_BAD) { b += pi; } else { b = DEPLORABLE; } } if (b <= least_cost) { best_place = p; least_cost = b; best_height_plus_depth = cur_height + prev_dp; } if (b == AWFUL_BAD || pi <= EJECT_PENALTY) { return best_place; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto not_found; } update_heights: if (type(p) == KERN_NODE) { cur_height += prev_dp + kern_width(p); } else { q = glue_ptr(p); active_height[2 + stretch_order(q)] += stretch(q); active_height[6] += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_BOX); help_inf_shrink_box(); error(); r = new_spec(q); delete_glue_ref(q); shrink_order(r) = NORMAL; glue_ptr(p) = r; } cur_height += prev_dp + glue_width(q); } prev_dp = 0; not_found: if (prev_dp > d) { cur_height = cur_height + prev_dp - d; prev_dp = d; } prev_p = p; p = link(prev_p); } }
void tex::insert_page(ptr p) { int n; ptr q, r; scal h, w; scal delta; if (page_contents == EMPTY) freeze_page_specs(INSERTS_ONLY); n = subtype(p); r = page_ins_head; while (n >= subtype(link(r))) r = link(r); if (subtype(r) != n) { q = new_node(PAGE_INS_NODE_SIZE); link(q) = link(r); r = link(r) = q; subtype(r) = n; type(r) = INSERTING; ensure_vbox(n); page_ins_height(r) = (box(n) == null) ? 0 : box_height(box(n)) + box_depth(box(n)); best_ins_ptr(r) = null; q = skip(n); if (count(n) == 1000) h = page_ins_height(r); else h = x_over_n(page_ins_height(r), 1000) * count(n); page_goal -= h + glue_width(q); page_so_far[2 + stretch_order(q)] += stretch(q); page_shrink += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err("Infinite glue shrinkage inserted from "); print_esc("skip"); print_int(n); help_inf_shrink_ins(); error(); } } if (type(r) == SPLIT_UP) { insert_penalties += float_cost(p); return; } last_ins_ptr(r) = p; delta = page_goal - page_total - page_depth + page_shrink; if (count(n) == 1000) { h = ins_height(p); } else { h = x_over_n(ins_height(p), 1000) * count(n); } if ((h <= 0 || h <= delta) && ins_height(p) + page_ins_height(r) <= dimen(n)) { page_goal -= h; page_ins_height(r) += ins_height(p); } else { if (count(n) <= 0) { w = MAX_DIMEN; } else { w = page_goal - page_total - page_depth; if (count(n) != 1000) { w = x_over_n(w, count(n)) * 1000; } } if (w > dimen(n) - page_ins_height(r)) { w = dimen(n) - page_ins_height(r); } q = vert_break(ins_ptr(p), w, ins_depth(p)); page_ins_height(r) += best_height_plus_depth; if (tracing_pages > 0) show_split(n, w, q); if (count(n) != 1000) { best_height_plus_depth = x_over_n(best_height_plus_depth, 1000) * count(n); } page_goal -= best_height_plus_depth; type(r) = SPLIT_UP; broken_ptr(r) = q; broken_ins(r) = p; if (q == null) { insert_penalties += EJECT_PENALTY; } else if (type(q) == PENALTY_NODE) { insert_penalties += penalty(q); } } }
void tex::handle_right_brace () { scal d; int f; ptr p; ptr q; switch (cur_group) { case SIMPLE_GROUP: unsave(); break; case BOTTOM_LEVEL: print_err("Too many }'s"); help_close_group(); error(); break; case SEMI_SIMPLE_GROUP: case MATH_SHIFT_GROUP: case MATH_LEFT_GROUP: extra_right_brace(); break; case HBOX_GROUP: package(0); break; case ADJUSTED_HBOX_GROUP: tex::adjust_tail = tex::adjust_head; package(0); break; case VBOX_GROUP: end_graf(); package(0); break; case VTOP_GROUP: end_graf(); package(VTOP_CODE); break; case INSERT_GROUP: end_graf(); q = split_top_skip; add_glue_ref(q); d = split_max_depth; f = floating_penalty; unsave(); decr(save_ptr); p = vpack(link(head), 0, ADDITIONAL); pop_nest(); if (saved(0) < 255) { tail_append(new_node(INS_NODE_SIZE)); type(tail) = INS_NODE; subtype(tail) = saved(0); ins_height(tail) = box_height(p) + box_depth(p); ins_ptr(tail) = list_ptr(p); split_top_ptr(tail) = q; ins_depth(tail) = d; float_cost(tail) = f; } else { tail_append(new_node(SMALL_NODE_SIZE)); type(tail) = ADJUST_NODE; subtype(tail) = 0; adjust_ptr(tail) = list_ptr(p); delete_glue_ref(q); } free_node(p, BOX_NODE_SIZE); if (nest_ptr == nest) build_page(); break; case OUTPUT_GROUP: if (loc != null || (token_type != OUTPUT_TEXT && token_type != BACKED_UP)) { print_err("Unbalanced output routine"); help_output_balance(); error(); do get_token(); while (loc != null); } end_token_list(); end_graf(); unsave(); output_active = FALSE; insert_penalties = 0; if (box(255) != null) { print_err("Output routine didn't use all of "); print_esc("box255"); help_output(); box_error(255); } if (tail != head) { link(page_tail) = link(head); page_tail = tail; } if (link(page_head) != null) { if (link(contrib_head) == null) contrib_tail = page_tail; link(page_tail) = link(contrib_head); link(contrib_head) = link(page_head); link(page_head) = null; page_tail = page_head; } pop_nest(); build_page(); break; case DISC_GROUP: build_discretionary(); break; case ALIGN_GROUP: back_input(); cur_tok = sym2tok(FROZEN_CR); print_err("Missing "); print_esc("cr"); print(" inserted"); help_align_cr(); ins_error(); break; case NO_ALIGN_GROUP: end_graf(); unsave(); align_peek(); break; case VCENTER_GROUP: end_graf(); unsave(); save_ptr -= 2; p = vpackage(link(head), saved(1), saved(0), MAX_DIMEN); pop_nest(); tail_append(new_noad()); type(tail) = VCENTER_NOAD; math_type(nucleus(tail)) = SUB_BOX; info(nucleus(tail)) = p; break; case MATH_CHOICE_GROUP: build_choices(); break; case MATH_GROUP: unsave(); decr(save_ptr); math_type(saved(0)) = SUB_MLIST; p = fin_mlist(null); math_link(saved(0)) = p; if (p != null) { if (link(p) == null) { if (type(p) == ORD_NOAD) { if (math_type(subscr(p)) == EMPTY && math_type(supscr(p)) == EMPTY) { mcopy(saved(0), nucleus(p)); free_node(p, NOAD_SIZE); } } else if (type(p) == ACCENT_NOAD && saved(0) == nucleus(tail) && type(tail) == ORD_NOAD) { q = head; while (link(q) != tail) q = link(q); link(q) = p; free_node(tail, NOAD_SIZE); tail = p; } } } break; default: confusion("rightbrace"); break; } }