However, it must provide for the <listing> and <code> tags which display text 'as is'. This may mean that text will have to be right-chopped. In this case it must provide for horizontal scrolling. This is also necessary for wide images when they will not fit completely within the current window width.
Or do I (2) map only what is currently to be displayed? Then I can make the image as wide as the widest line within the field of display. The biggest problem here is scrolling backwards. How do I determine where the beginning of the previous line is in the file? Here, display speed could be a problem. However, it will require far less disk space to accommodate files.
Since I may need to store lots of HTML and GIF files on the disk, it is sensible to adopt choice (2). The program will therefore need the following.
When a given HTML file is first displayed, FP1 remains at the start of the file while FP1 is advanced. As it advances, the HTML tags it encounters are expedited and the text is displayed. This continues until the window is full.
With <listing> and <code> tags, text flow may be interrupted as follows. As the window's right margin is reached at the end of each line of text, display is suppressed, but scanning of the text is continued until the full virtual galley width has been reached.
To move backwards is more difficult. First scan backwards from FP1 until enough text or graphics image has been re-abstracted to produce the previous complete line. The start of this line is the new FP1. The old value of FP1 having been put in FP3. FP2 is then moved back to the beginning of the previous line. It is therefore a good idea also to keep the next-to-last line pointer in FP4 for this purpose.
Another approach would be to scan the whole HTML file before it is displayed to find the positions of the beginning of each displayable line within the HTML file. These would have to be re-computed if the window were re-sized. However, a resizing event does not occur anywhere nearly as often as a scrolling event. Therefore, this could save a lot of time and complication for the scrolling operation. An array of file pointers FP[] could be defined into which the places where the displayable lines start in the HTML file are put during a pre-display scan of the whole file.
HTML files tend to be short as text files go. They are usually no more than a page of A4 - about 64 occupied lines. An array FP[1024] would comfortably accommodate files of 16 pages - about a chapter. However, this could be a dynamic array which is allocated at the time the file is scanned. I think this is the best approach.
Scrolling now becomes much simpler. The program simply moves up or down the array as required. It then abstracts the new line from the HTML file. It then copies the screen contents (pixel-by-pixel) up or down the by the number of pixels equivalent to 1 line of text. Finally, it lays in the new line. So to progress one line along the HTML file (ie down the page), the process is as shown below.

And to progress one line backwards along the HTML file (ie up the page), the process is as shown below.

There is also a need to be able to advance one whole window full at a time. This is done as follows:

The number of lines per window-full, n, varies with the current window height and with the point-size of the current font.. It must therefore be re-calculated whenever either of these is changed (which isn't very often). The pointers p1 and p2 are pointers to file-pointers. The base pointer p is also a pointer to a file-pointer and points to the start of the dynamic array of file pointers. To advance along the HTML file by one window-full, proceed as follows.
p1 += n; p2 += n; //increment the two pointers by n lines.Then, starting at point *p1 (ie from the byte position within the HTML file stream held in the array element pointed to by p1) in the HTML file, display the interpreted contents of the file. To go back, proceed as before except decrement p1 and p2 viz.
p1 -= n; p2 -= n; //decrement the two pointers by n lines.
What is the best way of expressing the positions of hyper-text within a window? The first consideration is that the test to see if the mouse pointer is within a hot-spot must be kept as fast and as simple as possible. It has to be done every time the mouse moves. The hot-spots must therefore be expressed in a form as close to mouse co-ordinates as possible. At the very least they should be in window-relative pixels. For each item of hyper-text you need to store the diagonal co-ordinates of the pixel box containing it, together with the URL with which it is associated.

struct hyperlink { //define a hyperlink data structure
int y1; //Y-co-ordinate of top left of hot-box
int y2; //Y-co-ordinate of bottom right of hot-box
int x1; //X-co-ordinate of top right of hot box
int x2; //X-co-ordinate of bottom right of hot box
FILE *url; //file pointer to stream containing its URL
}
*HL[256]; /*declare an array of pointers to
hyperlink structures */
A 256-element array of pointers to structures of this type is declared. For the time being it will be presumed to be global (ie declared as being outside all functions. I think that an upper limit of 256 hyperlinks per screen is more than adequate. Memory for each structure will be allocated using malloc() each time a hyper-link is encountered when a new window full of text/graphics is displayed.
FILE *HyperCheck //check whether or not mouse is over hyper-text
(
int x, //pixel x-co-ordinate of mouse within window
int y, //pixel y-co-ordinate of mouse within window
int k //number of hyper-links currently on screen
) {
struct hyperlink *p; //pointer to a hyperlink structure
FILE *f = NULL; //pointer to the hyper-link URL
for(p = HL; k > 0; k--, p++) {
if(y > *p->y1 && y < *p->y2 && x > *p->x1 && x < *p->x2)
if(cursor == arrow) {
[change mouse cursor from an arrow to a hand];
f = *p->url; //set hyper-link pointer to URL
}
else if(cursor == hand) {
[change mouse cursor from hand to arrow];
}
}
return(f); //return pointer to hyper-link URL
}
The hyper-text pointed to by the mouse, if any, has a corresponding URL stored within the HTML file. The function returns a file pointer which points to the text of the URL within the HTML file. If the mouse is not currently pointing at any hyper-text it returns a NULL file pointer.