oplineheight.c

Go to the documentation of this file.
00001 
00002 /*  $Id: oplineheight.c 355 2005-01-11 22:48:55Z andreradke $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 /*these routines support variable lineheight in opxxx.c*/
00029 
00030 #include "frontier.h"
00031 #include "standard.h"
00032 
00033 #include "ops.h"
00034 #include "opinternal.h"
00035 #include "oplineheight.h"
00036 #include "opdisplay.h"
00037 #include "wpengine.h"
00038 
00039 
00040 
00041 short opgetline1top (void) {
00042     
00043     /*
00044     return the number of pixels from top of outlinerect of hline1 as a negative number
00045     */
00046     
00047     register hdloutlinerecord ho = outlinedata;
00048     short line1linesabove = (**ho).line1linesabove;
00049     
00050     if (line1linesabove == 0)
00051         return (0);
00052     else
00053         return (-textvertinset - ((**ho).defaultlineheight * line1linesabove));
00054     } /*opgetline1top*/
00055 
00056 
00057 hdlheadrecord opgetlastvisiblenode (void) {
00058     
00059     hdloutlinerecord ho = outlinedata;
00060     hdlheadrecord nomad = (**ho).hline1;
00061     Rect r = (**ho).outlinerect;
00062     short vertpixels = r.bottom - r.top;
00063     hdlheadrecord hlastvisible;
00064     short ct = 0;
00065     
00066     ct += opgetline1top ();
00067     
00068     hlastvisible = nomad;
00069     
00070     while (true) {
00071         
00072         ct += opgetlineheight (nomad);
00073         
00074         if (ct > vertpixels)
00075             return (hlastvisible);
00076             
00077         hlastvisible = nomad;
00078         
00079         nomad = opgetnextexpanded (nomad);
00080         } /*while*/
00081     } /*opgetlastvisiblenode*/
00082 
00083 
00084 long opgetcurrentscreenlines (boolean flscrollwise) {
00085     
00086     /*
00087     return the number of lines currently showing in the window.
00088     
00089     6.0a12 dmb: added flscrollwise parameter. If true, return the number
00090     of scroll lines on the screen; otherwise return the number of headlines, 
00091     the original meaning if this function
00092     */
00093     
00094     hdloutlinerecord ho = outlinedata;
00095     hdlheadrecord nomad = (**ho).hline1, nextnomad;
00096     Rect r = (**ho).outlinerect;
00097     long vertpixels = r.bottom - r.top;
00098     short ctpixels = 0, ctlines = 0;
00099     
00100     ctpixels += opgetline1top ();
00101     
00102     if (flscrollwise)
00103         ctlines -= (**ho).line1linesabove;
00104     
00105     while (true) {
00106         
00107         ctpixels += opgetlineheight (nomad);
00108         
00109         if (ctpixels > vertpixels) {
00110         
00111             if (flscrollwise) { //need to count lines that do fit
00112             
00113                 ctpixels -= opgetlineheight (nomad); //undo the add
00114                 
00115                 ctlines += (vertpixels - ctpixels - textvertinset) / (**ho).defaultlineheight;
00116                 }
00117             
00118             return (ctlines);
00119             }
00120         
00121         if (flscrollwise)
00122             ctlines += opgetnodelinecount (nomad);
00123         else
00124             ctlines++;
00125         
00126         nextnomad = opgetnextexpanded (nomad);
00127         
00128         if (nextnomad == nomad) { //ran out of lines
00129         
00130             if (flscrollwise) // account for white space
00131                 ctlines += (vertpixels - ctpixels) / ((**ho).defaultlineheight + textvertinset);
00132             
00133             return (ctlines);
00134             }
00135             
00136         nomad = nextnomad;
00137         } /*while*/
00138     } /*opgetcurrentscreenlines*/
00139     
00140     
00141 long opsumprevlineheights (long lnum, short *heightthisline) {
00142     
00143     /*
00144     return the sum of the lineheights of all lines above this one.
00145     
00146     lnum is 0-based.
00147     
00148     6.0b2 dmb: work with negative lnums, with the same semantics (return
00149     a negative number)
00150     */
00151     
00152     hdloutlinerecord ho = outlinedata;
00153     hdlheadrecord nomad = (**ho).hline1;
00154     long sum = 0;
00155     long i;
00156     
00157     sum += opgetline1top ();
00158     
00159     if (lnum < 0) {
00160     
00161         for (i = 0; i > lnum; i--) { // at least once
00162             
00163             nomad = opbumpflatup (nomad, true);
00164             
00165             *heightthisline = opgetlineheight (nomad);
00166             
00167             sum -= *heightthisline;
00168             }
00169         }
00170     else {
00171     
00172         for (i = 0; i < lnum; i++) {
00173             
00174             sum += opgetlineheight (nomad);
00175             
00176             nomad = opbumpflatdown (nomad, !(**ho).flprinting); //6.0b4 dmb: can't opgetnextexpanded (nomad) when printing
00177             } /*while*/
00178         
00179         *heightthisline = opgetlineheight (nomad);
00180         }
00181     
00182     return (sum);
00183     } /*opsumprevlineheights*/
00184     
00185     
00186 long opsumalllineheights (void) {
00187     
00188     hdlheadrecord nomad = (**outlinedata).hsummit, nextnomad;
00189     long sum = 0;
00190     
00191     while (true) {
00192         
00193         sum += opgetlineheight (nomad);
00194         
00195         nextnomad = opgetnextexpanded (nomad);
00196         
00197         if (nextnomad == nomad)
00198             return (sum);
00199             
00200         nomad = nextnomad;
00201         } /*while*/
00202     } /*opsumalllineheights*/
00203     
00204     
00205 long opgetlinestoscrollupforvisi (hdlheadrecord hnode) {
00206     
00207     /*
00208     return the number of lines you have to scroll to make the node
00209     visible. assume the node lies off the bottom of the window.
00210     
00211     first we figure out how many pixels off we are (ctneeded).
00212     
00213     then we loop up from the first line until we equal or exceed
00214     that number.
00215     */
00216     
00217     hdloutlinerecord ho = outlinedata;
00218     hdlheadrecord nomad = (**ho).hline1;
00219     Rect r = (**ho).outlinerect;
00220     short vertpixels = r.bottom - r.top;
00221     long ctpixels = 0;
00222     long ctneeded = 0;
00223     long ctlines;
00224     long ctscroll;
00225     short lh;   
00226     
00227     ctpixels = opgetline1top (); //measure  from top of line1
00228     
00229     while (true) {
00230         
00231         lh = opgetlineheight (nomad);
00232         
00233         //if ((ctpixels + lh) > vertpixels) /*line doesn't fit, or completely fit*/
00234         //  ctneeded += lh;
00235             
00236         ctpixels += lh;
00237     
00238         if (nomad == hnode)
00239             break;
00240         
00241         nomad = opgetnextexpanded (nomad);
00242         } /*while*/
00243     
00244     ctneeded = ctpixels - vertpixels;
00245     
00246     if (ctneeded <= 0) /*it's already visible*/
00247         return (0);
00248         
00249     nomad = (**ho).hline1;
00250     
00251     ctpixels = opgetline1top ();
00252     
00253     ctscroll = -(**ho).line1linesabove;
00254     
00255     while (true) {
00256         
00257         lh = opgetlineheight (nomad);
00258         
00259         ctlines = opgetnodelinecount (nomad);
00260         
00261         ctpixels += lh;
00262         
00263         ctscroll += ctlines;
00264         
00265         if (ctpixels >= ctneeded) {
00266         
00267             if (ctpixels > ctneeded && ctlines > 1)
00268                 ctscroll -= (ctpixels - ctneeded) / (**ho).defaultlineheight;
00269             
00270             return (ctscroll);
00271             }
00272             
00273         nomad = opgetnextexpanded (nomad);
00274         }
00275     } /*opgetlinestoscrollupforvisi*/
00276 
00277 
00278 long opgetlinestoscrolldownforvisi (hdlheadrecord hnode) {
00279     
00280     /*
00281     return the number of lines you have to scroll to make the node
00282     visible. assume the node lies above the top of the window.
00283     
00284     we count the number of scroll lines above hline1, up to and including
00285     hnode
00286     
00287     6.0b2 dmb: account for text selection in headlines taller than the screen
00288     */
00289     
00290     hdloutlinerecord ho = outlinedata;
00291     hdlheadrecord nomad = (**ho).hline1;
00292     hdlheadrecord hsummit = (**ho).hsummit;
00293     long defaultlineheight = (**ho).defaultlineheight;
00294     long ctscroll = 0;
00295     long ctpixels = 0;
00296     Point ptsel;
00297     Rect r;
00298     
00299     if (!(nomad == hnode && opeditingtext (hnode))) {
00300         
00301         ctscroll = (**ho).line1linesabove; //first, bring hline1 to top of window
00302         
00303         ctpixels = -opgetline1top ();
00304         }
00305     
00306     while (true) {
00307         
00308         if (nomad == hsummit) //ran out, didn't find it
00309             break;
00310         
00311         if (nomad == hnode)
00312             break;
00313         
00314         nomad = opbumpflatup (nomad, true);
00315         
00316         ctscroll += opgetnodelinecount (nomad);
00317         
00318         ctpixels += opgetlineheight (nomad);
00319         }
00320     
00321     if (opeditingtext (hnode)) { // see if hnode has to scroll above the top of the window
00322         
00323         opeditgetselpoint (&ptsel);
00324         
00325         ptsel.v += ctpixels;
00326         
00327         r = (**ho).outlinerect;
00328         
00329         if (ptsel.v < r.top)
00330             ctscroll += divup (r.top - ptsel.v, defaultlineheight);
00331         
00332         else {
00333             
00334             ptsel.v += defaultlineheight;
00335             
00336             if (ptsel.v > r.bottom)
00337                 ctscroll -= divup (ptsel.v - r.bottom, defaultlineheight);
00338             }
00339         }
00340     
00341     return (ctscroll);
00342     } /*opgetlinestoscrolldownforvisi*/

Generated on Wed May 31 18:19:57 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6