SYSTEM FOR CONVERTING SCROLLING DISPLAY TO NON-SCROLLING COLUMNAR DISPLAY

Abstract: A computer system for automatically converting a scrollable electronic document, including text, graphics, tables and combinations, from a scrollable format to a non-scrollable format, the system comprising a page-forming mechanism configured to operatively and automatically arrange the scrollable electronic information document into a plurality of non-scrollable pages, each having one or more columns wherein each of the columns has a width corresponding to a number of characters per line within a predetermined range of characters per line, a content formatter mechanism configured to be operatively responsive to embedded formatting commands, either common word-processing commands or html commands or both; a font-sizing mechanism configured to operatively permit a user to selectively alter the size of the characters comprising the non-scrollable pages; an image sizing mechanism configured either to automatically alter the widths of graphic images and tables in the electronic document to proportionately conform to the width of the columns, or to reduce the graphic images and tables to selectively expandable icons positioned in the display; a screen having a display window configured to entirely display a selected one of the non-scrollable pages; and a page-turning mechanism configured to selectively, sequentially and individually display the plurality of non-scrollable pages in the display window. A method is provided for practicing the system.

Description: SYSTEM FOR CONVERTING SCROLLING DISPLAY TO NON-SCROLLING COLUMNAR DISPLAY BACKGROUND OF THR INVENTION 1. Field of the Invention. This invention relates generally to a display control system and, more particularly without limitation, to a system for controlling the display on the screen of a computer monitor for the purpose of reducing eye strain of, and increasing readability for, a user 2. Description of the Related Art, Reading has never been a particularly natural task for the human eye, but scanning text on a computer screen appears to be especially more effortful than it is on a printed page While the popular view of this phenomenon is that text on computers causes eye strain, it is more likely that text viewing generally increases the cognitive load on the user in a variety of ways One of the main factors that may contribute to difficulty reading text on a computer screen has to do with document length A common solution used to display long documents is to scroll the screen to bring more of the mateπal mto view Prior art employs two scrolling strategies screen-by- screen, line-by-line The problem is that, however efficient these scrolling strategies are from an engineering standpoint, they may actually make the reading task more difficult for the user The relevant issues encompass three key aspects of readability, namely readmg speed, reading comprehension, and readmg ease, each of which can be observed and measured as viewer performance vanables Content complexity can be considered a control vaπable, and should be used to distinguish effects among the three performance vanables bearing on readability Users employ two strategies to move down through a long document, either to advance screen-by-screen or hne-by-lrne, neither one of which is conducive to natural reading Scrolling screen-by-screen is disruptive to the reading experience because it causes users to lose their place, forcing them to free cognitive resources away from text comprehension in order to reorient the eye in the proper location in the text The other option is to scroll ne- by-line, ensurmg that only previously viewed matenal is removed from view, not new matenal However, this imposes a control task on the reader that similarly drams cognitive resources away from the primary task of text comprehension Such strain is due m part to the sudden and repetitive vertical shifting of screen contents and the natural attempt by the human visual system to follow such apparent motions It may also be due in part to a reduction of blinking, since the flicker caused by scrolling spoofs physical blinking Continuous scrolling, by more or less constant vertical motion of screen contents, likewise subjects the viewer to strain due to finer, but more frequent, vertical steps and flicker Furthermore, contmuous scrolling rarely achieves real freedom from the distraction of display control, reading speed normally vanes with content complexity, which may change substantially both within and between documents Thus, in choosmg any of the commonly available scrolling strategies for consuming substantial readmg matenal on-screen, the readability of the matenal is normally compromised This happens either by disruptions m information flow, by distractions from the task of consummg and comprehendmg mformation, or by additional eye stress and fatigue Fatigue may even foreshorten the consumption of significant amounts of readable material and affect comprehension Another problem with using a computer monitor for consummg readable material is that lines of text generally span from near one side of the monitor to the other This may require substantial lateral eye movement for every lme of text, which can cause user fatigue Upon completion of reading one lme of test, the human visual system generally retraces the lme to find the beginning of the subsequent line of text If the lme of text is too long relative to its height, retrace enors can occur, disrupting the flow of information similarly to the incomplete scrolling problem previously descπbed Thus, readability is agam compromised m reading ease and reading speed domams Pnor art attempts to resolve this particular problem generally introduces either reduced-width columns or multiple columns of mateπal on-screen Reduced width columns are certainly more readable, having shorter lmes that are more easily retraced However, reduced width columns also result m more scrolling, smce the area required to present the matenal is more or less fixed, and reducing the width merely mcreases the depth needed to be reached by scrolling Multiple columns of material may also result m reduced column width However, the typical presentation layout principle is to form columns with a sufficient depth to reach the bottom of the prmtable page, and is primarily suited for off-screen consumption Alternatively, a presentation layout principle for on-screen consumption is to more or less balance the depth of the columns In this case, the scrolling task is even greater, the viewer must scroll to the bottom of a column and then scroll completely back to the top of the subsequent column Thus, these prior art attempts to manage column widths may actually result in additional losses to readability Another common problem is the use of inappropriate type fonts m presentmg material on-screen The publisher may make use of rather small fonts, which can crowd more mformation onto the screen at once, thereby reducing the amount of scrolling required for complete consumption of the presented mformation This strategy generally results m additional eye strain, due to squinting or straining to read uncomfortably small print, and due to increased retrace errors caused by long narrow lmes of text Agam, readability is compromised The significance of type fonts as bearing on readability is dependent on individual viewers (visual acuity) and on their environment (external lighting and monitor quality) Individual response to eye strain, as caused by small fonts or repetitive vertical scrolling, may mvoke symptoms of optokmetic nystagmus, which is an involuntary eye reflex further enhanced by eye strain, which may also negatively affect readmg performance Nystagmus may arise regardless of font selection, however, due to eye strain induced by scrolling alone The viewmg environment issues (external lighting and momtor quality) may be considered noise factors m measuring readability, requiring controlled experimentation and statistical analysis The mtent of the publisher of the document is, presumably, to present information appropnately by predetermined font selections Due to individual viewer preferences and environment factors, such intentions may well result in a higher rate of eye strain and reduced readability than normally considered or assumed Prior art often permits the viewer to adjust the sιze(s) of the type font used to render the document onscreen The effort to discover and use methods to modify font size may discourage their use More significantly, the presentation layout principles incorporated in the prior art are often inadequate to desirably fulfill viewer requirements to improve readability through font size modification As an example, consider the implementation of multiple columns for a recent release of a web browser, the number of columns is prescribed by the web page author and cannot be modified by the viewer. As the viewer ovemdes the publisher's font selections m order to significantly enlarge font sizes for his own particular situation, the quality of the layout can be compromised. For instance, lines of text can easily contam too few characters, with large gaps for words that might preferably be hyphenated. In addition, there is a disproportionate increase m the rate of retracmg and the amount of requisite scrolling. All this results m a substantial reduction in readability. Similarly, when a person engages m readmg a lengthy publication, a natural tendency is to settle back in the chair for comfort When readmg pnnted mateπal, this is generally a well-supported activity; unless the publication itself is too heavy, the readmg distance is easily mamtamed For on-screen consumption of mformation, however, readmg distance is not easily maintained even with laptop computers Viewers could clearly benefit by simply increasing font sizes in proportion to the increased reading distances afforded by more comfortable sitting positions However, the practical difficulties in accomplishing this simple goal with prior art are quite apparently rather significant. Font size modifications by the viewer, m and of themselves, are generally madequate to enhance readability usmg the prior art. Thus, what is needed is a system for enhancing the readability of on-screen presentations of mformation Such a system would eliminate the need for scrolling It would also limit the lme widths of readable text to a useful range It would also allow the viewer to easily modify font size and apply better presentation layout principles to preserve and enhance on-screen consumption of mformation. SUMMARY OF THE INVENTION An unproved system is provided for on-screen publishing of documents, including combmations of text, graphics, and tables, to the consumer. The key features of this system include- precluding the use of window scrolling, to accommodate mformation too extensive to be displayed at one time, through the use of page-turning techniques, conforming this information to multiple columns to enhance readability; and integrating, m the multiple column layout on the on-screen presentation, font resizing operations conducted by the mformation consumer. More specifically, an improved computer system is provided for automatically converting a scrollable electronic document, mcludmg text, graphics, tables and combmations thereof, from a scrollable format to a non- scrollable format, the system comprising a page-forming mechanism configured to operatively and automatically aπange the scrollable electronic mformation document mto a plurality of non-scrollable pages, each having one or more columns wherein each of the columns has a width corresponding to a number of characters per lme within a predetermined range of characters per lme; a screen havmg a display wmdow configured to simultaneously display a selected one of the plurality of non-scrollable pages m its entirety; and a page-turning mechanism configured to selectively, sequentially and individually display the plurality of non-scrollable pages m the display wmdow. The page-forming mechanism may mclude a content formatter mechanism that is configured to be operatively responsive to formatting commands, either common word-processmg commands or html commands or both, embedded m the electronic document The page-forming mechanism includes a font-sizing mechanism configured to operatively permit a user to selectively alter the size of the characters compnsmg the non-scrollable pages. Also, the system includes an image sizing mechanism configured either to automatically alter the widths of graphic images and tables m the electronic document to proportionately conform to the width of the one or more columns, or to reduce the graphic images and tables to selectively expandable icons positioned m the displayed document Briefly, a first described embodiment of the present invention is configured to manipulate text utilizing common word-processing commands and graphics images embedded m a source document, whereas a modified embodiment thereof is configured to additionally manipulate tables and utilize html commands embedded m the source document A method is provided for practicmg the invention PRINCIPAL OBJECTS AND ADVANTAGES OF THE INVENTION The principal objects and advantages of the present invention mclude. providing a system and method for eliminating scrolling while viewmg lengthy mateπal on a momtor; providing such a system and method that establishes a maximum line width for text intended to be read by a user, providing such a system and method for permittmg a user to selectively enlarge information printed in small fonts such that the mateπal can be easily read while the user sits at a comfortable viewing distance from the monitor, providing such a system and method for automatically recalculating the number of displayed columns in response to a user change in size of displayed font, providmg such a system and method for automatically reformatting displayed mateπal m response to a user change m size of displayed font, providmg such a system and method for automatically resizing graphics images embedded m a source document to fit within a column; providmg such a system and method for automatically converting graphics images embedded m a source document to an icon or object image that is selectively expandable and reconvertable to the ongmally tended image; providmg such a system and method for automatically resizing tables embedded in a source document to fit within a column; providmg such a system and method for automatically converting tables embedded m a source document to an icon or object image that is selectively expandable and reconvertable to the ongmally mtended table display; and generally providmg such a system and method that is efficient m operation, reliable m performance, capable of long operatmg life, and is particularly well adapted for the proposed usage thereof. Other objects and advantages of the present invention will become apparent from the following descnption taken m conjunction with the accompanymg drawings, which constitute a part of this specification and wherem are set forth exemplary embodiments of the present invention to illustrate various objects and features thereof. BRTEF DESCRIPTION OF THE DRAWINGS Fig. 1 is a schematic representation of a display control system for converting a scrollable computer display to a non-scrollable columnar computer display, accordmg to the present mvention. Fig. 2 is a more detailed schematic representation of the display control system. Fig. 3 is a schematic representation of an application of the display control system, accordmg to the present mvention. Fig. 4 is a schematic representation of a modified embodiment of the display control system, accordmg to the present mvention. Fig 5 is a more detailed schematic representation of the modified embodiment of the display control system Fig. 6 is a schematic representation of an application of the modified embodiment of the display control system, accordmg to the present invention DETAILED DESCRIPTION OF THE INVENTION As required, detailed embodiments of the present mvention are disclosed herein, however, it is to be understood that the disclosed embodiments are merely exemplary of the mvention, which may be embodied in various forms Therefore, specific structural and functional details disclosed herem are not to be interpreted as limiting, but merely as a basis for the claims and as a representative basis for teachmg one skilled m the art to variously employ the present mvention in virtually any appropriately detailed structure The reference numeral 1 generally refers to a display control system in accordance with the present mvention, as shown m Figs 1 through 3 The system 1 generally compπses a screen 3, a page-forming mechanism 5, a resizing mechanism 7, a screen-printing mechanism 13, and paging means such as m the form of a page-turning mechanism 15 It is to be understood that the system 1 mcludes vaπous software algoπthms, commonly known to persons skilled m the programming art, which, in combination with each other and with various devices and components, also known to those havmg skill in the computer hardware and software arts, provide the various objectives and benefits of the present mvention, as heremafter descπbed A printout of the computer source code for realizing the objects and advantages of the system 1 is heremafter disclosed as Section A, beginning on page 15 hereof The screen 3 generally includes a display wmdow 17, wherein the display wmdow 17 may mclude the entire viewmg area of the screen 3 or may mclude only a smaller, selected portion of the available viewmg area of the screen 3, as suggested m Fig 1 It is to be understood that the screen 3 may be the displayable component of a cathode ray tube type of momtor, or may be any other type of monitor used for displaying mformation electronically First formatting means, such as m the form of a screen page formatting mechanism 23 of the page-forming mechanism 5, is configured to form a screen page 27 dimensioned to fit within the viewmg area of the display wmdow 17 and to thereby limit the quantity of electronic mformation available for printing to the screen 3 to only enough electronic information which will fit within the viewmg area of the display wmdow 17 In other words, the amount of information available for the screen 3 at any given time can be wπtten m its entirety within the display wmdow 17, as heremafter descπbed The screen page formatting mechamsm 23 is configured to automatically determine the manner in which electronic information, sometimes referred to herem as source document 33, will be displayed m the display wmdow 17 The screen page formatting mechanism 23 automatically determines the display capabilities available within the display wmdow 17, such as number of pixels compπsmg a horizontal line of the display wmdow 17, for example Generally, the system is preset to utilize a user-selected font, such as Times New Roman for example, and a user-selected font size, such as 12- or 14-poιnt type or other desirable font size, sometimes referred to herein as the "base font", wherem the cunent base font is the font currently selected by the user for presentation of the document It is to be understood that the font size is further adjustable m size by the user as heremafter descπbed The screen page formatting mechamsm 23 mcludes column determining means, such as m the form of a column formatting mechamsm 35, that, after first determining the maximum number of columns 37 havmg certain desired width characteπstics, is configured to automatically format the screen page 27 mto that maximum number of columns 37 The system 1 also mcludes a font-sizmg mechanism 43, which allows the user to selectively increase the size of the selected font by progressively mouse-clicking on a designated font-size enlargmg button 45, or to selectively decrease the size of the selected font by progressively mouse-clicking on a corresponding font-size reducing button 47 In addition, the system 1 may also be configured to enlarge the font size by keypressmg the "up arrow button" 49 of a keyboard 50 of the system 1, and reduce the font size by keypressmg the "down arrow button" 51 of the keyboard 50 Alternately or additionally, the system 1 may include a font-size pull-down menu 53 or other suitable arrangement wherein a particular size of font may be directly selected without havmg to progressively enlarge or progressively reduce the font size with the font-size enlargmg and reducing buttons 45 and 47 Of course, any change in the size of the font may alter the maximum number of the columns 37 that can be displayed m the display wmdow 17 while retammg desired width charactenstics for the columns 37 As a result and m response to a change m the font size, the screen page formatting mechanism 23 is configured to automatically recalculate the new maximum number of the columns 37 havmg the desired width characteristics that is displayable m the display wmdow 17, and the column formatting mechanism 35 is configured to automatically reformat the screen page 27 accordmgly Examples of computer code to implement the font changmg means of the present mvention mclude interpreting activation of the font size enlarging and reducmg buttons 45, 47 as change-font-size changmg commands shown m Section A, beginning at page 19, lme 13, mterpretmg "up" and "down" anow key presses of a keyboard of the computer system 4 as change-font-size commands shown m Section A, beginning at page 19, lme 19, respondmg to user commands to step font size up or down shown m Section A, beginning at page 21, lme 9, incrementing the base font size up or down by one mdex value shown m Section A, begmnmg at page 20, line 27, and setting base and footer fonts accordmg to new cunent font size mdex shown m Section A, begmnmg at page 21, lme 11 Second formatting means, such as in the form of a display page formatting mechanism 25 of the page- forming mechamsm 5, mcludes a source resizing mechanism 63 configured to automatically enlarge or reduce, as appropπate, the size of the font of all text of the source document 33 to conform to the size of font selected by the font-sizmg mechanism 43, as herembefore descπbed The display page formatting mechanism 25 is further configured to automatically divide the scrollable source document 33 mto a segmented display document 55, each segment 57 compπsmg one of a plurality of sequential display pages 57, each of which display pages 57 compπses only enough mateπal from the source document 33 to partially or totally fill each of the columns 37 of the screen page 27, as suggested by the portions designated by the numerals 59, 60, 61 m Fig 2, as an example wherem the screen page 27 is formatted mto three of the columns 37 The display page formatting mechanism 25 may also be configured to be responsive to certain in-line commands in the source document 33, such as paragraph mdent, word wrap, and other common word-processmg commands provided by popular word processing programs It is to be understood that formatting and segmentmg of the display document 55 may or may not be a separate operation but, instead, may be conducted concuπenfly with the printing of a selected one of the display pages 57 to the screen page 27, with the system 1 automatically tracking which portions 59, 60, 61 is cunently prmted or bemg pnnted to the display screen 17, and which portions conespond to each of the other display pages 57 It is also to be understood that when the font-sizmg mechanism 43 is activated to alter the font size as herembefore described, not only does the screen page formatting mechanism 23 automatically recalculate the physical width of the columns 37 to thereby mamtam the desired number of characters per lme within a desired range of characters per lme and also automatically reformat the new number of columns 37 mto the screen page 27, the display page formatting mechanism 25 also automatically redetermmes the specific text 59, 60, 61 of the source document 33 to be displayed in each of the columns 37 of each of the display pages 57 In other words, the display page formatting mechamsm 25 re-segments the display document 55 mto a new set of sequential display pages 57 until reaching the end of the text or graphics elements of the source document 33 Again, each newly reformatted display page 57 contains only enough material to partially or totally fill the newly formatted columns 37 of the screen page 27, including allowing for a newly determined number of the columns 37 resulting from the change in font size implemented by the font-sizing mechanism 43 The source resizing mechanism 63 may also mclude resizing means, such as in the form of an image resizing mechanism 65, configured to automatically recognize and resize graphic images contamed in the source document 33 The image resizing mechanism 65 may be adapted to reduce the width of the graphic images to conespond to the width of the columns 37 m the screen page 27 Alternately, the source resizing mechanism 63 may mclude icon formmg means wherem the image resizing mechanism 65 may be configured to convert each of the graphic images contamed m the source document 33 to a respective icon 75 and displaying each of the icons 75 m close proximity to text m the display document 55 that was positioned near the respective graphic image the source document 33 In that event, the source resizing mechanism 63 mcludes expandmg means wherem the image resizing mechanism 65 is configured to automatically expand a selected graphic image to its ongmally mtended display size by a simple command, such as mouse-clicking the respective icon 75 for example Displaying means, such as m the form of the screen printing mechanism 13, is configured to print a selected one of the display pages 57 to the screen page 27 by methods commonly known m the related art The page-turning mechanism 15 is configured to individually and sequentially, either forwardly or backwardly, page through the display pages 57 such that all mformation of the source document 33 is selectively cycled, without scrolling, mto the user's view on the screen 3, a display page 57 at time In other words, the page turning mechamsm 15 is adapted to replace a currently displayed display page 57 with any previous or subsequent display page 57 of the display document 55 m response to a user request to display any such previous or subsequent display page 57 By this aπangement, the system 1 eliminates the need to scroll information displayed in the display wmdow 17 smce the display area required to display the information contamed m any selected display page 57 does not exceed the display area provided by the columns 37 of the screen page 27 In an application of the present mvention, the screen page formatting mechanism 23 automatically determines the display capability of the display wmdow 17 in which the mformation contamed m the source document 33 is to be displayed If the entire viewable area of the screen 3 is to be used for the display wmdow 17, then the screen page formattmg mechanism 23 is configured to adapt the width and height characteristics of the screen page 27 to conform to the width and height characteristics of the viewable area of the screen 3 Similarly, if the user, employmg standard wmdow sizing and placement methods appropriate to the user's computer system, desires to specify a width for the display window 17 that is smaller than the viewable width of the screen 3 and/or a height for the display wmdow 17 that is smaller than the viewable height of the screen 3, then the screen page formattmg mechamsm 23 is configured to adapt the width and height characteristics of the screen page 27 to conform to the width and height characteristics of the user-desired display wmdow 17 By so limiting the dimensions of the screen page 27, scrolling of information pnnted to the display window 17 is eliminated smce the dimensions of the screen page 27 are fully disposed within the specified display window 17 It is to be understood that the user may also desire to place the display window 17 at a selected position on the screen 3, or from time to time change the location of the display window 17 on the screen 3 In that event, the screen printing mechamsm 13 is configured to operatively and conespondmgly position the screen page 27 at the same identical location of the display window 17 on the screen 3 If desired, a small area may be selectively reserved as a footer or information area 80 along one edge of the display area for displaying information not necessarily contamed m the source document 33 Of course, the representative portions 59, 60 and 61 must be adjusted accordingly Thus, the screen page 27 has been formatted to non-scrollably display electronic mformation, as schematically indicated by "FORMAT DISPLAY" 103 in Fig 3 An example of computer code for adjustmg the dimensions of the screen page 27 to account for any displayed footer area is shown in Section A, beginning at page 21, lme 16 Next, the screen page formatting mechamsm 23 of the system 1 is configured to automatically calculate the number of columns to compnse the screen page 27 by measuring the pixel width of the minimum standard line of text accordmg to the cunent base font By definition, a minimum standard lme of text is comprised of a set of characters meaningfully representmg the typical number of characters of text m a lme of text considered to be at the short limit for comfortable readmg Generally, such a set of characters comprises a predetermined number of identical characters, such as thirty characters, more or less, with the identical characters bemg the lower case "n" character, or other suitable character of similar width, such short limit bemg well-known m the typesetting industry The system 1 then divides the pixel width of the display wmdow 17 by the pixel width of the minimum standard lme of text to calculate a proposed column number, the number of columns 37 assigned to be automatically formatted mto the screen page 27 bemg either "one" or the proposed column number, whichever is greater The screen page formatting mechanism 23 then formats the screen page 27 as an anay of the columns 37, utilizing vanous appearance features known m the art, wherem the array of the columns 37 consists of the assigned number of the columns 37 generally have uniform width, height and separation in the screen page 27 An example of computer code for determining the number of the columns 27 for a standard range of characters per lme given the width of the display wmdow 17 is shown in Section A, begmnmg at page 25, lme 12 The system 1 is then ready to receive the source document 33, mcludmg graphics images, as schematically mdicated by "RECEIVE ELECTRONIC INFORMATION" 105 m Fig 3 The resizing mechamsm 63 then resizes all text of the source document 33 to the size of the base font, as schematically mdicated by "RESIZE TEXT" 107 m Fig 3 The system 1 resizes the text elements of the source document 33 by filling the columns 37 with text elements, printing the text to the display wmdow 17 usmg the base font and size while being responsive to m-lme formatting commands mcluded m the text of the source document 33, wherem the m-lme formatting commands may consist of a subset of HTML tags, a subset of document formattmg codes such as those provided by a word processor, or document layout specifications, breaking the lmes by hyphenating words that are too long to be pnnted withm the column width pursuant to the font metric imposed by the base font and m-lme formattmg rules of the system 1, or breaking the lmes on word boundaries m contiguous text elements, such as for paragraph and lme break mclusions, either directly mdicated by paragraph or break tags or mdirectly mdicated, such as by outlme inclusions Then, breakmg the lme filling at the end of individual text element segments, as indicated either by the mclusion of graphic elements, such as the icons 75, or by the end of the source document 33. Further, the image resizing mechamsm 65 converts graphics images of the source document 33 mto icons 75 or images havmg width dimensions not greater than the width of the columns formatted m the screen page 27, as schematically mdicated by "RESIZE GRAPHICS" 113 in Fig. 3. Resizing of a graphics image by the system 1 generally compπses. comparmg the actual width of the graphic image with the available width of the column 37. If the width dimension of the graphic image exceeds the width dimension of the column 37, the width of the graphic image is proportionately reduced to fit within the width of the column 37, the height also preferentially reduced by the same proportion; if the height dimension of the graphic image exceeds the height of the column 37 of the screen page 27, the height of the graphic image is proportionately reduced to fit within the height of the column of the screen page 27, the width also preferentially reduced by the same proportion The graphics image is then rendered as an m-lme graphic element and (l) placed immediately after any prior text elements m the cunent lme of the cunent column 37 of the display page 57, or (n) if the width of the graphics image exceeds the remaining width of the cunent lme of the cunent column 37 of the display page 57, placed immediately below the cunent lme of the cunent column 37 of the display page 57, or (in) if the height of the graphics image exceeds the remammg height of the cunent column 37 of the display page 57, placed m the next column 37 of the display page 57, or (iv) if the cunent column 37 is the last column 37 of the cunent display page 57, retamed for display m the first column 37 of the next succeedmg display page 57. An example of computer code for downloading the ongmal graphic images from a remote file, cachmg the graphic images, and returning the conespondmg image object or icon 75 is shown m Section A, begmnmg at page 16, lme 18. It is to be understood that resizing of the text font and/or resizing of the graphics images of the source document 33 may or may not be a separate operation but, mstead, may be conducted concunently with the prmtmg of a selected one of the display pages 57 to the screen page 27. Thus, the resized text, with the icons 75 appropπately positioned therein such that the text either stops above each of the icons 75 and contmues below each of the icons 75, or, if desired, wraps around each of the icons 75, is reformatted to essentially convert the source document 33 mto the display document 55 with a width of one of the columns 37. The display page formattmg mechanism 25 then equivalently segments the display document 55 mto a plurality of sequential display pages 57, as schematically mdicated by "SEGMENT ELECTRONIC INFORMATION INTO DISPLAY PAGES" 117 m Fig. 3. Then, a selected one of the plurality of screen pages 57 is pnnted, either concunently with the resizing or subsequently, to the display wmdow 17 by the screen-printing mechanism 77, as schematically mdicated by "SCREEN PRINT TEXT AND GRAPHICS OF SELECTED DISPLAY PAGE" 123 in Fig. 3. Smce the quantity of mformation from the source document 33 pnnted to the screen 3 at any given time is only enough to partially or totally fill the columns 37 of the screen page 27, need for scrolling m order to see all of the mformation pnnted to the screen 3 is eliminated by the present mvention An example of computer code for prmtmg a selected one of the display pages 57 to the display screen 17 using the cunent base font and the automatically calculated number of the columns 37 is shown in Section A, beginning at page 21, lme 33 Also, an example of computer code for resizing text and graphics images and prmtmg the cunent display page 57 line-by-line and word-by-word, hyphenating as needed, parsing tag-based formattmg instructions for text, resizing graphics images to fit withm column width, and returning end-of-tag mdices is shown m Section A, begmnmg at page 22, lme 23 If desired, the user may selectively change the size of certain feamres of the displayed material More specifically, one of the feamres selectively changeable by the user is the font size, as schematically indicated by "ALTER FONT SIZE" 125 in Fig 3 If font size is changed, the screen page formattmg mechamsm 23 would be activated to reformat the screen page 27, mcludmg recalculating the number of columns 37 to be included in such reformatting, and the display page formattmg mechanism 25 would be activated to develop a new segmented display document 55 conespondmg to the reformatted screen page 27, as herembefore descnbed Generally, altermg font size will cause the system 1 to automatically return to the display page 57 bemg prmted to the screen page 27 to the first one of the plurality of sequential display pages 57 Additionally, the icons 75 may be activated to expand the underlying graphics images to disclose or enlarge those features of the source document 33, as schematically mdicated by "ALTER GRAPHICS SIZE" 127 in Fig 3 Preferably, activatmg the icons 75 does not cause the system 1 to return to the first one of the plurality of sequential display pages 57 as when altermg the font size After viewmg the display page 57 bemg pnnted to the display wmdow 17, the user may proceed to the next sequential display page 57 or the immediately precedmg display page 57 as desired by activatmg the page- turning mechamsm 15, such as selectmg an appropnate pull-down menu, mouse-clicking a designated button, or other suitable anangement, as schematically mdicated by "SELECT NEW DISPLAY PAGE" 135 m Fig 3 As a result, a conespondmg one of the plurality of display pages 57 is pnnted to the screen page 27, as schematically mdicated by "SCREEN PRINT TEXT AND GRAPHICS OF NEWLY SELECTED PAGE" 137 m Fig 3 Agam, scrollmg of the mformation displayed m the display wmdow 17 is elimmated smce the display area required to display the mformation contamed m each display page 57 is not greater than the available display area provided by the columns 37 of the screen page 27 In other words, the system 1 may provide an expedited method for changmg font size while maintaining readability by maintaining a standard number of characters per line, as follows (l) changmg font size steps by acceptmg user mput for steppmg base font size up or down, keyboard mput (e g up or down anow keys), or graphical user interface "button" elements 45, 47, (n) limiting the range of base font sizes (e g , 8- pomt to 96-poιnt fonts), (in) limiting user input to defined range of font sizes, or (iv) modifymg the base font size Then, maintaining readability by (l) recalculating the number of columns 37 for the displayed font size usmg the newly cunent base font size as herembefore described for calculating the number of columns 37 for the displayed font size, (n) recomposing the screen page 27 m accordance with the recalculated number of columns 37 as herembefore described for composmg the screen page 27 as an anay of columns 34, and (in) resizing text and graphics m accordance with the recomposition of the screen page 27 as herembefore described for resizing of text elements and resizing of graphics images A modified embodiment of the display control system for converting a scrollable computer display to a non-scrollable columnar computer display, m accordance with the present mvention, is shown m Figs 4 through 6, and is generally designated herem by the numeral 201 A printout of the computer source code for realizing the objects and advantages of the modified embodiment 201 is heremafter disclosed as Section B, beginning on page 26 hereof. The primary difference between the modified embodiment 201 and the embodiment 1 previously described herem m the adaption of the present invention to support the extensive range of document formatting syntax possible with standard HTML, by utilizing numerous specialized methods for formattmg m accord therewith Many of the characteristics of the modified embodiment 201 are substantially similar to those of the previously described embodiment 1 and will not be reiterated here m detail The system 201 generally comprises a screen 203 of a computer system 204, a page-formmg mechamsm 205, a display sizing mechanism 207, and a page-turning mechanism 215. The page-formmg mechanism 205 mcludes a screen page formattmg mechamsm 223 and a display page formattmg mechanism 225. The screen page formattmg mechanism 223 is configured to form a screen page 27 dimensioned to fit within a display wmdow 217. The screen page formatting mechanism 223 is configured to automatically determine the manner in which a source document 233, will be displayed m the display wmdow 217 The screen page formattmg mechanism 223 includes a column formattmg mechanism 235 that, after first determmmg the maximum number of columns 237 havmg certain desired width charactenstics, is configured to automatically format the screen page 227 mto that maximum number of the columns 237. The system 201 also mcludes a font-sizmg mechanism 243, which allows the user to selectively mcrease the size of the selected font by progressively mouse-chckmg on a designated font-size enlargmg button 245, or to selectively decrease the size of the selected font by progressively mouse-chckmg on a conespondmg font-size reducmg button 247. In addition, the system 1 may also be configured to recognize a keypress of the "up anow button" 249 of a keyboard 250 of the system 201 as a command to enlarge the font size, and a keypress of the "down anow button" 251 of the keyboard 250 as a command to reduce the size of the font Alternately or additionally, the system 1 may mclude a font-size pull-down menu 253 or other suitable anangement wherem a particular size of font may be directly selected without havmg to progressively enlarge or progressively reduce the font size with the font-size enlargmg and reducmg buttons 245, 247, or the "up" and "down" anow keys 249, 251. In response to a change m the font size, the screen page formattmg mechanism 223 is configured to automatically recalculate the new maximum number of the columns 237 havmg the desired width characteristics that is displayable m the display wmdow 217, and the column formatting mechanism 235 is configured to automatically reformat the screen page 227 accordmgly Examples of computer code for determmmg the number of the columns for a standard range of characters per lme given the width of the display wmdow is shown in Section B, begmnmg at page 40, lme 35 and page 40, lme 36; for determmmg the minimum value of the width of the standard range of characters per line given the cunent base font size is shown m Section B, begmnmg at page 49, lme 18; for interpreting "up anow" and "down anow" key presses on the computer keyboard as change-font-size commands is shown in Section B, begmnmg at page 51, lme 18, for interpreting activation of font increasing and font decreasmg buttons as change-font-size commands is shown in Section B, begmnmg at page 50, lmes 24 and 29, for responding to user commands for stepping font size up or down is shown in Section B, begmnmg at page 41, lme 17 and page 51, lme 7, for incrementing base font size up or down by one index value is shown m Section B, begmnmg at page 49, line 27, and for setting base font size to a new mdex value withm certain font size limits is shown m Section B, beginning at page 49, line 1 The display page formatting mechamsm 225 mcludes a source resizing mechanism 263 configured to automatically enlarge or reduce, as appropriate, the size of the font of all text of the source document 233 to conform to the size of font selected by the font-sizmg mechanism 243, as hereinbefore described The display page formattmg mechamsm 225 is further configured to automatically divide the scrollable source document 233 into a segmented display document 255, each segment 257 thereof comprising one of a plurality of sequential display pages 257, each of which display pages 257 compπses only enough material from the source document 233 to partially or totally fill each of the columns 237 of the screen page 227, as suggested by the portions designated by the numerals 259, 260, 261 m Fig 5, as an example wherem the screen page 227 is formatted mto three of the columns 237 The display page formattmg mechamsm 225 may also mclude a content formatter mechamsm 262 that is configured to be operatively responsive to formatting commands embedded m the source document 233, such as text color, style, font, font size, table and form specifications, etc , as well as paragraph mdent, word wrap, and other common word-processing commands provided by popular word processmg programs The source resizing mechanism 263 may also mclude an image resizing mechanism 265 and a table resizing mechanism 267 configured to automatically recognize and resize graphic images and tables, respectively, contamed m the source document 233 The image and table resizing mechanisms 265, 267 may be adapted to reduce the width of the graphic images and the tables to conespond to the width of the columns 237 m the screen page 227 Alternately, the image and table resizing mechanisms 265, 267 may be configured to convert each of the graphic images and the tables contamed m the source document 233 to a respective icon 275 and displaying each of the icons 275 m close proximity to text m the display document 255 that was positioned near the respective graphic image or table m the source document 233 In that event, the image and table resizing mechanisms 265, 267 are configured to automatically expand a selected graphic image or table to its ongmally mtended display size by a simple command, such as mouse-chckmg the respective icon 275 for example Resizing of a table by the system 201 generally compπses the steps of rendering the table as an inline element and (l) placing the table unmediately after any prior text or graphic elements m the cunent lme of the cunent column 237 of the display page 257, or (n) if the prefened width of the table exceeds the remammg width of the cunent lme of the cunent column 237 of the display page 257, placing the table unmediately below the cunent lme m the cunent column 237 of the display page 257, or (m) if the minimum height of the table exceeds the remaming height of the cunent column 237 of the display page 257, placmg the table in the next column 237 of the display page 257, or (iv) if the cunent column 237 is the last column 237 of the cunent display page 257, retammg the table for display m the first column 237 of the next succeeding display page 257 Rendermg of the table by the system 201 comprises the steps of (1) creating a grid anay with an adequate number of rows and columns for the table specifications as determmed by the source document 233 or other reference data, and (n) filling the cells of the grid with the table entry data as specified by the source document 233 or other reference source, wherem the cells comprise resized text, graphics, and table elements adapted to the allocated dimensions of the cells The screen prmtmg mechanism 213 is configured to print a selected one of the display pages 57 to the screen page 227 Examples of computer code for prmtmg a selected one of the display pages to the display screen using the cunent base font and the automatically calculated number of the columns is shown in Section B, beginning at page 46, lines 11, 15 and 18, for adjusting the dimensions of the screen page to account for any footer area displayed is shown m Section B, beginning at page 49, lmes 9 and 11 , for resizing of text elements and printing the cunent display page to the display screen is shown in Section B, beginning at page 43, lme 39, for parsing html tag-based formattmg instructions for text, graphics and tables, and returning end-of-tag indices is shown in Section B, beginning at page 37, lme 24, for sendmg blocks of text to be drawn on the display wmdow includmg measunng text word-by- word, hyphenatmg as needed, adding words to be printed to a row of text and graphics, and returning a boolean when all words m the block of text have been handled is shown m Section B, begmnmg at page 36, lme 37, for sendmg words to be drawn of the display table mcludmg converting html character entities if any, addmg words to a cache for prmtmg a row of text and graphics, and determmmg the width of the word is shown in Section B, begmnmg at page 40, lme 17, for drawing lmes composed of text, graphics, and table elements including accountmg for heights, offsets and widths of all row elements, pnntmg each to the display screen, addmg Java components as required, and returning end-of-content mdices is shown m Section B, begmnmg at page 44, lme 32, for resizing graphics elements mcludmg downloading ongmal graphic images from file, caching images for future use, and returning image objects or icons is shown m Section B, begmnmg at page 57, lme 33, for accountmg for column width and height to determine image scale-down factor if any, and returning widths of rendered images is shown m Section B, begmnmg at page 57, lme 15, for rendermg table elements mcludmg prmtmg the table to the display screen is shown m Section B, beginning at page 64, line 15, for creatmg an anay of rows and columns accordmg to html table specifications is shown m Section B, begmnmg at page 63, lme 2, for resizing tables to fit column width and height limits, and returning end-of-tag indices is shown in Section B, beginning at page 59, lme 30, for setting base and footer fonts accordmg to a new size index is shown m Section B, begmnmg at page 48, lme 31 , and for setting base font color and metrics is shown in Section B, begmnmg at page 48, lmes 35 and 36 The page-turnmg mechanism 215 is configured to individually and sequentially, either forwardly or backwardly, page through the display pages 257 such that all mformation of the source document 233 is selectively cycled, without scrollmg, mto the user's view on the screen 203, a display page 257 at time In an application of the modified embodiment 201 of the present mvention, a user connects to a host html page of a client system, as schematically indicated by "HOST HTML PAGE INVOKED BY USER" 303 m Fig 6, and a selected document file, namely the source document 233, is downloaded therethrough as schematically indicated by "DOCUMENT FILE DOWNLOAD" 305 The system 201 is configured to parse the source document 233 and automatically determine the specialized Java class applets needed to render the source document 233 as schematically indicated by "FORMATTER CLASSES AS NEEDED" 307 The appropriate applet classes are then accessed by the system 201, either locally from the computer system 204 or downloaded through the html page, as schematically indicated by "APPLET CLASS DOWNLOAD" 313 The system 201 then, cooperatively with the downloaded applet classes, automatically formats the columns 237 as schematically indicated by "AUTOMATIC COLUMNS" 315, and automatically scales graphics images and tables to fit the columns 237 as schematically indicated by "IMAGES SCALED TO FIT COLUMNS" 317. The system 201 is configured to directly prmt a selected one of the display pages 255 to the columns 237 of the screen page 227 and, therefore, to the display screen 217, as mdicated schematically by "READER SCREEN" 323, to form an applet display as schematically mdicated by "APPLET DISPLAY" 325, or a combmation of the two The user may then selectively interact with the system 201 as schematically mdicated by "USER INTERACTIONS" 327, mcludmg making further connections through the html page as mdicated by "EXTERNAL HTML PAGE LINK" 333, selectively and individually viewing other display pages 257 of the display document 255 as schematically mdicated by "TURN PAGE AS NEEDED"335, and enlargmg a table or graphics image by mouse-clicking on the reduced display thereof or by mouse-chckmg on the conespondmg icon 275, as appropriate, as schematically mdicated by "ZOOM TABLE AS NEEDED" 337 and "ZOOM IMAGE AS NEEDED" 343 m Fig 6 Of course, after completion of the exercise, the user causes the system 201 to "CLOSE ALL WINDOWS" 245 Summarizing, the present mvention provides an expedited method for changing font size while maintaining readability by maintaining a standard number of characters per line, as follows (l) changmg font size steps by acceptmg user mput for stepping base font size up or down, keyboard mput (e.g up or down anow keys), or graphical user mterface "button" elements, (n) limiting the range of base font sizes (e.g , 8-poιnt to 96- pomt fonts), (m) limiting user mput to defined range of font sizes, or (iv) modifymg the base font size. Then, mamtammg readability by (l) recalculating the number of columns for the displayed font size usmg the newly cunent base font size as herembefore descπbed for calculating the number of columns based on the available display wmdow width and the selected display font size, (π) recomposmg the screen page m accordance with the recalculated number of columns as herembefore described for composmg the screen page as an anay of columns; and ( ) resizing text, graphics, and tables in accordance with the recomposition of the screen page as herembefore descπbed for resizing of text elements, resizing of graphics images, and resizing of tables In addition to the foregomg, other techniques may be used in combination therewith to further reduce eye stram of a user viewmg a monitor utilizmg the screen control display system. For example, background and desirable contrasting text, etc., colors may be selected mcludmg gray scales, as appropriate Simply stated, features provided by the present mvention mclude the ability to pull up text, a graphic image or a table mto its own separate wmdow with a smgle mouse click on the selected material, and the appearance of the electronic information on the screen is document dependent instead of the appearance being software dependent, which allows a viewer to control and mamtam the appearance of the document m a more readable form, regardless of how the author of the electronic information set up that document ongmally These features, m combmation, have the effect of reducing eye strain in on-momtor reading and viewing of text and graphics by measurably reducing optokmetic nystagmus and/or measurably reducmg eye squinting Section A. First Described Embodiment That Includes Manipulation of Text Utilizing Cnmmon Word- Processing Commands and Graphics Images Embedded in a Source Document. The following is a printout of computer source code for realizing the objects and advantages of the first described embodiment herem /* %W% %E% Everett Stoub Copyπght (c) '96-'97 ION Web Products, Inc All Rights Reserved ez_text applet displays snaking text with m-lme graphics and produces a reader screen frame when clicked */ X* * ^author Everett Stoub %I%, %G% */ import java awt *,ιmport java applet * .import java net *,ιmport java io *,ιmport ava util *, public class ez_text extends Applet {private final boolean formattedText = true, // if true, in-line graphics and pull quotes are enabled pπvate Strmg title = null, pπvate Strmg article = null,pπvate ezrpnlap panel = null.pπvate ezrfrmap frame = null, private MediaTracker tracker = null, private Vector lmageFileNames = null, // vector of all image file names for document pπvate Vector graphicsURLs = null, // vector of all graphic image URLs for document pπvate Vector graphicslmages = null, // vector of all graphic images for document pπvate final boolean frameOption = true, // set false for 1Kb code reduction private final mt NONE = 0, private final mt LINE = 1 , private final mt FLAT = 2, private final mt RAISED = 3 , private final lnfDROPPED = 4, pπvate final mt ETCHED = 5, private t frameType = NONE, private mt frameSize = 0, pnvate final String AG = '"", private final Strmg AM = "&", pπvate final Strmg SC = ",", private final Strmg SP = " ", private final Strmg PL = "<p", private final Strmg QL = "V", pπvate final Strmg PR = "<p>", private final Strmg QT = "quot", pnvate final Strmg alert_0 = "PLEASE READ - A Java ", private final String alert_l = "Exception has occuned ", private final Strmg alert_2 = "Most likely, there has been a transmission failure with one or more applet files A Refresh or Reload command on your browser will sometimes lead to a successful download ", private final Strmg alert_3 = "An attempt to read a local file has been detected' In order to read this article, you must download the applet usmg hyper-text transport protocols (http // ) from a web server Please try again using http with a valid URL ", private final String alert_4 = "If the problem persists, please contact the Web Master ", public final void dbg(Stπng s) { if (debug) System out.pπntln(s), } private boolean debug = false, // Print debugging mfo? public Strmg getTιtle() { // dbg("ezrpnlap getTιtle()"); return this.title, } public final void pamt(Graphιcs g) { // dbg("ez_text.paιnt(): frameType ="+frameType); if (frameOption) { mt 1; Dimension d = sιze(); switch (frameType) { case LINE: { g.setColor(getForeground()); for (1 = 0; K frameSize; ι++) g.drawLme(0,d.heιght-ι-l,d.wιdth-ι-l,d.heιght-ι-l); } break; case FLAT: { g.setColor(getForeground()); for (I = 0; l < frameSize; ι++) g.drawRect(ι,ι,d.wιdth-2*ι-l,d.heιght-2*ι-l), } break; case RAISED: case DROPPED, case ETCHED: { boolean raise = frameType— RAISED; mt R = (getForeground().getRed()+ getBackground().getRed() )/2; mt G = (getForeground().getGreen()+getBackground().getGreen())/2; mt B = (getForeground().getBlue()+ getBackground().getBlue() )/2; g.setColor(new Color(R,G,B)); for (I = 0; I < frameSize; ι++) { if (frameType == ETCHED) raise = I >= frameSize/ 2; g.draw3DRect(ι,ι,d.wιdth-2*ι- l,d.heιght-2*ι-l, raise); } if (frameType = ETCHED) { g.setColor(getForeground()); g.drawLme(0,0,frameS_ze/2,frameS_ze/2); g.drawLιne(d.wιdth-frameSιze,d.heιght-frameSιze,d.wιdth- frameSιze/2,d.heιght-frameSιze/2), g.setColor(getBackground()); g.drawLme(frameSιze/2,frameSιze/2,frameSιze,frameS_ze); g drawLme(d wιdth-frameSιze/2,d.heιght- frameSιze/2,d width- l,d.heιght-l), } else { g.setColor((frameType=RAISED) getBackground():getForeground()), g drawLine(0,0,frameSize,frameSize), g.setColor((frameType==RAISED) getForeground():getBackground()), g drawLιne(d.wιdth- frameSιze,d.heιght-frameSιze,d.wιdth-l,d.heιght-l); } } } } } public synchronized Image fetchImage(Strιng fileName) { // dbg("ez_text.fetchImage("+fileName+")"); if (IformattedText || fileNa e = null) { return null; } else { Image thelmage = null; mt imageDatabaselndex = // get referemce to image database file name unageFileNames.mdexOf(fileName); if (imageDatabaselndex < 0) // not registered yet: add it m { URL theURL = null; try // look m the documentBase { theURL = new URL(getDocumentBase(), fileName); InputStream is = theURL.openStream(); // test connection thelmage = getlmage(theURL); tracker.addlmage(thelmage,0); // jump-start image loadmg tracker.checkID(0,true); try { tracker. waιtForΙD(O); } catch ( IntenuptedException le ) { } Image bufferedlmage = createlmage(l,l); if (bufferedlmage l= null) { Graphics bg = bufferedImage.getGraphιcs(); if (bg l= null) { bg.drawlmage(thelmage,0,0,this); bg.dιspose(); } } bufferedlmage.flushO; } catch (MalformedURLException u) { System.out.prmtln("ez_text.fetchImage("+fileName+"). MalformedURLException = "+u); thelmage = null; } catch (IOException io) { System.out.pπntln("ez_text.fetchImage("+fileName+"): InputStream IOException = "+io); thelmage = null; } // update image database for document ιmageFιleNames.addElement(fileName); // the filename is the main key to image database acces graphιcsURLs.addElement( theURL); // in case we need to download it again later graphicsImages.addElement(thelmage); // this may be reset to null with imageUpdate } else { thelmage = (Image)graphιcsImages.elementAt(ιmageDatabaseΙndex), } return thelmage; } } public void dιsposeFrame() { // dbg("ez_text.dιsposeFrame()"); if (frame != null) { Event evt = new Event(frame, Event. WINDOW_DESTROY, null), Component co[] = frame.getComponents(); for (mt l = 0, K co.length, 1++) cofι].handleEvent(evt) frame.dιspose(), frame = null; } } public boolean mouseUp(Event evt, mt x, mt y) { // dbg("ez_text.mouseUp(Event "+evt+", mt "+x+", int "+y+") "), if (frame != null) frame. toFront(); else frame = new ezrfrmap(tιtle, article, this), return false, } public Strmg htmlCanon(Stπng itsText, boolean convertNWSs) { // dbg("ezrpnlap.htmlCanon(\n "+ιtsText+"\n , "+convertNWSs+")"), if ('formattedText) retarn itsText, if (convertNWSs) // look for ftιtle<p] { String LCtext = ιtsText.toLowerCase(); if (LCtext.startsWιth(AG)) // initial accent grave specifies article title { mt endTitle = LCtext.ιndexOf(PL), // end of lme after canonization if (endTitle > 0) { title = ιtsText.substrmg(l,endTιtle), itsText = itsText substπng( endTitle), } } } else { // replace character entities with spaces (except quot -> \") StnngTokenizer entities = new StπngTokemzer(ιtsText,AM,true), StnngBuffer newText = new StrmgBuffer(70), while (entιtιes.hasMoreTokens()) { Strmg entity = //[body text], [&][#nnn;body text],.. ,[&][#nnn,body text] entιtιes.nextToken(AM), if (entιty.equals(AM)) { Strmg eText = //should be character entity text # nnn or name entιtιes.nextToken(SC); entity = entιtιes.nextToken(), // should be "," if eText is valid character entity value if (entity.equals(SC)) // replace character entity with local character (set) { if (eText.equals(QT)) { newText.append(QL); } else { newText.append(SP), } } else // syntax enor: { newText.append(AM).append(eText).append( entity), } } else { newText.append( entity); //standard text } } itsText = newText.toStπngO, //look for [<tιtle >tιtle text</tιtle ] Strmg LCtext = itsText toLowerCase(); mt endmg = 0, starts = Lctext.ιndexOf("<tιtle"), if (starts > -1) { starts = Lctext.ιndexOf(">",starts)+l ; // start of title if (starts > 0 && starts < LCtext. length()) { endmg = Lctext.mdexOf("</tιtle",starts); if (ending > -1) { title = ιtsText.substπng(starts,endιng); } } } //look for [<body ..>body text</body...] starts = Lctext.ιndexOf("<body"); if (starts > -1) { starts = Lctext.mdexOf(">",starts)+l; // start of body if (starts > 0 && starts < Lctext.length()) { endmg = LCtext.ιndexOf("</body",starts); if (endmg > -1) { return itsText substπng(starts,endmg); } } } } return itsText; } public Strmg lmeCanon( Strmg itsText, boolean convertCRs) { // dbg("ez_text.hneCanon()"), if (itsText = null || itsText.lengthO = 0) return itsText; Strmg newSeparator = convertCRs?PR:SP, // target return code Strmg searchSeparators[] = // replacable return codes { "\n"+"\r", // chr(lθ), chr(13) "\r"+"\n", // chr(13), chr(lθ) 'V, // chr(13) "\n", // chr(lθ) "\f // chr( 12)} ; Strmg newText = new Stnng(ιtsText); for (mt l = 0; I < searchSeparators. length; ι++) // replace old with new { Strmg oldSeparator = new Stπng(searchSeparators[ι]); newText = replaceStπng(newText,oldSeparator,newSeparator), } return newText; } public Strmg replaceStπng ( Strmg theStπng // oπgmal strmg , Strmg oldStπng // replace- ee , String newStπng // replace-or ) { // dbg("ez_Text.replaceStrmg(theStnng, old "+oldStπng+", new "+newStπng+")"); StnngBuffer out = new StrιngBuffer(), mt oldlndex = -1, oldEnd = 0; mt oldLength = oldStnng.lengthO; while ((oldlndex = theStrmg.mdexOf(oldStπng, oldEnd)) > -1) { Strmg piece = theStnng.substπng(oldEnd,oldIndex);// got it 9 get it' good out.append(pιece), // add the piece before the next old string out.append(newStrmg), // get the replacement oldEnd = oldlndex + oldLength, // skip to the end of this old strmg } // nothing more to replace if (oldEnd < theStπng.length()) { Strmg piece = theStrmg.substrmg(oldEnd), out.append(pιece), // add the piece after the last old strmg } return out.toStnngO, } public Insets ιnsets() { // dbg("ezrpnlap.msets()"), if (frameOption) switch (frameType) { case LINE: return new Insets(0,0,frameSize,0), case FLAT case RAISED case DROPPED, case ETCHED return new Insets(frameSιze,frameSιze,frameSιze,frameS_ze), } return new lnsets(0,0,0,0), } public void ιnιt() { // dbg("ez_text.mιt<>: parent background = "+getParent().getBackground()); if (formattedText) { imageFileNames = new Vector( 10); // must be created before calls to fetchlmage graphicsURLs = new Vector(lO); // must be created before calls to fetchlmage graphicslmages = new Vector(lO); // must be created before calls to fetchlmage } tracker = new MedιaTracker(thιs); Strmg s = getParameter("fileName"); if (s != null) try // new URL, etc. { URL url = new URL(getDocumentBase(), s); InputStream is = url.openStream(); BufferedlnputStream bis = new BufferedInputStream(ιs); mt len = 0; byte buffer[] = new byte[512]; StnngBuffer pageText = new StπngBuffer(); while ((len = bιs.read(buffer)) > 0) pageText.aρpend(new Stπng(buffer,0,0,len)); bιs.close(); ιs.close(); boolean toHTML = s.toLowerCase().endsWιth(".txt") || s.toLowerCase().endsWιth(".text") || s.toLowerCase().endsWιth(".nws"); article = htmlCanon // retains only supported tags ( lιneCanon(pageText.toStπng() , toHTML) // true converts 'CR's to '<p>'s , toHTML // true converts enews tags to html ); // strips off head & saves title // start loadmg in-lme graphics right away StπngTokenizer images = new StπngTokenιzer( article, "@",true); while (ιmages.hasMoreTokens()) { Strmg token = ιmages.nextToken(); if (token.equals("@")) { String fileName = images nextToken("<"); // <p> following fileName if (fileName.toLowerCase().endsWιth(".jpeg") || fileName. toLowerCase(). ends Wιth(" gif')) fetchΙmage(fileName.tπmO); } } } catch (MalformedURLException mu) { StrmgBuffer msg = new StπngBufferO; msg.append(alert_0).append("Malformed URL ").append(alert_l).append(alert_2).append(alert_4); article = msg.toStπng(); Strmg e = "Could not open "+s; showStatus(e); System.out.prmtln(e+"; exception- "+mu), } catch (IOException io) { StnngBuffer msg = new StπngBufferO; msg.append(alert_0).append("Input/Output").append(alert_l).append(alert_2).append(alert_4); article = msg.toStnngO; Strmg e = "Could not open "+s; showStatus(e); System.out.pπntln(e+"; exception: "+ιo); } catch (SecuπtyException se) { StnngBuffer msg = new StπngBufferO; msg.append(alert_0).append("Secuπty ").append(alert_l).append(alert_3).append(alert_4); article = msg.toStnngO; Strmg e = "Could not open "+s, showStatus(e); System.out.pπntln(e+"; exception- "+se); } else { StrmgBuffer msg = new StrmgBuffer(); msg.append(alert_0).append("Input/Output ").aρpend(alert_l); msg.append("No article file specification was detected! "); msg.append(alert_2).apρend(alert_4); article = msg.toStnngO; Strmg e = "No fileName specified"; showStatus(e); System.out.pπntln(e); } thιs.setLayout(new BorderLayout()); thιs.setBackground(getParent().getBackground()); thιs.setForeground(getParent().getForeground()); panel = new ezrpnlap(artιcle, this, false), // NOT the reader screen // add msets for applet boundanes... thιs.add("Center", panel); if (frameOption) { Strmg b = getParameter("frameType"); if (b != null) { b = b.toUpperCase(); if (b.equals("LINE")) { frameSize = 1; frameType = LINE; } if (b.equals("FLAT")) { frameSize = 1; frameType = FLAT; } if (b.equalsfRAISED")) { frameSize = 2; frameType = RAISED; } if (b.equals("DROPPED")){ frameSize = 2; frameType = DROPPED;} if (b.equals("ETCHED")){ frameSize = 4, frameType = ETCHED; } } Strmg w = getParameter("frameSιze"); if (w != null) try {frameSize = Integer.parselnt(w); } catch (NumberFormatException nf) { } } } } /* * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc All Rights Reserved * ez_text applet reader screen frame */ /** * @author Everett Stoub %I%, %G% */ιmport java.awt.*; import java.applet.*; importjava.net.*; import java.io *; import java.util.*; public final class ezrfrmap extends Frame { private ezrpnlap readerScreen; pπvate Panel control; private ez_text ez Text; // private Label footer; private boolean demo = t e; private Strmg buttonName[] = { "Home" , "Previous" , "Next" , "Font +" , "Font -" } ; public ezrfrmap(Stπng title, Strmg readerContent, ez_text ez_Text) { super(tιtle); // dbg(" ezrfrmap. <ιnιt>"); thιs.ez_Text = ez_Text; this.readerScreen = new ezrpnlap(readerContent, ez_Text, tme); thιs.add("Center", readerScreen); control = new Panel(); control.setBackground(Color.gray); // control.setLayout(new FlowLayout(FlowLayout.RIGHT)), control.setLayout(new FlowLayout(FlowLayout.CENTER)); StrmgBuffer version = new StπngBufferO; versιon.append("ION EZ Text "); if (demo) versιon.append("Demo"); else versιon.append("vl.03"), // [?n- major]. [?n-mιnor][?n-tweak][?a-fix] control.add(new Label(versιon.toStrmg())); for (mt I = 0; l < buttonName.length; ι++) { Button b = new Button(buttonName[ι]); b.setBackground(Color. white); control.add(b); } control. add(new Label("(c)'97 ION Systems, Inc. 888.ION.JAVA")); thιs.add("South", control); thιs.pack(); thιs.show(); } public boolean actιon(Event e, Object o) { if (e.target mstanceof Button) { if (o = (buttohName[0])) readerScreen.doVιewerHome(); else if (o = (buttonName[l])) readerScreen.doViewerLeftO; else if (o == (buttonName[2])) readerScreen.doVιewerRιght(); else if (o == (buttonName[3])) readerScreen doVιewerSιze(false); else if (o == (buttonName[4])) readerScreen.doVιewerSιze(tme); else retum false, // repaιnt(); remm tine, } else retum false; }/* private final void dbg(Stπng s) { if (debug) System.out.pπntln(s), } private boolean debug = false, // Prmt debuggmg info?*/ public final boolean keyDown(Event evt, mt key) // note: keyUp is not utilized at all (missmg m JDK 1.02 on Mac) { // dbg("ezrfrmap.keyDown("+evt+", "+key+")"); boolean down = key == Event.DOWN; switch (key) { case EventHOME: readerScreen.doVιewerHome(); repaιnt(); re m tme; case Event.PGDN: case Event.RIGHT: readerScreen.doVιewerRιght(); repaιnt(); remm tme; case Event.PGUP: case Event.LEFT: readerScreen.doViewerLeftO; repaιnt(); remm tme; case Event.UP: case Event.DOWN: readerScreen.doVιewerSιze(down); repaιnt(); return true; } remm false; } public final boolean handleEvent(Event evt) { // dbg("ezrfrmap.handleEvent("+evt+")"); switch (evt.id) { case Event. WINDOW EXPOSE: readerScreen.requestFocus(); break; case Event. WINDOWJDEICONIFY: thιs.show(); break; case Event. WINDOW CONIFY: thιs.hιde(); break; case Event. WINDOW_DESTROY. ez_Text.dιsposeFrame(); break; } remm super.handleEvent(evt), } public void update(Graphιcs g) { // g.setColor(getBackgroundO), // g.fιllRect(0, 0, width, height); g.setColor(getForeground()); pamt(g), } }/* * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * web crawler with ReaderScreen */ /** * @author Everett Stoub %I%, %G% */ import java.awt *; import java.awt.image.*; import java.applet.*; importjava.net.*; import java.io.*; import java.util.*; public final class ezrpnlap extends Panel { public final static int LEFT = 0; public final static mt CENTER = 1; public final static mt RIGHT = 2; public final static Strmg MT = ""; public final static String BL = " "; private boolean demo = tme; // mild display spam pπvate final boolean formattedText = tme, // if true, m-lme graphics and pull quotes are enabled private ez text ez Text = null; private Strmg readerContent = null, pπvate Image readerScreen = null, pπvate mt readerFontSιze[] = { 8, 9,10,11,12,14,18,24,30,36,42,48,56,64,72,80,96} ; private mt readerFootlndex = 2; // this 2-step decrement is also hard coded in stepFontSιze() private int readerSizelndex = 4; // default for on- webPage article rendering private mt readerPullIndex = 5, // this 1-step mcrement is also hard coded m stepFontSιze() private mt readerHeadlndex = 6, // this 2-step mcrement is also hard coded m stepFontSιze() pnvate Font readerFooterFont = null; private Font readerScreenFont = null; private Font readerPQuoteFont = null; private Font readerHeaderFont = null; pπvate mt readerAhgnment = LEFT; private mt readerPeπmeter = 10; private mt readerNumCols = 1 , private mt readerLeadmg = 0; pnvate mt readerPageNum = 1 ; private mt readerNumPages = 0; private mt readerEstPages = 1 ; pnvate mt readerEndlndex = 0; private mt readerStartlndex = 0; private int readerTextLength = 0; pnvate boolean readerScreenDirty = tme, // tme if panel needs redraw private boolean readerFrame = false, // tme if panel owned by frame private boolean readerHeader = false, // tme if article begins with "title private Color readerBackColor = new Color(231,231,231), pπvate Vector readerPageStart = new Vector(50), pπvate Rectangle readerRect = new Rectangle(), // variable principally for pamtTextArea private mt lowestTextAreaBaseLine = 0; private int controlSize = 0, private mt pullQuoteLme Width = 2; private mt pullQuoteSrzelncr = 1 , private boolean drawPullUnderhner = false; // switch to finish pull quote display private boolean fimshPullQuoteText = false, // switch to finish pull quote content private boolean lastColumn = false, // cunent setting private boolean lastRow = false, // cunent setting private boolean parSpace = false, // cunent setting pnvate boolean pπorEmptyPara = false, // cunent setting pπvate Rectangle aheadRect = new Rectangle(), private Rectangle closeRect = new Rectangle(), pπvate Rectangle abackRect = new Rectangle(); private Color pullColor = Color.blue, // cunent setting pπvate Font textFont = null, // cunent setting pnvate FontMetπcs textMetncs = null; // cunent setting pπvate Color textColor = null, // cunent setting private mt textHeight = 0, // cunent setting private mt textAhgn = LEFT; // cunent setting pπvate Rectangle textRect = null, // cunent setting pπvate mt colNum = 0, colWidth = 0, colSpacmg = 0, numColumns = 0, oneSetOff = 0; private mt nextWidth = 0, xb = 0, te = 0, xe = 0, ys = 0, yb = 0, ye = 0; public ezrpnlap(Stπng readerContent, ez_text ez_Text, boolean readerFrame) { // dbg("ezrpnlap.<ιnιt>"); thιs.ez_Text = ez_Text; this.readerFrame = readerFrame; this.readerHeader = ez_Text.getTιtle() != null, this.readerContent = readerContent; this.readerTextLength = readerContent. length(); if (readerFrame) { thιs.sefForeground(Color.black); thιs.setBackground(readerBackColor); stepFontSιze(false), } else { thιs.setBackground(Color. white), // this is a hack } setAHFonts(), } public synchronized void stepFontSιze(boolean smaller) { // dbg("ezrpnlap stepFontSιze( smaller = "+smaller+")"), if (smaller) readerSizelndex--; else readerSιzeIndex++, readerHeadlndex = readerSizelndex + 2, readerPullIndex = readerSizelndex + 1 ; readerFootlndex = readerSizelndex - 2; readerSizelndex = Math.max(Math.mιn(readerSιzeIndex,readerFontSιze.length - 1),0); readerHeadlndex = Math.max(Math.mιn(readerHeadIndex,readerFontSιze.length - 1),0), readerPullIndex = Math.max(Math.mm(readerPullIndex,readerFontSιze.length - 1),0), readerFootlndex = Math.max(Math.mm(readerFootIndex,readerFontSize.length - 1),0), setAllFonts(), } public synchronized boolean ιmageUpdate(Image -mg, int flags, mt x, mt y, mt w, mt h) { // dbg("ezrpnlap.ιmageUpdate(flags = "+flags+")"); if (formattedText && (flags & ImageObserver.ALLBITS) != 0) // this image is complete (at last) { // resetReaderVιew(), repamtReaderScreen(), remm false; } else remm tme, } public final synchronized void doVιewerHome() { // dbg("ezrpnlap doVιewerHome()"), if (readerPageNum > 1) { readerPageNum = 1 ; readerStartlndex = ((Integer)readerPageStart.elementAt( readerPageNum- l)).intValue(); } repaintReaderScreen(); } public final synchronized void doViewerLeft() { // dbg("ezφnlap.doViewerLeft()"); if (readerPageNum > 1) { readerPageNum—; readerStartlndex = ((Integer)readerPageStart.elementAt( readerPageNum- l)).intValue(); } repaintReaderScreen(); } public final synchronized void doViewerRight() { // dbg("ezrpnlap.doViewerRight(): readerEndlndex = "÷readerEndlndex); if (readerEndlndex < readerTextLength) { readerPageNum++; if (readerNumPages < readerPageNum) { readerStartlndex = readerEndlndex - 1 ; readerPageStart.addElement( new Integer(readerStartlndex)); } else // been there, done that { readerStartlndex = ((Integer)readerPageStart.elementAt( readerPageNum-l)).intValue(); } } else if (readerNumPages == 0) { readerNumPages = readerPageNum; } repaintReaderScreen(); } public final synchronized void doViewerSize(boolean smaller) { // dbg("ezrpnlap.doViewerSize(boolean "+smaller+")"); stepFontSize(smaller); setReaderRect(); resetReaderView(); repaintReaderScreen(); } public synchronized void setAHFontsO { // dbg("ezrpnlap.setAHFonts()"); readerFooterFont = new Font("TimesRoman", Font.PLAIN, readerFontSizefreaderFootlndex]); readerScreenFont = new Font("TimesRoman", Font.PLAP , readerFontSizefreaderSizelndex]); readerPQuoteFont = new Font("TimesRoman", Font.PLAIN, readerFontSize[readerPullIndex]); readerHeaderFont = new Font("TimesRoman", Font.PLAIN, readerFontSizefreaderHeadlndex]); } public synchronized void setReaderRect() { // dbg("ezrpnlap.setReaderRect()"); setReaderRect(this.bounds()); } public synchronized void setReaderRect(Rectangle r) { // dbg("ezrpnlap.setReaderRect("+r+")"); readerRect.reshape ( 1 , 1 , r. width - 1 , r.height - 1 - (readerFrame?readerFontSize[readerFootIndex]*3/2:0) ); } public boolean mouseUp(Event evt, int x, int y) { // dbg("ezrpnlap.mouseUρ(Event "+evt+", int "+x+", int "+y+") ") ; if (! readerFrame) remm false; else if (aheadRect.inside(x,y)) { doViewerRight(); retum true; } else if (closeRect.inside(x,y)) { ez_Text.disposeFrame(); remm tme; } else if (abackRect.inside(x,y)) { doViewerLeft(); remm tme; } else retum false; } public final Dimension minimumSize() { // dbgC'ezrpnlap.minimumSizeO"); remm new Dimension(585, 400); } public final Dimension prefenedSize() { // dbg("ezrpnlap.prefenedSize()"); retam minimumSize(); } public synchronized void reshape(int x, int y, int width, int height) { // dbg("ezrpnlap.reshape("+x+", "+y+", "+width+", "+height+")"); lowestTextAreaBaseLine = 0; readerScreenDirty = tme; resetReaderView(); // fillRect is performed here rather than in update(g) getGraphics().setColor(getBackground()); getGraphics().fillRect(0, 0, width, height); getGraphics().setColor(getForeground()); super.reshape(x, y, width, height); } public final synchronized void paint(Graphics g) { // dbg("ezrpnlap.paint(g)"); if (readerScreenDirty) { if (readerScreen != null) readerScreen.flush(); readerScreen = this.createlmage(this.size().width, this.size().height); Graphics q = this.readerScreen.getGraphicsO; paintReaderScreen(q); q.dispose(); readerScreenDirty = false; } g.drawImage(readerScreen,0,0,this); } private final synchronized void paintReaderScreen( Graphics g) { // dbg("ezrpnlap.paintReaderScreen(g)"); Rectangle r = bounds(); setReaderRect(r); // set to full area (this.boundsO) g.setColor(getBackground()); g.fillRect(0, 0, r. width, r.height); int numCols = calculateReaderColumnsO; if (numCols != readerNumCols) { readerNumCols = numCols; resetReaderView(); } if (readerFrame) readerLeading = 2; // make it more comfortable else readerLeading = 0; // make it more compact if (readerHeader && ! readerFrame) // draw header (article title) { lowestTextAreaBaseLine = 0; g.setColor(Color.blue); int titleEnd = paintTextArea ( g // Graphics g , 0 // int beginlndex , readerHeaderFont // Font textFont , ez_Text.getTιtle() // Strmg textContent , 1 // mt numCols , CENTER // mt alignment ); lowestTextAreaBaseLine += readerHeaderFont.getSιze()/2; readerRect.reshape ( 1 , lowestTextAreaBaseLine , r.width - 1 , r.height - lowestTextAreaBaseLine ); g.setColor(getBackground()), g.fillRect(readerRect.x, readerRect.y, readerRect. width, readerRect.height); } if (demo && readerFrame) { Font sFont = new Font ( "Dialog" , Font.BOLD , 2*readerFontSize[readerHeadIndex] ); setFont ( Color. white , sFont , g ); String spam = "Demo"; int s Wide == textMetπcs.stπngWιdth( spam), ι, j; for (j = 2*readerPeπmeter + textHeιght/2 ; j < readerRect.height ; j += 3*textHeιght/2 ) for ( I = 4*readerPeπmeter + textHeιght/2 - j ; ι < readerRect width ; I += 3*sWιde/2 ) g.drawStnng // draw the spam ( spam , I + readerRect.x , j + readerRect.y ); } g.setColor(getForeground()); readerEndlndex = pamtTextArea(g, readerStartlndex); if (readerNumPages = 0) { if (readerEndlndex = readerTextLength) readerEstPages = readerNumPages = readerPageNum; else // estimate number of pages { readerEstPages = Math.round(0.5f+(float)readerPageNum*(float)readerTextLength/(float)readerEndIndex); } } else readerEstPages = readerNumPages; if (readerFrame) // draw footer (page mformation) { StnngBuffer pi = new StrmgBuffer(); pI.append("Screen ").append(Strmg.valueOf(readerPageNum)).append(" of "); if (readerNumPages = 0) pl.append("~"); pI.append(Stπng.valueOf(readerEstPages)), Strmg pagelnfo = pl.toStπngO; mt mfo Width = getFontMetπcs(readerFooterFont).stπngWιdth(pageInfo); g.setFont(readerFooterFont); g.setColor(getForeground()); mt xLoc = (r.width - mfo Wιdth)/2; mt yLoc = r.height - readerFontSιze[readerFootIndex]/4 - 1 ; g.drawStnng(pageInfo, xLoc, yLoc); } } private final synchronized mt paintTextArea ( Graphics g , int beginlndex ) // returns strmg mdex of first non-drawn character { // dbg("ezrpnlap.paintTextArea(g, "+begιnlndex+") "+readerNumCols+" columns"); retum paintTextArea ( g , beginlndex , readerScreenFont , this.readerContent , readerNumCols , readerAlignment ); } private final synchronized mt paintTextArea ( Graphics g , mt beginlndex , Font theFont , String textContent , mt numCols , mt alignment ) // returns strmg mdex of first non-drawn character { // dbg("ezrpnlap.pamtTextArea()"), // paιntTextArea(\n(g\n, "+beginlndex+"\n "+theFont+"\n, textContent\n "+numCols+"\n, "+ahgnment+"\n) int endText = textContent.length(); int endlndex = beginlndex; boolean go = endlndex != endText; numColumns = numCols, textAhgn = alignment; textColor = g.getColor(), thιs.setFont(textColor,theFont,g); StπngTokemzer paragraphs = new StπngTokenizer // break up the text mto normal paragraphs (textContent.substπng(begιnIndex),"<",true); // final true returns token on next call colNum = 0; mt colMargin = 4*textMetπcs.stπngWιdth(BL); // four spaces between cols colWidth = (readerRect. width - 2*readerPeπmeter - (numColumns- l)*colMargin)/numColumns; colSpacmg = colWidth + colMargin; Suing nextWord = MT; StrmgBuffer thisLine = new StπngBuffer(70); xb = readerRect.x + readerPeπmeter; // local left edge of the column area te = xb; // end position of this lme's words xe = xb + colWidth; // local πght edge of the column area nextWidth = 0; ys = readerRect y + (textHeight + readerLeadιng)*3/4; // local starting baseline of first line yb = ys; ye = readerRect.y + readerRect.height - textHeight/4; // local maximum baseline of last line lowestTextAreaBaseLine = yb, // lowest baselme m readerRect priorEmptyPara = false, // permits paragraph spacers lastColumn = colNum = numColumns - 1 , lastRow = false; controlSize = textHeιght*2/3; oneSetOff = (textHeight + readerLeadmg)/2; // use stnd font size for half-space set-offs // dbg(".. oneSetOff = "÷oneSetOff), abackRect.reshape ( readerRect.x + readerRect width - 2 - (controlSιze+4)*3 , readerRect y + readerRect height - 4 - controlSize , controlSize + 4 , controlSize + 4 ), if (debug) g drawRect(abackRect x,abackRect y,abackRect wιdth,abackRect height), closeRect.reshape ( readerRect x + readerRect width - 2 - (controlSιze+4)*2 , readerRect y + readerRect.height - 4 - controlSize , controlSize + 4 , controlSize + 4 ), if (debug) g.drawRect(closeRect.x,closeRect.y,closeRect.wιdfh,closeRect.heιght), aheadRect reshape ( readerRect.x + readerRect. width - 2 - (controlSιze+4)*l , readerRect y + readerRect.height - 4 - controlSize , controlSize + 4 , controlSize + 4 ); if (debug) g.drawRect(aheadRect.x,aheadRect y,aheadRect wιdth,aheadRect.heιght); draw while (paragraphs.hasMoreTokens() && go) // paragraph to follow { Stπng para = paragraphs.nextToken("<"), // dbg("... new paragraph token = ["+ρara+"]"), if (formattedText && para.startsWithC"")) // test for m-lme title { // dbg(".. pull quote: yb = "+yb), rollBack(); int pullQuoteHeight = 2*ρullQuoteLmeWιdth // reserve pull-quote bars + oneSetOff*((yb <= ys)?l:2), // reserve 1 or 2 setOffs outside bars textAlign = CENTER; this setFont(Color.blue,readerPQuoteFont,g); pullQuoteHeight += textHeight + readerLeading; // reserve one pullquote lme of text // dbg("... pullQuoteHeight = "+pullQuoteHeιght), if (yb + pullQuoteHeight > readerRect y + readerRect.height) { // not enough room m this (partial 9 ) column if (lastColumn) break draw, // no more columns left to fill nextColumn(), yb = readerRect y, // start at the top } else if (yb > ys) // not at the top of the column 9 { yb += oneSetOff, // upper set-off } for (mt line = 0, lme < pullQuoteLine Width; lme++) { g.drawLme(xb, yb, xe, yb++); } yb += textHeight + readerLeading; // drop for next line drawPullUnderliner = fimshPullQuoteText = tme, para = para.substrmg(l), // drop control character endlndex++, // update location } else if (formattedText && drawPullUnderliner && ! fimshPullQuoteText) // restore stnd values { rollBackO; for (mt lme = 0; lme < pullQuoteLine Width; hne++) { g.drawLιne(xb, yb, xe, yb++); } drawPullUnderliner = false; textAlign = alignment; thιs.setFont(textColor,theFont,g); ιf(yb > ys) yb += oneSetOff + textHeight + readerLeading; // drop for next lme if (yb > ye) { // not enough room m this (partial?) column if (lastColumn) break draw; // no more columns left to fill nextColumn(); } } JI (para.equals("<")) // an html new paragraph 9 { Stπng tagText = paragraphs.nextToken(">").toLowerCase(), mt tagLength = tagText._ength(); para = paragraphs nextToken(), if (para.equals(">")) { if (tagText.startsWιth("p")) { if (yb > ys && pπorEmptyPara) // unless we're at the top { yb += textHeight + readerLeading; // drop down to another lme if (yb > ye) { // not enough room m this (partial 9 ) column if (lastColumn) break draw; // no more columns left to fill nextColumn(); } } } lowestTextAreaBaseLine = Math.max(lowestTextAreaBaseLιne,yb); priorEmptyPara = tme, } endlndex += tagLength+2, } else if (formattedText && para.startsWιth("@") && ( para.toLowerCase().endsWιth(".jpeg") || para.toLowerCase().endsWιth(".gιf '))) // test for m-hne graphic { Image thelmage = ez_Text.fetchImage(para.substπng(l) tπm()), if (thelmage l= null) { rollBack(); priorEmptyPara = false, int wlm = thelmage.getWidth(ez Text), mt hlm = theImage.getHeιght(ez_Text), if (wlm > colWidth) // scale graphic down to column width { him = Math.round( (float)col Width * (float)hlm / (float)wlm ), wlm = colWidth, } if (him > readerRect.heιght) // scale graphic down to column height { wlm = Math.round( (float)readerRect.heιght * (float)wlm / (float)hlm ), him = readerRect.height, } int fulllmageHeight = him + ((yb > ys)?oneSetOff:0); if (yb + fulllmageHeight > readerRect y + readerRect.height) { // not enough room in this (partial?) column if (lastColumn) break draw; // no more columns left to fill nextColumn(); rollBack(), } else if (yb > ys) { yb += oneSetOff, // upper spacing } mt xlm = xb + (colWidth - wIm)/2, // center it g.fillRect(xIm, yb, wlm, him), g.drawlmage(thelmage, xlm, yb, wlm, him, this), endlndex += para.length(), // update location yb += him, // image sizing lowestTextAreaBaseLine = Math.max(lowestTextAreaBaseLιne,yb); yb += oneSetOff + textHeight + readerLeading, // image spacing if (yb > ye) // no room for text under image margin { if (lastColumn) break draw, // no more columns left to fill nextColumn(); } } } else // none of the above... { // dbg(".. new paragraph text: "+para.substπng(0,Math.mιn(20,para.length()))); priorEmptyPara = false, if (formattedText && fimshPullQuoteText) { textAlign = CENTER; thιs.setFont(Color .blue, readerPQuoteFont, g), } te = xb; // start a new line StrmgTokenizer words = new StrmgTokemzer(para,BL,true), // "tme" returns white spaces while (words.hasMoreTokens()) { nextWord = words.nextToken(); nextWιdth = textMetπcs.strmgWιdth(nextWord); if (te + nextWidth < xe) // it will fit on this lme, so add it on { thιsLιne.append(nexfWord); te += nextWidth, nextWord = MT, nextWidth = 0, } else // it won't fit if added, so draw the text { if (thιsLιne.length() > 0) // not if a monster is first m the article { // dbg("new lme = ["+thιsLιne+"], nextWord = ["+nextWord+"]"), endlndex += thιs.drawText(thιsLιne, g); thιsLιne.setLength(O); // start the new lme } ιf (yb > ye) // start a new column 9 { if (lastColumn) break draw; // no more columns left to fill nextColumn(); while (thisLme toStπng().startsWιth(BL)) { // ignore preceedmg blanks on new lme Strmg noBlank = thιsLιne.toStπng().substπng(l); thιsLιne.setLength(O), thιsLιne.append(noBlank); endlndex++; } } if (thιsLιne.lengfh() == 0) while (nextWord.startsWιth(BL)) // ignore preceedmg blanks on new lme { nextWord = nextWord.substπng(l); // look again nextWidth = textMetπcs.strmgWιdth(nextWord); endlndex++, } thιsLme.append(nextWord); te = xb + nextWidth; // possibly a monster! nextWord = MT; nextWidth = 0; while (te > xe) // shorten the lme by breakmg the word { // dbg("ιt's big: thisLine = ["+thιsLιne+"]"); while (te > xe) // transfer letters back until fit (one lme) { mt e = thisLme.lengthO; nextWord = thιsLme.toStnng() substrmg(e-l,e) + nextWord, Strmg truncated = thisLme.toStπng().substnng(0,e-l); thιsLιne.setLength(O); thιsLιne.append(trancated), // dbg(" - try thisLine = ["+thιsLιne+"]\n...and nextWord = ["+nextWord+"]"); te = xb + textMetπcs.stπngWidth(thιsLme.toStπng()+"-"), } thιsLιne.append("-"), endlndex += thιs.drawText(thιsLιne, g) - 1; thιsLιne.setLength(O); // start the new lme if (yb > ye) // start a new column 9 { if (lastColumn) break draw; // no more columns left to fill nextColumn(); } thιsLιne.append(nextWord), te = xb + textMetπcs.stπngWιdth(thisLιne.toStπngO); nextWord = MT; nextWidth = 0; } } } // no more words in this paragraph if (thιsLιne.length() > 0) endlndex += thιs.drawText(thιsLιne, g); thisLιne.setLength(O); // start the new lme ιf (yb > ye) // start a new column? { if (lastColumn) break draw, // no more columns left to fill nextColumn(), } nextWord = MT, // starting fresh nextWidth = 0, te = xb; // pixel width of this lme's words } fimshPullQuoteText = false, } // end of draw label block // no more paragraphs while (endlndex < endText && textContent.substrιng(endIndex++).startsWιth(BL)), // skip blanks g.setColor(getForeground()), // left anow if (readerPageNum > 1) { mt x = abackRect.x + 2 , y = abackRect.y + abackRect.heιght/2, for (mt anow = 0; anow < controlSize; anow++) { g.drawLine ( x + anow , y - anow/2 , x + anow , y + anow/2 ), } } // close box if (readerFrame) { int x = closeRect x + 2 , y = closeRect.y + 2 , w = closeRect width - 5 , h = closeRect.height - 5, g.drawRect(x, y, w, h), g.drawLme(x, y, x+w, y+h), g.drawLιne(x+w, y, x, y+h), } // right anow if (endlndex < endText) { int x = aheadRect.x + aheadRect. width - 2 , y = abackRect y + abackRect.heιght/2; for (mt anow = 0; anow < controlSize; anow++) { g.drawLme ( x - anow , y + anow/2 , x - anow , y - aπow/2 ); } } remm endlndex; } private final synchronized void resetReaderVιew() { // dbg("ezrpnlap.resetReaderVιew()"); readerStartlndex = 0; readerEndlndex = 0; readerNumPages = 0; readerEstPages = 1 ; readerPageNum = 1 , readerPageStart.removeAllElements(), readerPageStart.addElement(new Integer(readerStartlndex)); } public final void dιspose() { // dbg("ezrpnlap.dιspose()"); if (readerScreen != null) readerScreen.flush(); } public synchronized void update(Graphιcs g) { // dbg("ezrpnlap.update()"); // fillRect is NOT performed here to eliminate blank screen boredom during offscreen drawing // g.setColor(getBackground()); // g.fillRect(0, 0, width, height), // g.setColor(getForeground()); ρamt(g); } private final synchronized void dbg(Stπng s) { if (debug) System.out.pπntln(s), } private boolean debug = false, // Print debugging mfo? private final synchronized void repaιntReaderScreen() { // dbg("ezrpnlap.repaιntReaderScreen()"); readerScreenDirty = tme; repamt(), } private final synchronized mt calculateReaderColumns() { // dbg("ezrpnlap.calculateReaderColumns()"); int numCols = 1, Rectangle r = bounds(), // rectangle of ezrpnlap int numChar = 30, // the control parameter: min # of n's per line of text int targetWidth = numChar * getFontMetπcs(readerScreenFont).strmgWιdth("n"); setReaderRect(r); numCols = (r.wιdth)/targetWιdth, if (numCols < 1) numCols = 1; remm numCols, } private final synchronized mt drawText(StrmgBuffer thisLme, Graphics g) { // dbg("ezrpnlap.drawText(\""+thιsLme.toStπng()+"\")"), g.drawStπng ( thisLine.toStrmgO , xb + textAlign* (colWidth + xb - te)/2 , yb ); // draw the text lowestTextAreaBaseLine = Math.max(lowestTextAreaBaseLιne,yb); yb += textHeight + readerLeading; // drop down to another lme checkShortLme(); retum thιsLιne.length(); } private final synchronized void checkShortLιne() { // dbg("ezrpnlap.checkShoιtLιne()"); if (lastColumn && (lastRow = (ye - yb) <= (textHeight + readerLeadmg)*2)) { if (readerPageNum > 1) // left anow xe = abackRect.x; else if (readerFrame) // close box xe = closeRect.x; else // right anow xe = aheadRect.x; } // dbg("ezrpnlap.checkShortLιne(): new xe = "+xe); } pnvate final synchronized void nextColumn() { // dbg("ezrpnlap.nextColumn()"); colNum++, // finished another column lastColumn = colNum == numColumns - 1 ; // clearlmtialSpaces = tme; yb = ys; // local baseline of first lme xb += colSpacmg; // local left edge of the column area te += colSpacmg, // local end of text xe += colSpacmg; // local right edge of the column area checkShortLιne(); } private final synchronized void setFont(Font f, Graphics g) { // dbg("ezrpnlap.setFont("+f+")"); textMetπcs = getFontMetπcs(f); textHeight = f.getSιze()* 5/4, g.setFont(f), // dbg("ezrpnlap.setFont(setFont): textHeight = "+textHeιght); } private final synchronized void setFont(Color c, Font f, Graphics g) { // dbg("ezrpnlap.("+c+", "+f+", g)"); g.setColor(c); setFont(f, g); } private final synchronized void rollBack() { // dbg("ezrpnlap.rollBack()"), if (yb = ys && drawPullUnderliner && ! fimshPullQuoteText) { yb = readerRecty + readerRect.height - pullQuoteLine Width; // roll back to base of previous column colNum--, lastColumn = false; xb -= colSpacmg, // local left edge of the column area te -= colSpacmg; // local end of text xe -= colSpacmg; // local right edge of the column area } else if (yb > ys) { yb -= (textHeight + readerLeadmg)/2; // roll back half of last CR } else { yb = readerRect y, // start at the top } } } /** * sample web page with applet tag */ <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac"> <TITLE></TITLE> </HEAD> <BODY> <applet codebase="ez_class" code="ez_text.class" wιdth=300 heιght=200> <param name="fileName" value="ezsample txt"> </applet> </BODY> </HTML> /** * ezsample txt web page for applet */ EZ Text Sample Article '"Click on the applet" The reader screen presentation of content is interactive and optimized for readability Font size can be changed by pressing up or down anow keys, or by clicking the Font+ or Font- buttons Pages can be turned by pressing home, left, or right keys, or by clicking the Home, Previous, or Next buttons "optimized for readability" One of the key advantages of this reader screen presentation is its careful avoidance of a particular form of eye-strain known as optokinetic nystagmus Nystagmus, a reflexive jump in the muscles directing the eye, is triggered by, for example, vertical scrollmg of text on a computer screen @ez_eye gif As nystagmus stram mcreases, muscle jumps can become exaggerated and even enatic, finally resultmg m a perception of visual wearmess Nystagmus is well-known as a side-effect of excessive alcohol a simple road-side test conducted by law officers can aid m determination of a possible DWI offense Other possible causes of nystagmus include general physical exhaustion and illness While the term "nystagmus" may have been unfamiliar, the condition is encountered m many circumstances, none of which is very pleasant '"optokinetic nystagmus" The main side effect of optokinetic nystagmus induced by scrollmg text is a tendency to print the document, so that it can be read later with greater comfort This interrupts delivery of content and consumes resources It is very possible that the demise of the paperless office dreams of the '80's was caused m part by nystagmus Another major cause of its demise was the difference in formattmg between standard paper, height bemg typically 30% greater than width, and standard computer monitors, width being typically 33% greater than height Word processors targeted paper formatting, so that documents delivered from computer to computer were not easily adapted to screen formats This pattern also resulted m a tendency to print such documents rather than straggle to consume their contents on screen EZ Text solves these twin problems nicely First, there is no scrolling text, resulting m reduced eye-strain Font sizing can be adjusted by the reader for his particular situation of lighting, monitor quality and size, and his personal visual comfort Second, The content is automatically laid out in columns of text, with neither too few words m a line, about 30 characters minimum, nor too many, about 60 characters maximum The upper limit yields a lme length which, as the human eye executes its rapid raster motion to the begmnmg of the next lme, is not too long to accurately and easily find the conect next new lme If lmes are much shorter, below the minimum, lmes of text contam too little content, and the frequent raster motions can induce eye-strain ' "Web pages become a rewarding experience with EZ Text " This sample document contains about 3300 characters m about 640 words At normal readmg speeds, it should take about 5 minutes to absorb its mam content The effort required to read this article on the screen, usmg EZ Text, should be noticeably less than required by other channels For instance, usmg a word processor, two approaches are common The first is to print it out, collect the page(s), and finally read it Altematively, one could open the document m a word processor, adjust window widths and zoom factors, and finally read it, occasionally scrollmg to brmg unseen parts into view With EZ Text, just sit back, tap the up anow to adjust the font, and tap the right anow to m the page as needed Web pages, known widely as challenging when it comes to delivering on-screen content, can become a rewarding experience with EZ Text Section B. Modified Embodiment That Further Includes Manipulation of Tables and Utilization of HTML Commands Embedded in a Source Document. The following is a printout of computer source code for realizing the objects and advantages of the modified embodiment herem /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * ez html applet displays snaking text with in-line graphics * and produces a reader screen frame when clicked * applet param specifications * fileName value=name_of_file (required) * extension must be .htm or .html for html parsing * e.g. <param name="fileName" value="ezsample.htm"> * maxColumns value=an_integer (optional) * specifies upper limit of column number in APPLET display only * e.g. <param name="maxColumns" value="2"> * frameType value=special_name (optional) * e.g. <param name="frameType" value="LINE"> default frameSize = 1 * e.g. <param name="frameType" value="FLAT"> default frameSize = 1 * e.g. <param name="frameType" value="RAISED"> default frameSize = 2 * e.g. <param name="frameType" value="DROPPED"> default frameSize = 2 * e.g. <param name="frameType" value="ETCHED"> default frameSize = 4 * frameSize value=an_integer (optional) * specifies width of optional frame * e.g. <param name="frameSize" value="2"> * HTML tag parsing honors the following commands and attributes * " <title>...</title> title text delimeters * " <base> document relationships * href relative or absolute url for hyperlink * " <body>...</body> body text delimeters * bgcolor=color background color (#hhhhhh or name) * text=color default text color * link=color hypertext link color * background=URL tiled applet & reader background * " <table>...</table> table tag & range (replaced with hot image) * @author Everett Stoub %I%, %G% */ import java.awt.*; import java.awt.image.*; import java.applet.*; importjava.net.*; import java.io.*; import java.util.*; public class ez html extends Applet { public static Color backColor = new Color(239,239,239); public static Color foreColor = Color.black; public static Color linkColor = Color .blue; public static int maxColumns = 15; public _f_rs_db frame = null; public String title = null; private String article = null; private _p_rs_db titlePanel = null; private _p_rs_db bodyPanel = null; private _o_im_db imageDB = null; private o tb db tableDB = null; private _o_fl_db formsDB = null; private Image backlmage = null; private URL baseURL = null; private MediaTracker tracker = null; private final int NONE = 0; private final int LINE = 1; private final int FLAT = 2; private final int RAISED = 3; private final int DROPPED = 4; private final int ETCHED = 5; private int frameType = NONE; private int frameSize = 0; private Insets insets = new lnsets(0, 0, 0, 0); public final static String CS = "Release to create reader screen..."; public final static String RS = "Release to view reader screen..."; public final static String WS = "Wait for new reader screen..."; public final static String ZM = "Click to read..."; private static final void dbg(String s) { if (debug) System. out.println(s); } private static boolean debug = false; // Print debugging info? public void disposeFrame(_f_rs_db disposee) { if (disposee != null) { Event evt = new Event(disposee, Event. WINDOW_DESTROY, null); Component co[] = disposee.getComponents(); for (int i = 0; i < co.length; i++) co[i].handleEvent(evt); disposee.dispose(); } if (disposee = frame) { frame = null; } } public Image getBackImage() { remm this.backlmage; } public URL getDocumentBase() { if (baseURL != null) retum baseURL; else remm super.getDocumentBase(); } public o im db getImageDB() { if (this. imageDB == null) this. imageDB = new _o_im_db(this); return this.imageDB; } public _o_tb_db getTableDB() { if (this.tableDB == null) this. tableDB = new _o_tb_db(this); retum this.tableDB; } public o fl db gefFormDB() { if (this. formsDB = null) this.formsDB = new _o_fl_db(fhis); remm this.formsDB; } public Color getBackColor() { retum this.backColor; } public Color getForeColor() { retum this.foreColor; } public String getTitle() { retum this.title; } public MediaTracker getTracker() { if (this. tracker == null) this. tracker = new MediaTracker(this); remm this.tracker; } public void init() { String s = getParameter("fileName"); if (s != null) { article = _o_ht_db.getArticle(s, this); } String m = getParameter("maxColumns"); if (m != null) { maxColumns = Math.max ( _o_tg_db.parseInt(m, maxColumns) , 1 ); } this.setLayout(new BorderLayout()); if (title != null) { // dbg("titlePanel: "+title); String t = getParameter("showTitle"); if (t != null) { if(t.toLowerCase().equals("yes")) { titlePanel = new _p_rs_db ( "<font color=\"#0000b3\"><h2 align=center>"+title , this , null // the browser is the frame , false // NOT the reader screen , 1 // fixed to center the title , false // no paging indicator marks , false // no page position footer , false // not zoomable ); titlePanel.textAlign = _p_rs_db.CENTER; this.add("North", titlePanel); } } } bodyPanel = new _p rs_db ( article , this , null // the browser is the frame , false // NOT the reader screen , maxColumns // completely automatic , tme // use paging indicator marks , false // no page position footer , true // zoomable ); this.add("Center", bodyPanel); String b = getParameter("frameType"); if(b != null) { b = b.toUpperCase(); if (b.equals("LINE")) { frameSize = 1 ; frameType = LINE; } if (b.equals("FLAT")) { frameSize = 1; frameType = FLAT; } if (b.equals("RAISED")) { frameSize = 2; frameType = RAISED; } if (b.equals("DROPPED")){ frameSize = 2; frameType = DROPPED;} if (b.equals("ETCHED")) { frameSize = 4; frameType = ETCHED; } } String w = getParameter("frameSize"); if (w != null) try { frameSize = Math.max ( Integer .parselnt(w) , 1 ); } catch (NumberFormatException nf) {} switch (frameType) { case LINE: insets.bottom = frameSize; break; case FLAT: case RAISED: case DROPPED: case ETCHED: insets.top = frameSize; insets. left = frameSize; insets.bottom = frameSize; insets.right = frameSize; } } public Insets insets() { remm insets; } public boolean mouseDown(Event evt, int x, int y) { // dbg("ez_html.mouseDown()"); if (frame != null) { showStatus(RS); } else { showStatus(CS); } return tme; } public boolean mouseEnter(Event evt, int x, int y) { showStatus(ZM); remm true; } public boolean mouseExit(Event evt, int x, int y) { showStatus(_p_rs_db.MT); return tme; } public boolean mouseMove(Event evt, int x, int y) { showStatus(ZM); return tme; } public boolean mouseUp(Event evt, int x, int y) { // dbg("ez_html.mouseUp()"); if (frame != null) { // dbg("ez_html.mouseUp(): restoring _f_ rs _db"); frame.toFrontO; } else { // dbg("ez_html.mouseUp(): making new _f_rs_db"); showStatus(WS); frame = new _f_rs_db ( title , article , this , 15 // max columns , tme // present markers , tme // present footer ); } remm tme; } public final void paint(Graphics g) { // dbg("applet.paint()"); int i; Dimension d = size(); if (g != null) switch (frameType) { case LINE: { g.setColor(getForeground()); for (i = 0; i < frameSize; i++) g.drawLine(0,d.height-i-l,d.width-i-l,d.height-i- 1); } break; case FLAT: { g.setColor(getForeground()); for (i = 0; i < frameSize; i++) g.drawRect(i,i,d.width-2*i-l,d.height-2*i-l); } break; case RAISED: case DROPPED: case ETCHED: { boolean raise = frameType=RAISED; int R = (getForeground().getRed()+ getBackground().getRed() )/2; int G = (getForeground().getGreen()+getBackground().getGreen())/2; int B = (getForeground().getBlue()+ getBackground().getBlue() )/2; g.setColor(new Color(R,G,B)); for (i = 0; i < frameSize; i++) { if (frameType = ETCHED) raise = i >= frame Size/2; g.draw3DRect(i,i,d.width-2*i-l,d.height-2*i-l, raise); } if (frameType = ETCHED) { g.setColor(getForeground()); g.drawLine(0,0,frameSize/2,frameSize/2); g.drawLine(d.width- frameSize,d.height-frameSize,d.width-frameSize/2,d.height-frameSize/2); g.setColor(getBackground()); g.drawLine(frameSize/2,frameSize/2,frameSize,frameSize); g.drawLine(d.width-frameSize/2,d.height- frameSize/2,d.w_dth-l,d.__eight-l); } else { g setColor((frameType==RAISED) 9 getBackground() getForeground()), g drawLme(0,0,frameSize,frameSize), g setColor((frameType==RAISED) getForeground() getBackground()), g drawLιne(d width- frameSιze,d heιght-frameSιze,d wιdth-l,d heιght-l), } } } } public void setBackColor(Color color) { this backColor = color, } public void setBackImage(Image image) { this backlmage = image, } public void setBaseURL(URL baseURL) { this baseURL = baseURL, } public void setForeColor(Color color) { this foreColor = color, } public void setLmkColor(Color color) { this linkColor = color, } public void setTιtle(Stπng title) { this title = title, } public void update(Graphιcs g) { // fillRect is NOT performed here to eliminate blank screen boredom during offscreen drawing // g setColor(getBackground()), // g fillRect(0, 0, width, height), // g setColor(getForeground()), pamt(g), } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc All Rights Reserved * an object to read html documents and parse head content * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java awt *, import java io *, import java net *, import java util *, public class _o_ht_db extends Object { private ez_html ez_HTML = null, private final static Strmg alert_0 = "PLEASE READ - A Java ", private final static Strmg alert_l = "Exception has occuned ", private final static String alert_2 = "Most likely, there has been a transmission failure with one or more applet files A Refresh or Reload command on your browser will sometimes lead to a successful download ", private final static Strmg alert_3 = "An attempt to read a local file has been detected' In order to read this article, you must download the applet using hyper-text transport protocols (http // ) from a web server Please try again usmg http with a valid URL ", pπvate final static String alert_4 = "If the problem persists, please contact the Web Master ", public final static String BL = " ", public final static String BS = "<base", public final static Strmg HF = "href, public final static Strmg MT = "", public final static Strmg PR = "<p>", private static final void dbg(Stπng s) { if (debug) System out pπnfln(s), } private static boolean debug = tme, // Print debugging mfo 9 public static Stπng getArtιcle(Strmg fileName, ez html ez_HTML) { Strmg article = MT, if (fileName '= null) try // new URL, etc { URL url = new URL(ez_HTML getDocumentBase(), fileName), InputStream is = url openStream(), BufferedlnputStream bis = new BufferedΙnputStream(ιs), int len = 0, byte buffer[] = new byte[512], StrmgBuffer pageText = new StπngBuffer(), while ((len = bis read(buffer)) > 0) pageText append(new Strmg(buffer,0,O,len)), bis close(), is close(), boolean isHTML = fileName toLowerCase() endsWιth(" htm") || fileName toLowerCase() endsWιth(" html"), // other indicators would be more helpful if (isHTML) // protect literal sections from stripping { StrmgBuffer articleBuffer = new StrmgBuffer(), Vector pieces = new Vector(50), // Strmg segments of pageText distinguished by filtering Vector status = new Vector(50), // Boolean status of each segment tme of filtering is needed Strmg MCtext = pageText toStπngO, Strmg LCtext = MCtext toLowerCase(), // the plamtext tag preempts all subsequent tags mt plaintext = LCtext ιndexOf("<plaιntext>"), if (plamtext > -1) // rare a deprecated tag by HTML 3 2 { pieces addElement(MCtext substnng(0,plaintext)), status addElement(new Boolean(true)), // filtering is needed pieces addElement(hneCanon(MCtext substrmg(plamtext), false)), status addElement(new Boolean(false)), // filtering is complete } else { pieces addElement(MCtext), status addElement(new Boolean(true)), // filtering is needed } // <textarea> </textarea> & <pre> </pre> ranges are taken literally while (status sιze() > 0) { if (((Boolean)status firstElement()) booleanValue()) // filtering needed { MCtext = (Stπng)pιeces firstElementO, LCtext = MCtext toLowerCase(), Strmg TE = "</textarea>", String PE = "</pre>"; t began, ended; if ((ended = LCtext.ιndexOf(TE)) > -1 && (began = LCtext.lastIndexOf("<textarea", ended)) > -l) { ended += TE length(); // inclusive terminus pieces.setElementAt(MCtext.substnng(0,began), /* replace origmal */ 0); status.setElementAt(new Boolean(trae), /* filtering needed */ 0); pieces. ιnsertElementAt(lιneCanon(MCtext.substrmg(began, ended), false), 1); status.msertElementAt(new Boolean(false), /* filtering complete */ 1); pieces. msertElementAt(MCtext.substrmg(ended), 2); status. ιnsertElementAt(new Boolean(true), /* filtering needed */ 2); } else if ((ended = LCtext.ιndexOf(PE)) > -l && (began = LCtext.lastIndexOf("<pre",ended)) > -l) { ended += PE.length(), // inclusive terminus pieces.setElementAt(MCtext.substrmg(0,began), /* replace original */ 0), status. setElementAt(new Boolean(true), /* filtering needed */ 0); pieces. ιnsertElementAt(lmeCanon(MCtext.substrmg(began, ended), false), 1); stams msertElementAt(new Boolean(false), /* filtering complete */ 1); pieces. ιnsertElementAt(MCtext.substπng(ended), 2); stams. ιnsertElementAt(new Boolean(true), /* filtering needed */ 2); } else // filter it as html & tack it on { artιcleBuffer.append(lmeCanon(MCtext, tme)), // filtering complete: tack it on pιeces.removeElementAt(O); // remove original stams removeElementAt(O), // remove origmal } } else // filtering is complete- tack it on { artιcleBuffer.aρρend((Stπng)pιeces.firstElement()), pιeces.removeElementAt(O), stams removeElementAt(O), } } article = htmlBodyText(artιcleBuffer toStπng(), ez_HTML), } else { article = htmlBodyText(lmeCanon(pageText.toStπng(), false), ez_HTML), } } catch (MalformedURLException mu) { StrmgBuffer msg = new StrmgBuffer(); msg.append(alert_0).append("Malformed URL ").append(alert_l).append(alert_2).append(alert_4); article = msg.toStnngO; Strmg e = "Could not open "+fileName; ez_HTML.showStatus(e), System. out.prmtln(e+". "+mu); } catch (IOException io) { StrmgBuffer msg = new StπngBufferO ; msg.append(alert_0).append("Input Output").aρpend(alert_l).aρpend(alert_2).append(alert_4); article = msg.toStnngO; Stπng e = "Could not open "+fileName; ez_HTML.showStatus(e); System.out.pnntln(e+": "+ιo); } catch (SecuπtyException se) { StrmgBuffer msg = new StπngBufferO; msg.append(alert_0).append("Secuπty ").append(alert_l).append(alert_3).append(alert_4); article = msg.toStringO; Strmg e = "Could not open "+fileName; ez_HTML.showStatus(e); System.out.pnntln(e+" "+se); } else { StrmgBuffer msg = new StrmgBuffer(); msg.append(alert_0).append("Input Output").append(alert_l); msg.append("No article file specification was detected! "); msg.aρpend(alert_2).append(alert_4), article = msg.toStnngO, Strmg e = "No fileName specified"; ez_HTML.showStatus(e), System.out.pπntln(e), } remm article; } public static Stnng htmlBodyText(Strιng itsText, ez_html ez HTML) { Stnng newText = new Stπng(ιtsText); String LCtext = newText.toLowerCaseO; J l°°k f° r [<!—• — >] html comments and eliminate them Strmg CE = "— >"; int began, ended = LCtext.ιndexOf(CE), while (ended > -l) // the first end-of-comment { began = LCtext.lastIndexOf("<!~",ended), // its (prior) start-of-comment if (began > -1) { ended += CE.length(); // inclusive terminus StrmgBuffer text = new StπngBufferO, text.append(newText.substπng(0,began)); // preceedmg text text.append(newText.substπng(ended)), // succeedmg text newText = text.toStrmg(), LCtext = newText.toLowerCaseO; ended = LCtext.ιndexOf(CE), } else { ended = -1, // format enor exit path } } // look for [<tιtle...>tιtle text</tιtle...] began = LCtext.ιndexOf("<tιtle"); if (began > -l) { began = LCtext.ιndexOf(">",began)+l , // start of title if (began > 0 && began < LCtext.length()) { ended = LCtext.indexOf("</title",began); if (ended > -l) { ez_HTML.setTitle(newText.substring(began,ended)); } } } began = LCtext.indexOf(BS); if(began > -l) { began += BS.length(); ended = LCtext.indexOf(">",began)+l ; // end of base if (ended > 0 && ended < LCtext.length()) { String itsSpec = _0_tg_db.getTagAttribString(newText.substring(began,ended),HF); try { ez_HTML.setBaseURL(new URL(ez_HTML.getDocumentBase(),itsSpec)); } catch (MalformedURLException m) { ez_HTML.setBaseURL(null); } } } // look for [<form...>table specs</form...] recursively number document forms & elements String fb = _p_rs_db.PF + "form"; String fe = _p rs db.PF + _p_rs_db.SL + "form" + _p rs_db.SF; int start, formNumber = 0; ended = LCtext.indexOf(fe); // the first end-of-form began = LCtext.lastIndexOf(fb, ended); // its (prior) start-of-form start = LCtext.indexOf(_p_rs_db.SF, began); // its start-of-form endpoint while (-1 < began && began < start && start < ended) { formNumber++; start += _p_rs_db.SF.length(); // start-of-form content range start point int trail = ended + fe.length(); // beginning of trailing content String orig_tag = LCtext.substring(began,start);// just the original form tag _o_fm_db theForm = new _o_fm_db(formNumber, orig tag); ez_HTML.getFormDB().newForm(theForm); String formContent = newText.substring(start, ended); String newContent = theForm.replaceContent(formContent); StringBuffer text = new StringBuffer(); text.append(newText.substring(0,began)) // preceeding text, excluding original form tag .aρpend(newContent) // new form range content (modified elements plus orig html content) .append(newText.substring(trail)); // succeeding content text, excluding original end form tag ended -= trail - began; // this was dropped ended += newContent.length(); // this was added newText = text.toString(); LCtext = newText.toLowerCase(); ended = LCtext.indexOf(fe, ended); // the next end-of-form began = LCtext.lastIndexOf(fb, ended); // its (prior) start-of-form start = LCtext.indexOf(_p_rs_db.SF, began); // its start-of-form endpoint } // look for [<table...>table specs</table...] recursively: load and replace specs String TE = "</table>"; ended = LCtext.indexOf(TE); int tableNumber = 0; while (ended > -1) // the first end-of- table { began = LCtext.lastIndexOf("<table",ended); // its (prior) start-of-table if (began > -l) { ended += TE.length(); // inclusive terminus tableNumber++; // dbg("! - new table ("+tableNumber+"): range = ("+began+", "+ended+")"); _p_tb_db newTable = new _p_tb_db ( newText. substring(began,ended) , new Integer(tableNumber) , ez HTML ); ez_HTML.getTableDB().addTable(newTable); StringBuffer text = new StringBuffer(); text.append(newText.substring(0,began)) // preceeding text .append(newTable.addCaption(true)) // superior caption, if any .append(newTable.addCaption(false)) // inferior caption, if any, in superior position .append(_p_rs_db.PF) .append(_p_rs_db.TB) // private table tag .append(_p_rs_db.BL) .append(_p_rs_db.VL) .append(_p_rs_db.EQ) .append(newTable.theTableNumber) .append(_p_rs_db.SF) // substi te text, e.g. <tblt value=l> // .aρpend(newTable.addCaption(false)) // inferior caption, if any; shifted to superior position .append(newText.substring(ended)); // succeeding text newText = text.toStringO; LCtext = newText.toLowerCaseO; ended = LCtext.indexOf(TE); } else { ended = -1; // format enor exit path } } // look for [<body...>body text</body...] began = LCtext.indexOf("<body"); if (began > -1) { int body = LCtext.indexOf(">",began)+l ; // start of body if (body > 1 && body < LCtext.length()) { // parse body text attributes String tagText = LCtext.substring(began+l,body-l); ez_HTML.setLinkColor( _o_tg_db.parseColorValue( _o_tg_db.getTagAttribString( tagText, "link" ), OxOOOOff)); ez_HTML.setForeColor( _o_tg_db.parseColorValue( _o_tg_db.getTagAttribString( tagText, "text" ), ez_HTML.getForeColor().getRGB())); ez_HTML.setBackColor( _o_tg_db.ρarseColorValue( _o_tg_db.getTagAttπbStnng( tagText, "bgcolor"), ez HTML getBackColor().getRGB())); Strmg fileName = _o_tg_db.getTagAttπbStrmg(tagText, "background"), if (fileName != null) { ez_HTML.setBackImage(ez_HTML.getImageDB() fetchImage(fileName)), } ez_HTML.setForeground(ez_HTML.getForeColor()), ez HTML setBackground(ez_HTML.getBackColor()), ended = LCtext.ιndexOf("</body",body); ιf (ended > -l) { remm newText substrmg(body,ended), // nice foπnatting } } } remm newText, } public static Strmg lmeCanon(Stnng itsText, boolean isHTML) { if (itsText == null || ιtsText.length() = 0) remm itsText, Strmg newSeparator = isHTML 9 BL PR, // target retum code Strmg searchSeparators[] = // replacable retum codes { "\n"+"\r" // chr(lθ), chr(13) , "\r"+"\n" // chr(13), chr(lθ) , 'V' // chr(13) , 'V // chr(lθ) , "\f ' // chr(12) // , "\t" // chr( 99 ) }, Strmg newText = new Stπng(ιtsText), for (mt I = 0, l < searchSeparators. length; ι++) // replace old with new { Stnng oldSeparator = new Stπng(searchSeparators[ι]), newText = replaceStπng(newText,oldSeparator,newSeparator), } mt oldLen = newText length(), newLen = 0, if (isHTML) do // prune double spaces && paragraph codes { oldLen = newText length(); newText = replaceStπng(newText,BL+BL,BL), newText = replaceStπng(newText,PR+PR,PR), newLen = newText.length(), } while (oldLen > newLen), else newText = replaceStπng(newText,"\t"," "), remm newText, } private static Strmg replaceStrmg ( String theStrmg // original string , String oldStπng // replace-ee , Strmg newStnng // replace-or ) { char[] tag = new char[l], Strmg piece = MT, theTag = MT, StringBuffer out = new StπngBufferO; mt oldlndex = -1, oldEnd = 0, n = 0; mt oldLength = oldStπng.length(), boolean newWhite = newStrmg.equals(BL); while ((oldlndex = theStrιng.ιndexOf(oldStrιng, oldEnd)) > -1) { piece = theStrιng.substrιng(oldEnd,oldIndex); // got it? get it 1 good... out.append(pιece); // add the piece before the next old stnng // don't convert returns mto white space after tags (browser fashion) if (newWhite && (n = out.length()) > 0) { tag[0] = out.charAt(n-l); theTag = new Strmg(tag), } if ('(newWhite && theTag.toLowerCase().equals(">"))) out append(newStrmg); // get the replacement oldEnd = oldlndex + oldLength, // skip to the end of this old stπng } // nothmg more to replace if (oldEnd < theStrmg. length()) { piece = theStrmg. substπng(oldEnd), out append(pιece), // add the piece after the last old string } remm out toStπng(). } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved * object with static methods to parse html tags * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java awt *; public class _o_tg_db extends Object { public static final mt getTagAhgnment ( Strmg tagText , mt itsDefault ) { remm getTagAhgnment(tagText, _p_rs_db.AL, itsDefault), } public static final int getTagAhgnment ( Stnng tagText , Stπng attπb , mt itsDefault ) { String itsAlignment = getTagAttπbStπng(tagText, attπb); if (itsAlignment '= null) { itsAlignment = ιtsAhgnment.toLowerCase(); if (ιtsAlιgnment.equals("left")) retum _p_rs_db.LEFT; if (itsAlignment equals("center")) return _p_rs_db.CENTER; if (itsAlignment equals("πght")) remm _p_rs_db RIGHT, if (itsAlignment equals("top")) remm _p_rs_db.TOP, if (ιtsAhgnment.equals("mιddle")) remm _p_rs_db.MIDDLE; if (itsAlignment equals("bottom")) remm _p_rs_db.BOTTOM; } remm itsDefault; } public static final int getTagAttπblnt ( Strmg tagText , Stπng attrib , mt itsDefault ) { Strmg value = getTagAttπbStrmg(tagText, attπb), if (value = null) remm itsDefault; else remm parselnt(value, itsDefault), } public static final Strmg getTagAttπbStnng ( Strmg itsText , Strmg attrib ) { String tagText = itsText toLowerCase(); int l = tagText.ιndexOf(attnb), L = attπb.lengthO; // look for source attribute if (1 > -1) { mt a = tagText.ιndexOf(_p_rs_db.EQ, 1 + L) + 1, // look for "=" assignment command if (0 < a && a < I + L + 2) // avoid assignment confusion { String search = "\"V \t\n\r>", // quotes position < 2 ιntj = a, m = 0, // start after "=" character int n = tagText. length(), while < n // skip single quote or whitespace or close tag && (m = search.mdexOf(tagText.charAt(j))) > 0) j++; if (j < n) { ιf(m == 0) // double quote, match for balance { m = tagText.ιndexOf(search charAt(m),j+l); ιf(m > -1) return ιtsText.substπng(j+l,m), } // attribute is not enclosed in double quotes, use whitespace to delimit mt k =j+l; while (k < n // skip until any quote or whitespace or close tag && search ιndexOf(tagText.charAt(k)) = -l) k++; retam ιtsText.substπng(j,k).tπm(); } } } remm null; } public static final Color getTagColor ( Strmg tagText // lower case , mt defaultRGB ) { remm ρarseColorValue(getTagAttπbStrmg(tagText, "color"), defaultRGB); } public static final mt getTagFontlndex ( String tagText , mt defaultlndex ) { String sizeStrmg = getTagAttπbStπng(tagText, _p_rs_db.SZ); if (sizeStπng == null) remm defaultlndex; int itsSizelndex = defaultlndex; if (sιzeStπng.startsWιth("+")) try {itsSizelndex = defaultlndex + Integer.parseInt(sιzeStπng.substπng(l)),} catch (NumberFormatException nf) {} else if (sιzeStπng.startsWιth("-")) try {itsSizelndex = defaultlndex - Integer.parseInt(sιzeStπng.substrmg(l));} catch (NumberFormatException nf) {} else try {itsSizelndex = Integer.parseΙnt(sιzeStrmg),} catch (NumberFormatException nf) {} remm Math max(Math.mιn(ιtsSιzeIndex,16),0), // max mdex value for readerFontSize anay } public static final mt getTagPerCenfWιdth(Stπng tagText) { Strmg width = getTagAttπbStπng(tagText, "width"); if (width != null) try { if (wιdth.endsWιth("%")) return - Integer.parselnt(wιdth.substrmg(0,wιdth.length()-1)); else remm Integer parselnt( width), } catch (NumberFormatException nf) { } retum 0; } public static final int getTag Width ( String tagText , mt defaultWidth ) { int itsWidth = defaultWidth; String width = getTagAttπbStπng(tagText, "width"); if (width != null) try { if (wιdth.endsWιth("%")) its Width = lnteger.parselnt(width.subsrring(0,width.length()- l))*defaultWιdth/100; else itsWidth = Integer.parselnt( width); itsWidth = Math.mm(ιtsWιdth,defaultWidth); } catch (NumberFormatException nf) {} retum its Width; } public static final Color parseColorValue ( Stnng colorValue , mt defaultRGB ) { mt rgb = defaultRGB; if (colorValue != null) { if (colorValue.startsWιth("#")) { try {rgb = Integer.parseInt(colorValue.substrιng(l), 16);} catch (NumberFormatException nf) {} } else // try to interpret the named color { if (colorValue. equals("black")) rgb = 0x000000; else if (colorValue.equals("red")) rgb = OxffOOOO; else if (colorValue.equals("green")) rgb = OxOOffOO; else if (colorValue.equals("blue")) rgb = OxOOOOff; else if (colorValue.equals("yellow")) rgb = OxffffOO; else if (colorValue.equals("magenta")) rgb = OxffOOff; else if (color Value.equals("cyan")) rgb = OxOOffff; else if (colorValue.equals("whιte")) rgb = Oxffffff; else if (colorValue.equals("hghtGray")) rgb = OxcOcOcO; else if (color Value.equals("gray")) rgb = 0x808080; else if (colorValue.equals("darkGray")) rgb = 0x404040; else if (colorValue. equals("ριnk")) rgb = Oxffafaf; else if (colorValue. equals("orange")) rgb = 0xffc800; else // maybe a hex number after all (w/o preceeding # sign) try {rgb = Integer parseInt(colorValue, 16);} catch (NumberFormatException nf) {} } } retum new Color(rgb); } public static final mt parselnt ( Strmg value , int itsDefault ) { try { remm Integer .parselnt( value), } catch (NumberFormatException nf) { return itsDefault; } } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc All Rights Reserved * a pagable panel to display multicolumn text and graphics * HTML tag parsmg honors the following commands and attributes * " <a>...</a> anchor tag * href relative or absolute url for hyperlink * " <address>...</address> address (new italic paragraph) * " <applet>. .</applet> applet tag & range: range is hidden, applet is not launched * " <b>...< b> bold * " <basefont>. .</basefont> basic font size for document; </basefont> reverts to 4 * sιze=value relative or absolute index size adjustment * " <bιg> ..</bιg> increase font size one step * " <blockquote>...</blockquote> blockquote (left & right margin indentation) * " <br>... new paragraph, no extra halfspace * alιgn=type left, center, right * " <center> .</center> center justify * " <cιte>...</cιte> citation (italic) * " <code>...</code> code (monospaced) * " <dιr>. .</dιr> unordered directory list * type=bullet type circle, square, or disc * " <dd> . </dd> definition list definition component * " <dl>.. </dl> unordered (non-bulleted) definition list * " <dt>. .</dt> definition list term component * " <em> ..</em> emphasis (italic) * " <font>...</font> font color and size; </font> reverts to normal * color=color rgb or color name * sιze=value size index value * " <form>.. </form> form specification domain * actιon=url server contact for response * enctype=encodιng element value coding system * method=style either get or post * " <hr> horizontal rule * ahgn=type left, center, right * sιze=pιxels vertical rale size * noshade sets flat rounded rect rale * wιdth=value or % specify width up to column width value * " <hl. .6>...<lhl...6>, headmg levels 1 thru 6 * ahgn=type left, center, right * " <ι>...</ι> italic * " <ιmg> insert .gif or jpeg image * ahgn=type bottom, middle, or top * src=url image url * " <ιnput> form mput element specification * ahgn=type top, middle, or bottom (image) * border=n pixel border thickness (image) * checked marks radio or checkbox initially selected * maxlength=n max # of chars to accept (file or password) * name=name passed to designated url * sιze=n max # of chars to display (file or password) * src=url image url * type=type button, checkbox, file, hidden, image, password, radio, reset, submit, text * value=stπng passed to designated url * " <kbd>...</kbd> keyboard (monospaced) * " <lι>... list item * type=bullet type for unordered- circle, square, or disc * type=number type for ordered: A, a, I, l, or 1 * start=ιnt ovenidmg ordered list number * " <menu>...</menu> unordered menu list * type=bullet type circle, square, or disc * " <ol>...</ol> ordered (nested) list * type=number type A, a, I, l, or 1 * start=ιnt ovenidmg ordered list number * " <optιon>...</optιon> pop-up input list element definition * selected initially select element * value=stnng passed to designated url (mstead of <optnon> contents) * " <p>...</p> new paragraph, extra halfspace * ahgn=type left, center, right * " <plamtext> plamtext (rendered literally, with monospaced font): no terminal * " <pre>...</pre> pre-formatted text (rendered literally, with monospaced font) * " <select>...</select> pop-up input list specification domain * multiple allow multiple selections * name=name passed to designated url * sιze=n number of items to display * " <small>...</small> decrease font size one step * " <stnke>...</strike> stnkethrough text * " <strong>...</strong> strong (bold) * " <sub>...</sub> subscript * " <sup>...</sup> superscript * " <table>...</table> table tag & range (replaced with hot image) * " <textarea>...</textarea> text mput area specification domain * cols=n number of characters to display in a row * name=name passed to designated url * rows=n number of lmes to display m area * " <tt>...</tt> teletype (monospaced) * " <u>...</u> underline * " <ul>...</ul> unordered (nested) list * type=bullet type cucle, square, or disc * " <var>...</var> variable (italic) * " <!-- —> html comments (stripped out) * @author Everett Stoub %I%, %G% */ import java.awt.*; import java.awt.rmage *, import java.applet.*; import java.net.*; importjava.io.*; import java.util *; public final class _p_rs_db extends Panel { public final static mt LEFT = 0; // position public final static int CENTER = 1; // position public final static mt RIGHT = 2; // position public final static mt TOP = 3, // position public final static int MIDDLE = 4, // position public final static int BOTTOM = 5, // position pubhc final static mt POSITION = 7, // osition mask public final static int UNDERLINE = 8, // text pubhc final static int STRIKETHRU = 16, // text pubhc fmal static int SUBSCRIPT = 32, // text pubhc final static int SUPSCRIPT = 64, // text public final static mt HYPERLINK = 128, // text public final static mt LEFTINDENT = 256, // text pubhc final static mt RIGHTINDENT = 512, // text pubhc final static mt HIDDENTEXT = 1024, // text public final static int UNORDERLIST = 2048, // text public final static mt ORDEREDLIST = 4096, // text pubhc final static Strmg AD = "address", pubhc final static Strmg AL = "align", public final static Strmg AN = "a", public fmal static Strmg AP = "applet", public final static String BD = "b", public final static Strmg BF = "basefont", public final static Strmg BG = "big", public final static String BL = " ", pubhc final static Strmg BQ = "blockquote", pubhc final static String BR = "br", public final static Strmg CD = "code", public final static Strmg CJ = "center", public final static Stnng CK = "checked", pubhc final static String CR = "Courier", public final static String CT = "cite", public final static Strmg DD = "dd", public final static String DL = "dl", public final static Strmg DT = "dt", public final static Strmg DR = "dir", public final static Strmg EM = "em", public final static Strmg EN = "elementNumber", // private form element attribute public final static String EQ = "=", pubhc final static Strmg FM = "frmn", // private form tage public final static String FN = "formNumber", // private form attribute public final static Strmg FS = "TimesRoman", public final static Strmg FT = "font", public final static String HF = "href, public final static Strmg HN = "h", pubhc final static String HR = "hr", pubhc final static Stπng IM = "lmg", public final static Strmg IN = "mput", pubhc final static Strmg IT = "I", public final static Strmg KB = "kbd", pubhc final static String LI = "h", public final static Strmg ML = "menu", public final static Strmg MT = "", pubhc final static Strmg MX = "maxlength", public final static Strmg NM = "name", pubhc final static Stπng OL = "ol", pubhc final static Strmg OP = "option", pubhc final static Stπng PA = "p", public final static Stπng PF = "<", pubhc final static Stπng PR = "pre", public final static Strmg PT = "plamtext", public final static Strmg SB = "sub", public final static Stπng SF = ">", public final static Strmg SG = "strong", pubhc final static Strmg SK = "strike", pubhc final static Stnng SL = "/", pubhc final static Strmg SM = "small", public final static String SP = "sup", pubhc final static Strmg SR = "src", pubhc final static Strmg ST = "select", public final static String SZ = "size", public final static Strmg TA = "textarea", pubhc final static String TB = "tblt", // private table tag pubhc fmal static Strmg TP = "type", public final static Stnng TT = "tt", public final static String UL = "ul", public final static Strmg UN = "u", pubhc final static Strmg VA = "var", public final static Strmg VL = "value", pubhc final static Strmg ZI = "Release for fullsize image view ", pubhc final static Strmg ZM = "Click to zoom image ", pubhc final static String ZN = "Release for new reader screen ", pubhc final static String ZW = "Wait for new reader screen ", public final static String ZX = "Wait for fullsize image view ", public final static String ZZ = " ", pubhc ez_html ezJHTML = null, private _f_rs_db frame = null, private _o_nt_db charEntConverter = null, public Strmg readerContent = null, public Insets msets = new lnsets(0,0,0,0), pnvate mt maxColumns = 15, private Dimension mmimumSize = new Dιmensιon( 0, 0), private Dimension prefenedSize = new Dιmensιon(- 1,-1), private Image readerScreen = null, public boolean zoomable = false, pubhc mt readerFontSιze[] = { 8, 9,10,11,12,14,18,24,30,36,42,48,56,64,72,80,96}, public mt readerFootlndex = 2, // this 2-step decrement is also hard coded m stepFontSιze() public int readerSizelndex = 4, // default for on-webPage article rendermg public mt readerEn Width = 6, public Font readerScreenFont = null, public Font readerFooterFont = null, pubhc mt footerTextHeight = 12, public mt readerNumCols = 1 , public int readerLeading = 0, public mt readerPageNum = 1 , public int readerNumPages = 0, public int readerEstPages = 1 , public int readerEndlndex = 1 , public int readerStartlndex = 0, pubhc int readerTextLength = 0, public boolean readerScreenDirty = tme, II true if panel needs redraw public boolean readerFrame = false, // true if panel owned by frame public boolean readerHeader = false, // true if article begms with title public boolean readerMarker = false, // tme to present markers public boolean readerFooter = false, // tme to present footer public Vector readerPagelmage = new Vector(50), public Vector readerListAccts = new Vector(50), public Vector readerLinkHeads = new Vector(50), public Vector readerLinkRects = new Vector(50), pubhc Vector readerZoomHeads = new Vector(50), public Vector readerZoomRects = new Vector(50), public Vector readerPageComps = new Vector(50), pubhc Vector readerPageStart = new Vector(50), public Vector readerFontStart = new Vector(50), public Vector readerLinkStart = new Vector(50), public Vector readerTintStart = new Vector(50), public Vector readerTypeStart = new Vector(50), public Rectangle readerRect = new Rectangle(), // variables principally for pamtArea public mt border = 0, public mt padding = 0, public int spacing = 0, pubhc mt max Width = 0, public mt maxHeight = 0, public mt controlSize = 8, public boolean first Word = true, // cunent settmg public boolean lastColumn = false, // cunent setting public boolean lastRow = false, // cunent setting public boolean termDefimtion = false, pubhc boolean plamtext = false, // tme blocks tag parsmg pubhc Rectangle aheadRect = new Rectangle(), public boolean newListltem = false, // cunent page pending item public Vector listAccount = new Vector(), // cunent page (nested) list elements public Vector nkHeads = new Vector(), // cunent page public Vector linkRects = new Vector(), // cunent page public Vector zoomHeads = new Vector(), // cunent page public Vector zoomRects = new Vector(), // cunent page public Vector pageComps = new Vector(), // cunent page public Font textFont = null, // cunent settmg public FontMetπcs textMetncs = null, // cunent settmg public Color textColor = null, // cunent setting public mt textHeight = 0, // cunent settmg pubhc mt textHalfSpace = 0, // cunent settmg pubhc mt textAlign = LEFT, // cunent setting public mt colNum = 0, colWidth = 0, colSpacmg = 0, numColumns = 0, tagLength = 0, pubhc int endlndex = 0, nextWidth = 0, xb = 0, te = 0, xe = 0, yb = 0, ye = 0, public boolean markings = false, // cunent word public boolean underlining = false, // cunent word public boolean strikethrough = false, // cunent word pubhc boolean subscript = false, // cunent word public boolean supscnpt = false, // cunent word pubhc boolean hyperLink = false, // cunent word public boolean leftlndent = false, // cunent word public boolean πghtlndent = false, // cunent word pubhc boolean hidmgText = false, // cunent word pubhc boolean unorderList = false, // cunent word public boolean orderedList = false, // cunent word public URL hyperHead = null, // cunent word public Vector linelmages = new Vector(), // cunent row pubhc Vector data Values = new Vector(), // cunent row public Vector wordBlocks = new Vector(), // cunent row public Vector hyperLinks = new Vector(), // cunent row public Vector styleCodes = new Vector(), // cunent row pubhc Vector wordColors = new Vector(), // cunent row public Vector charsFonts = new Vector(), // cunent row public final boolean addBlock(Stπng tagBlock, Graphics g, boolean count) { // dbg("_p_rs_db("+readerContent substπng(0,Math mm(30,readerContent length()))+(readerContent length()<30 ?ZZ substπng(readerContent length()) MT)+") addBlock("+tagBlock+")"), if (tagBlock = null) remm true, StrmgTokenizer words = new StπngTokenιzer(tagBlock,BL,trae), // "tme" returns blanks (for counting) String nextWord = MT; while (words hasMoreTokens()) { nextWord = words. nextToken(); nextWidth = addWord(nextWord, false, count); if (te + nextWidth < xe - ιndent(true)) // it will fit on this lme, so add it on { te += nextWidth; } else // it won't fit if added, so draw the lme { endlndex += pamtRow(g, 1); // try to punch out prior pendmg lme elements te = xb + ιndent( false), ιf (yb > ye) // start a new column? { if (lastColumn) remm false; // no more columns left to fill nextColumn(); } if (nextWord.equals(BL)) // drop leading blank at new lme { endlndex++; // count the blank clearRowElements(); savePageData ( readerPageNum , endlndex ), // for the next page nextWord = MT; nextWidth = MT.length(); } te += nextWidth; // start a new line with, possibly, a monster! if (te > xe - ιndent(true) && prefenedSize width > 0) { prefenedSize. width = Math.max ( insets. left + lnsets.πght + 2 + nextWidth , prefenedSize width ), // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent length()))+(readerContent length()<30 ?ZZ.substrmg(readerContent.length())-MT)+") addBLock(); new ρrefenedSιze("+prefenedSιze.wιdth+","+prefenedSιze.heιght+") = resιze() + ("+(sιze().wιdth - prefenedSιze.wιdth)+","+(sιze() height - prefenedSize heιght)+"): nextWord = ["+nextWord+"]"); } while (te > xe - mdent(true)) // a monster, shorten it by breakmg the word { te = xb + mdent(false); // start the new line again Strmg monster = nextWord, // this would be a great place for a hyphenator nextWord = MT, int e = monster.length(); while (te + nextWidth > xe - ιndent(true) && e > 0) { // transfer letters back until fit (one line) clearRowElementsO; nextWord = monster.substnng(e-l,e) + nextWord; monster = monster.substπng(0,e-l); // dbg("... monster = ["+monster+"], nextWord = ["+nextWord+"]"); e = monster.length(); nextWidth = addWord(monster, true, count); } te += nextWidth; endlndex += paιntRow(g, 0); // try to punch out pendmg lme elements te = xb + ιndent(false); // start the new lme agam if (yb > ye) // start a new column? { if (lastColumn) remm false; // no more columns left to fill nextColumn(), } nextWidth = addWord(nextWord, false, count); te += nextWidth; } } } remm tme; // no more words in this tag block } private final mt addTag(Stπng itsText, Graphics g) { // dbg("_p_rs_db("+readerContent.substπng(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.length()):MT)+").addTag("+ιtsText+")"); Strmg tagText = itsText. toLowerCase(), mt addlndex = 0; tagLength = tagText length() + 2; if (tagText.equals(PA) // an html new paragraph tag w/o attributes || tagText. starts Wιth(PA+BL) // an html new paragraph tag w/ attributes || tagText. starts Wιth(BR) // an html new line tag || tagText.equals(AD)) // an html address tag { addlndex += paintRow(g,0); // try to punch out pending lme elements if (!startNewParagraph(tagText. starts Wιth(BR)?0- 1)) remm addlndex; textAlign = _0_tg_db.getTagAhgnment(tagText,(tagText.startsWιth(PA)?LEFT:textAlιgn)); if (tagText.equals(AD)) thιs.setFont(new Font(textFont getName(),textFont.getStyle() + Font.ITALIC,textFont.getSιze())), } else if (tagText equals(SL÷PA) // an html end paragraph tag || tagText.equals(SL÷AD)) // an html end address tag { addlndex += ρamtRow(g,0); // try to punch out pendmg lme elements textAlign = LEFT; // default alignment if (tagText.equals(SL+AD)) thιs.setFont(new Font(textFont.getName(),textFont.getStyle() - Font.ITALIC,textFont.getSιze())); } else if (tagText. starts Wιth(IM)) // an html image tag { mt newAddlndex = _o ιm_db.placeImage(tagText, ez_HTML, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex; else addlndex = —newAddlndex, // reverse bias } else if (tagText. starts Wιth(HR)) // an html horizontal rale tag { mt newAddlndex = _o_hr_db.placeRule(tagText, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex; else addlndex = —newAddlndex; // reverse bias } else if (tagText. starts Wιth(TB)) // a preprocessed html table tag { mt newAddlndex = _o tb_db.placeTable(tagText, ezJHTML, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex, else addlndex = — newAddlndex; // reverse bias } else if (tagText.startsWιth(HN) // an html headmg level tag && (tagText.length() < 3 // either without attributes || tagText substrmg(2,3).equals(BL))) // or with attributes to follow { addlndex += painfRow(g,0), // try to punch out pendmg lme elements if (istartNewParagraph(l)) retom addlndex; textAlign = _o_tg_db.getTagAhgnment( tagText, LEFT); thιs.setFont(new Font(textFont.getName(),Font.BOLD,readerFontSιze[readerSιzeIndex + 4 - _o_tg_db.parseInt(tagText.substrmg(l,2), 4)])); } else if (tagText.startsWιth(AN+BL)) // an html anchor tag { try { hyperHead = new URL(ez_HTML.getDocumentBase(), _o_tg_db.getTagAttπbStπng(tagText,HF)), hyperLink = true; textColor = ez HTML.hnkColor, } catch (MalformedURLException m) {}, } else if (tagText.equals(SL+AN)) // an html end anchor tag { if (hyperLink) { hyperHead = null; hyperLink = false, textColor = getForeground(); } } else if (tagText.equals(BD) // an html bold tag || tagText.equals(SG)) // an html strong tag { thιs.setFont(new Font(textFont getName(),textFont.getStyle() + Font BOLD,textFont.getSιze())), } else if (tagText.equals(SL+BD) // an html end bold tag || tagText equals(SL÷SG)) // an html end strong tag { thιs.setFont(new Font(textFont.getName(),textFont.getStyle() - Font.BOLD,textFont.getSιze())); } else if (tagText.equals(IT) // an html italic tag || tagText.equals(CT) // an html citation tag || tagText.equals(EM) // an html emphasis tag || tagText.equals(VA)) // an html variable tag { thιs.setFont(new Font(textFont.getName(),textFont.getStyle() + Font.ITALIC,textFont.getSιze())), } else if (tagText.equals(SL+IT) // an html end italic tag || tagText.equals(SL+CT) // an html end citation tag || tagText.equals(SL+EM) // an html end emphasis tag || tagText equals(SL+V A)) // an htinl end variable tag { thιs.setFont(new Font(textFont.getName(),textFont.getStyle() - Font.ITALIC,textFont.getSιze())); } else if (tagText. starts Wιth(FT)) // an html font tag { thιs.setFont(new Font(textFont.getName(),textFont.getStyleO,readerFontSιze[_o_tg_db.getTagFontIndex(tagText,readerSιzeInde x)]),_o_tg_db.getTagColor(tagText,textColor.getRGB())); } else if (tagText.equals(SL+FT) // an html end font tag || (tagText.startsWith(SL+HN) // an html end headmg tag && tagText.length() < 4)) { this.setFont(readerScreenFont,getForeground()), if (tagText. starts Wιth(SL+HN) // an html end heading level tag && tagText.length() < 4) { addlndex += paintRow(g,0); // try to punch out pendmg line elements if (!startNewParagraph(0)) retum addlndex; } } else if (tagText.startsWιth(LI) // an html list item tag || tagText.equals(DT) // an htinl definition term tag || tagText.equals(DD)) // an html definition component tag { mt newAddlndex = _o_h_db.addItem(tagText, itsText, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex; else addlndex = —newAddlndex; // reverse bias } else if (tagText. starts Wιth(UL) // an html unordered list tag || tagText.startsWιth(OL) // an html ordered list tag || tagText. starts Wιth(ML) // an html menu list tag || tagText.equals(DL) // an html definition list tag || tagText.startsWιth(DR)) // an html directory list tag { int newAddlndex = _o_h_db.addLιst( tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex; else addlndex = — newAddlndex; // reverse bias } else if (tagText. equals(SL÷UL) // an html end unordered list tag || tagText.equals(SL+OL) // an html end ordered list tag || tagText equals(SL+ML) // an html end menu list tag || tagText.equals(SL+DL) // an html end definition list tag || tagText equals(SL÷DR)) // an html end directory list tag { mt newAddlndex = _o_lι_db.endLιst(tagText, itsText, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex; else addlndex = —newAddlndex, // reverse bias } else if (tagText.startsWιth(IN)) { int newAddlndex = _o_fm_db addInput(tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex, else addlndex = —newAddlndex, // reverse bias } else if (tagText. starts Wιth(OP)) { int newAddlndex = _o_fm_db.addOptιon(tagText, itsText, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex; else addlndex = — newAddlndex, // reverse bias } else if (tagText equals(SL+OP)) { mt newAddlndex = _o_fm_db.endOptιon(tagText, itsText, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex; else addlndex = —newAddlndex, // reverse bias } else if (tagText starts Wιth(ST)) { mt newAddlndex = _o_fm_db.addSelector(tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex, else addlndex = —newAddlndex, // reverse bias } else if (tagText.equals(SL+ST)) { int newAddlndex = _o_fm_db endSelector(tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex, else addlndex = —newAddlndex, // reverse bias } else if (tagText. starts Wιth(TA)) { mt newAddlndex = _o_fm_db.addTextArea(tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex; else addlndex = —newAddlndex, // reverse bias } else if (tagText.equals(SL+TA)) { mt newAddlndex = _o_fm_db.endTextArea(tagText, itsText, this, ++addlndex, g); // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex, else addlndex = -newAddlndex, // reverse bias } else if (tagText starts Wιth(FM)) { mt newAddlndex = _o_fm_db.addForm(tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++newAddIndex, else addlndex = —newAddlndex, // reverse bias } else if (tagText.equals(SL+FM)) { int newAddlndex = _o_fm_db.endForm( tagText, itsText, this, ++addlndex, g), // bias for sign detect if (newAddlndex < 0) remm ++new Addlndex; else addlndex = —newAddlndex, // reverse bias } else if (tagText.equals(BG) // an html big tag || tagText equals(SL÷SM) // an htinl end small tag || tagText.equals(SM) // an html small tag || tagText.equals(SL+BG)) // an html end big tag { thιs.setFont(new Font(textFont getName(),textFont getStyle(),readerFontSιze[Math.max(Math mιn(getFontIndex(textFont,reader SιzeIndex)+((tagText equals(BG) || tagText equals(SL+SM)) 9 (l) (-l)),readerFontSιze length - 1),0)])), } else if (tagText.equals(BQ) // an html blockquote tag || tagText.equals(SL+BQ)) // an html end blockquote tag { leftlndent = πghtlndent = tagText.equals(BQ), } else if (tagText.equals(CJ) // an html center tag || tagText.equals(SL+CJ)) // an html end center tag { textAlign = tagText equals(CJ) 9 CENTER LEFT, } else if (tagTextequals(SK) // an html stπkethrough tag || tagText.equals(SL+SK)) // an html end stπkethrough tag { stπkethrough = tagText.equals(SK), } else if (tagText equals(UN) // an html underline tag || tagText.equals(SL+UN)) // an html end underlme tag { underlining = tagText equals(UN), } else if (tagText.equals(SB) // an html subscript tag || tagText equals(SL+SB)) // an html end subscript tag { subscript = tagText.equals(SB), } else if (tagText equals(SP) // an html superscript tag || tagText.equals(SL+SP)) // an html end superscript tag { supscπpt = tagText.equals(SP), } else if (tagText.equals(CD) // an html code tag monospaced font || tagText equals(PR) // an html pre tag monospaced font || tagText. equals(PT) // an html plamtext tag. monospaced font || tagText equals(TT) // an html teletype tag: monospaced font || tagText.equals(KB)) // an html keyboard tag- monospaced font { thιs.setFont(new Font(CR,Font.PLAIN,textFont getSιze())), if (tagText equals(PT)) plaintext = true, // if true, further tag parsing is blocked } else if (tagText.equals(SL+CD) // an html end code tag: standard font || tagText. equals(SL+PR) // an html end pre tag- standard font || tagText.equals(SL+TT) // an html end teletype tag: standard font || tagText.equals(SL+KB)) // an html end keyboard tag: standard font { thιs.setFont(new Font(FS,Font.PLAIN,textFont.getSιze())); } else if (tagText. starts Wιth(BF) // an html basefont tag || tagText.equals(SL+BF)) // an html end basefont tag { readerSizelndex = (tagText.startsWιth(BF))?_o_tg_db.getTagFontIndex(tagText,readerSιzeIndex)-4, readerScreenFont = new Font(FS, Font PLAIN, readerFontSizefreaderSizelndex]); thιs.setFont(readerScreenFont), } else // whatever has not been handled is ignored but counted { dbg("tag = <"+tagText+"> was not handled; tagLength = "÷tagLength), } linelmages.addElement(null); data Values. addElement ( new Rectangle ( tagLength // "x" mcrement for endlndex (character count) , 0 // "y" for vertical placement of image (ascent) , 0 // "width" element width on lme , 0 // "height" element drop below baseline (descent) ) ); wordBlocks.addElement(MT); hyperLιnks.addElement(null); styleCodes.addElement(styleCode()); wordColors addElement(textColor); charsFonts.addElement(textFont); remm addlndex, // the endlndex increment precipitated by this tag } private final mt addWord( String nextWord, boolean addHyphen, boolean count) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substπng(readerContent.length()):MT)+").addWord(\""+nextWord+"\")"); if (nextWord = null) remm 0; // nothmg to draw Strmg block = charEntConverter.convertCharacterEntιtιes(nextWord); if (hidmgText) block = MT; // cheap trip for hidden text if (addHyphen) block = block + "-", // don't count this: it's an added character mt wlm = textMetπcs.stπngWιdth(block), // all words are followed by spaces mt him = textHeight + readerLeading; if (firstWord && wlm > 0) { mimmumSize = new Dimension ( wlm + msets.left + lnsets.πght + 2 , him + msets.top + insets.bottom + 2 ); // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substπng(readerContent.length()):MT)+").addWord(): new mmιmumSιze("+mmιmumSιze.wιdtiι+", "+mιnιmumSιze.heιght+") for ["+nextWord+"]"); firstWord = false; } mt maxAscent = (textHeιght+2)*2/3 + readerLeading; // ascent and descent are wrong in some browsers linelmages.addElement(null), dataValues.addElement ( new Rectangle ( (count?nextWord.length():0) // "x" increment for endlndex (character count) , maxAscent // "y" for vertical placement of image (ascent) , wlm // "width" element width on line , him - maxAscent // "height" element drop below baseline (descent) ) ); wordBlocks.addElement(new Stnng(block)); hyperLιnks.addElement(hyperHead); styleCodes.addElement(styleCode()), wordColors.addElement( textColor), charsFonts.addElement(textFont), remm wlm; // the width of this element on the lme } public final int calculateReaderColumns() { remm calculateReaderColumns(thιs.sιze(). width); // the width of this panel } public final mt calculateReaderColumns(mt breadth) { // dbg("_p_rs_db("+readerContent.substπng(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substnng(readerContent.length()).MT)+").calculateReaderColumns(): breadth = "+breadth), int numCols = breadth / standardLineWidth(), // dbg("... breadth = "+breadth+" / numChar("+numChar+") / readerEnWιdth("+readerEnWιdth+") = numCols("+numCols+"), maxColumns = "+maxColumns); if (numCols < 1) numCols = 1; remm Math.mιn(numCols, maxColumns); } pubhc final void clearPage() { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substπng(readerContent.length()):MT)+").clearPage()"); newListltem = false, stAccount = new Vector(); unorderList = false; orderedList = false; hyperHead = null, hyperLink = false, lmkHeads = new Vector(); lmkRects = new Vector(), zoomHeads = new Vector(); zoomRects = new Vector(); removeAll(); } pubhc void clearRect(mt x, int y, int width, int height) { // oveπide, to retain transparency for background tiling if any } public final void clearRowElements() { hneImages.removeAHElements(); dataValues.removeAHElements(), wordBlocks removeAUElements(), hyperLιnks.removeAHElements(); styleCodes.removeAllElements(); wordColors.removeAUElements(), charsFonts.removeAHElements(); } public Dimension columnSιze() { return new Dιmensιon(effectιveWιdth(), readerRect height), } private final void dbg(Strmg s) { if (debug) System. out.ρrmtln(s), } private boolean debug = true, // Prmt debuggmg mfo? public final void dιspose() { // dbg("_p_rs_db("+readerContent.substπng(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ substrmg(readerContent.length()):MT)+").dιspose()"); if (readerScreen != null) readerScreen.flush(); } public final void doVιewerSιze(boolean smaller) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.lengthO):MT)+").doVιewerSιze("+smaller+") # comps = "+countComponents()), stepFontSιze(smaller); setReaderRect(); clearRowElements(); resetReaderVιew(); estιmateNumPages(); repamtReaderScreenO, } public int effectιveWιdth() { if ([markings || aheadRect.x = 0) return colWidth - mdent(trae) - mdent(false), else remm Math.min ( aheadRect x + ιndent(trae) , xb + colWidth ) - xb - mdent(trae) - ιndent( false); } public void estιmateNumPages() { // dbg("_p_rs_db("+readerContent.substrmg(0,Math mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ substπng(readerContent.length()).MT)+").estιmateNumPages()"); if (readerNumPages = 0) { if (readerEndlndex = readerTextLength) { readerEstPages = readerNumPages = readerPageNum, // dbg(". exact value = "+readerPageNum); } else // estimate number of pages { readerEstPages = Math round(0.5f + (float)readerPageNum * (float)readerTextLength / (floaf)readerEndIndex), // dbg("... est'd value = "+readerEstPages); } } else { readerEstPages = readerNumPages; // exact value is known // dbg("... exact value = "+readerNumPages); } } public final int getFontIndex(Font itsFont, mt itsDefault) { mt itslndex = 0, itsSize = ιtsFont.getSιze(); while (itslndex < readerFontSize.length && ltsSize != readerFontSrze [itslndex]) ιtslndex++; if (itslndex == readerFontSize.length) itslndex = readerSizelndex; // default remm itslndex, } public final boolean ιmageUpdate(Image lmg, mt flags, mt x, mt y, t w, mt h) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mm(30,readerContent.length0))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.length())-MT)+").ιmageUpdate(flags = "+flags+")"), if ( ( flags & ( ImageObserver.ALLBITS | ImageObserver FRAMEBITS ) ) '= 0) // this image is complete (at last) { Image pagelmage = (Image)readerPagelmage.elementAt(readerPageNum - 1); if (pagelmage '= null) pagelmage.flush(); readerScreenDirty = true, readerPageImage.setElementAt(null, readerPageNum - 1), setReaderRectO; clearRowElements(), repamtReaderScreenO, thιs.repamt(), return false; } else remm true; } public int ιndent(boolean right) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent length()<30 ?ZZ.substrmg(readerContent length()):MT)+") mdent("+πght+")"), if (right) { if (πghtlndent) { retum 2*readerEn Width, } } else { if (unorderList) { int tabs = hstAccount.sιze() > l?hstAccount.sιze() - 1:0; retum 2*(tabs + (termDefinition?l :0))*readerEn Width; } if (orderedList) { return 2*hstAccount.sιze()*readerEnWιdth; } if (leftlndent) { retum 2*readerEnWιdth; } } return 0, } public Insets msets() { // dbg("_p_tb_db("+theTableNumber+").msets()"); remm msets; } public final void loadPageData(mt pagelndex) { // dbg("_p_rs_db("+readerContent.substπng(0,Math.mιn(30,readerContent length()))+(readerContent length()<30 ?ZZ.substπng(readerContent length()):MT)+").loadPageData("+pageIndex+"). readerPageStart.sιze() = "+readerPageStart sιze()+", readerEndlndex = "+readerEndIndex+", lmelmages.sιze() = "+hnelmages.sιze()+", lιstAccount.sιze() = "+hstAccount.sιze()); Image pagelmage = (Image) readerPageImage.elementAt(pageIndex); hstAccount = (Vector) readerListAccts.elementAt(pagelndex); lmkHeads = (Vector) readerLinkHeads.elementAt(pagelndex); lmkRects = (Vector) readerLinkRects.elementAt(pagelndex); zoomHeads = (Vector) readerZoomHeads.elementAt(pagelndex), zoomRects = (Vector) readerZoomRects.elementAt(pagelndex), pageComps = (Vector) readerPageComps elementAt(pagelndex), readerStartlndex = ((Integer) readerPageStart.elementAt(pageIndex)).ιntValue(); hyperHead = (URL) readerLinkStart elementAt(pagelndex); this.restoreStyle ((Integer) readerTypeStart.elementAt(pageΙndex)); this.setFont ((Font) readerFontStart.elementAt(pagelndex) ,(Color) readerTintStart.elementAt(pagelndex)); if (pagelmage != null) readerScreen = pagelmage; } pubhc final Dimension mιnιmumSιze() { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substtmg(readerContent.length()):MT)+").mmιmumS_ze(''+mmιmumSιze.wιdth+","+mmιmumSιze.heιght +")"); remm mmimumSize; } public boolean mouseDown(Event evt, mt x, mt y) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mm(30,readerContent.length()))+(readerContent.length0<30 ?ZZ.substπng(readerContent length()):MT)+").mouseDown("+x+","+y+")"); if ( freaderFrame && zoomable && readerContent.length() > 0 ) { Component ancestor = getParent(), if (ancestor != null) { if (ancestor instanceof ez html) { retum false; } else if (ancestor mstanceof_p_tc_db) { while (ancestor != null) { if (ancestor instanceof _f_tb_db && ((_f_tb_db)ancestor).justDraggιng) { retum false, } ancestor = ancestor.getParent(); } } } ez_HTML.showStatus(ZN); } else for (int l = 0; l < zoomRects.sιze(); ι++) { if (zoomRects. elementAt(ι) instanceof Rectangle && ((Rectangle)zoomRects.elementAt(ι)).ιnsιde(x,y)) { if (zoomHeads. elementAt(ι) instanceof String) { ez_HTML.showStatus(ZI); } retum tme; } } retum super.mouseDown(evt, x, y); } public boolean mouseMove(Event evt, int x, mt y) { for (mt I = 0; I < lmkRects. sιze(); ι++) if (lmkRects. elementAt(ι) instanceof Rectangle && lmkHeads. elementAt(ι) instanceof URL && ((Rectangle)hnkRects.elementAt(ι)).ιnsιde(x,y)) { ez_HTML.showStatus(((URL)lιnkHeads.elementAt(ι)).toStπng()), retum true, } for (mt l = 0; l < zoomRects. sιze(); i++) if (zoomRects. elementAt(ι) mstanceof Rectangle && zoomHeads. elementAt(ι) instanceof Strmg && ((Rectangle)zoomRects.elementAt(ι)).ιnsιde(x,y)) { ez HTML.showStatus(ZM); remm true; } if ( zoomable && readerContent. length() > 0 ) { ez_HTML.showStatus(ez_HTML.ZM); remm trae; } ez_HTML.showStatus(_p rs_db.MT); remm super mouseMove(evt, x, y); } public boolean mouseUp(Event evt, int x, int y) { // dbg("_p_rs_db("+readerContent.substπng(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substnng(readerContent length()):MT)+").mouseUp() "); for (mt 1 = 0; K lιnkRects.sιze(); ι++) { if (lmkRects elementAt(ι) instanceof Rectangle && lmkHeads.elementAt(ι) instanceof URL && ((Rectangle)hnkRects.elementAt(ι)).msιde(x,y)) { ez_HTML.getAppletContext().showDocument ( (URL)lιnkHeads.elementAt(ι) . " blank" // opens new page m (new, if cooperative) browser window ); remm trae; } } if ( 'readerFrame && zoomable && readerContent length() > 0 ) { Strmg title = null; Component ancestor = getParent(); if (ancestor != null) { if (ancestor instanceof ez html) { remm suρer.mouseDown(evt, x, y), } else if (ancestor instanceof _p_tc_db) { boolean fmdTitle = true; while (ancestor != null) { if (ancestor instanceof _p_tb_db && fmdTitle) { title = ((_p_tb_db)ancestor).theCaptιon, fmdTitle = false; } if (ancestor instanceof _f_tb_db && ((_f_tb_db)ancestor).justDraggmg) { retum super.mouseDown(evt, x, y); } ancestor = ancestor.getParent(); } } } // dbg("... makmg new _f_rs_db"); ez_HTML.showStatus(ZW); _f_rs_db panelFrame = new _f_rs_db ( title , readerContent , ez HTML , 15 // max columns , trae // present markers , trae // present footer ), remm trae; } else for (ιnt ι = 0; ι < zoomRects. sιze(); ι++) { if (zoomRects. elementAt(ι) instanceof Rectangle && ((Rectangle)zoomRects.elementAt(ι)).ιnsιde(x,y)) { if (zoomHeads. elementAt(ι) instanceof Strmg) { ez_HTML.showStatus(ZX); _o_ιm_db.zoomImage((Strmg)zoomHeads.elementAt(ι), ez_HTML), } retum tme; } } remm super.mouseUp(evt, x, y); } pubhc final void nextColumn() { // dbg("_p_rs_db("+readerContent.substnng(0,Math.mm(30,readerContent.length()))+(readerContent.length0<30 ?ZZ.substrmg(readerContent.length()):MT)+").nextColumn(): old colNum = "+colNum); colNum++; // finished another column lastColumn = colNum = numColumns - 1 ; yb = readerRect.y; // local baselme of first lme xb += colSpacmg; // local left edge of the column area te += colSpacmg; // local end of text xe += colSpacmg, // local right edge of the column area } pubhc final void paιnt(Graphιcs g) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substπng(readerContent.length()):MT)+") paιnt(g): lsEnabled = "+ιsEnabled()+", isShowmg = "+ιsShowmg()+", lsVahd = "+ιsVahd()+", is Visible = "+ιsVιsιble()); if (readerScreenDirty) { if (readerScreen != null) readerScreen.flush(); readerScreen = createlmage(thιs.sιze() width, thιs.sιze().heιght), Graphics q = thιs.readerScreen.getGraphιcs(); paιntScreen(q); // adds components (paintArea) for this page & saves them q.dιspose(); readerScreenDirty = false; readerPageImage.setElementAt(readerScreen, readerPageNum - 1); thιs.ιnvalιdate(); thιs.vahdate(); } else if (this. countComponents() != pageComps.sιze()) // restore components { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent length()<30 ?ZZ.substπng(readerContent.length()):MT)+").paιnt(g): removeAll() "); thιs.removeAll(), for (mt I = 0; 1 < pageComρs.sιze(); ι++) { _p_tb_db table = (_p_tb_db)pageComps.elementAt(ι); // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length0))+(readerContent.length()<30 ?ZZ substπng(readerContent.length()).MT)+") paιnt(g) addmg table "+table theTableNumber); thιs.add(table), // table. show(), //just in case it was hidden } } ιf (g '= null) { g.drawImage(readerScreen,0,0,this); // thιs.vahdate(); } } private final int paintArea // returns string index of first non-drawn character ( Graphics g , int beginlndex , String textContent , mt numCols ) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substnng(readerContent.length()):MT)+").paιntArea(begιnIndex = "+begmlndex+")"); // long time = System.cunentTuneMιlhs(); mt endText = textContent.length(); endlndex = beginlndex; numColumns = numCols; colNum = 0; int colMargin = 2*readerEnWιdth; // 2 n-spaces between cols colWidth = (readerRect.width - (numColumns-l)*colMargm)/numColumns, colSpacmg = colWidth + colMargin; Strmg nextWord = MT; xb = readerRect.x; // local left edge of the column area te = xb + ιndent( false); // end position of this line's words & graphics xe = xb + colWidth; // local right edge of the column area nextWidth = 0; yb = readerRect y, // local starting top of first lme ye = readerRect y + readerRect.height, // local maximum bottom of last line // dbg("... yb = "+yb+"(mιtιally), ye = "+ye); lastColumn = colNum = numColumns - 1 ; lastRow = false; controlSize = textHeιght*2/3, if (markings) setMarkers(g, controlSize), clearRowElements(); StrmgTokemzer tagBlocks = new StπngTokenizer // break up the text into normal tagBlocks (textContent.substrmg(begmIndex),PF,true); // final true returns token on next call draw while (tagBlocks.hasMoreTokens() && !(yb > ye && lastColumn)) { // tag block to follow Strmg tagBlock = tagBlocks.nextToken(PF), // [body text],[<tag text>body text], ,[<tag text>body text] // handle all html tag instructions if ( [plaintext && tagBlock.equals(PF)) // an html "<" (PF) tag prefix 9 { Strmg tagText = tagBlocks.nextToken(SF), // should be tag text if (tagBlocks.hasMoreTokens()) tagBlock = tagBlocks.nextT oken(); // should be ">" (SF) tag suffix else tagBlock = MT; // syntax enor if (tagBlock.equals(SF)) { int endlncr = addTag(tagText, g); // accounts for any pamtRow() indexing if (endlncr < 0) { endlndex -= endlncr; // account for what was actually done break draw, // incomplete tag management (no room for it) } else { endlndex += endlncr; // been there, done that, what's next } tagBlock = MT; // tagText handled, transfer text capture } else // recover from syntax enor { tagBlock = PF + tagText + tagBlock; } } // handle all html text content if (!tagBlock.equals(PF) && !tagBlock.equals(MT)) // not an html tag? { if (!addBlock(tagBlock,g,trae)) break draw; } } // end of draw // no more tagBlocks endlndex += paιntRow(g, 0); // try to punch out pendmg lme elements while (endlndex < endText && textContent.substπng(endIndex++).startsWιth(BL)), // skip blanks savePageData(readerPageNum, endlndex); // for the next page estιmateNumPages(), ιf (markmgs) paιntMarkers(g, controlSize); // dbg("area pamt duration = "+(System.cunentTιmeMιlhs()-tιme)+" ms."), remm endlndex, } public final void paιnfMarkers(Graphιcs g, int controlSize) { if (g == null) remm, g.setColor(getForeground()); if (! readerFrame) // right anow { int x = aheadRect x + aheadRect width - 2 , y = aheadRect.y + aheadRect.heιght/2; for (mt anow = 0; anow < controlSize; aπow++) { g.drawLιne(x - anow,y + anow/2,x - anow,y - aπow/2), } } } public final synchronized mt paιntRow(Graphιcs g, mt retain) { // dbg("jp_rs_db("+readerContent.substrιng(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substπng(readerContent.length()).MT)+").paιntRow(g, "+retaιnCount+") @ ("+xb+","+yb+"), left indent = "+mdent(false)+", right mdent = "+ιndent(true)+"; stack("+dataValues.sιze()+")"); int retainCount = Math.max(0,retam); // ensure reasonable results int maxAscent = 0; // measure the max baselme ascent for output mt maxDescent = 0; // measure the max baselme descent for output mt line Width = 0; // measure the full width of this output int indexincr = 0; // measure the number of characters represented by this lme for (int l = 0; l < data Values. sιze() - retainCount; ι++) { Rectangle d = (Rectangle)dataValues.elementAt(ι), maxAscent = Math max(maxAscent, d y), maxDescent = Math max(maxDescent, d height), line Width += d width, } yb += maxAscent + maxDescent, while (yb > ye) // start a new column 9 { // dbg(" yb > ye"), if (lastColumn) retum mdexincr, // no more columns left to fill nextColumn(), yb += maxAscent + maxDescent, } mt itsStyle = LEFT, if (styleCodes sιze() > 0) { if ( g '= null && wordColors sιze() > 0 && charsFonts sιze() > 0 ) { g setColor((Color)wordColors firstElement()), g setFont((Font)charsFonts firstElement()), } restoreStyle(ιtsStyle = ((Integer)styleCodes firstElement()) mtValue()), } mt x = xb + mdent(false) + textAhgn*(effectιveWιdth() - hneWιdth)/2, mt y = yb - maxDescent, // go up to baselme and draw above & below it while ( linelmages sιze() > retamCount && data Values sιze() > retamCount && wordBlocks sιze() > retainCount && hyperLmks sιze() > retainCount && styleCodes sιze() > retainCount && wordColors sιze() > retamCount && charsFonts sιze() > retamCount ) // draw all unretamed elements { Rectangle d = (Rectangle)data Values firstElement(), Image anOfflmage = (Image)hnelmages firstElement(), String wordBlock = null, if (wordBlocks firstElement() instanceof Strmg) wordBlock = (Strmg)wordBlocks firstElement(), // dbg(" anOfflmage "+(anOfflmage'=null 9 "' " "=")+"= null, wordBlock ="+(wordBlock'=null 9 (wordBlock=MT 9 "= MT" " "+wordBlock) "= null")+","), if (anOfflmage '= null // either a graphic or a table image && wordBlock '= null) { // dbg(" drawlmage()"), Image oπglmage = ez_HTML getImageDB() fetchlmage(wordBlock), if (oπglmage getWιdth(ez_HTML) > anOfflmage getWιdth(ez_HTML)) { zoomHeads addElement(wordBlock), zoomRects addElement(new Rectangle(x, y - d y, anOfflmage getWιdth(ez_HTML), anOfflmage getHeιght(ez_HTML))), } if (g '= null) g drawlmage(an0fflmage, x, y - d y, this), anOfflmage flush(), } else // table reference stored m wordBlocks if (wordBlocks fϊrstElement() mstanceof_p_tb_db) { __p tb_db theTable = (_p_tb_db) wordBlocks firstElement(), theTable valιdate(), max Width = Math max(max Width, theTable prefenedSιze() width), maxHeight = Math max(maxHeιght, theTable prefenedSιze() height), } else if (MT — wordBlock) // controllmg tag { ιf(g '= null) { g setColor((Color)wordColors firstElement()), g setFont((Font)charsFonts firstElement()), } restoreStyle(ιtsStyle = ((Integer)styleCodes firstElement()) mtValue()), // dbg(" update style("+ιtsStyle+") newListltem = "+newLιstItem+", unorderList = "+unorderLιst+", orderedList = "+orderedLιst), } else if (wordBlock '= null) { // dbg(" drawStπng(["+wordBlock+"],x,y), itsStyle = "÷itsStyle), if (newListltem && hstAccount sιze() > 0) { ((Pomt)hstAccount firstElement()) x++, // bookkeepmg count if (unorderList) { _o_lι_db drawBullet(thιs, x, y, g), } if (orderedList) { _o_h_db drawLabel(thιs, x, y, g), } } boolean doUnderlrne = (itsStyle & UNDERLINE) '= 0 || (itsStyle & HYPERLINK) '= 0, boolean doLmeStπke = (itsStyle & STRIKETHRU) '= 0, mt shift = 0, if ((itsStyle & SUBSCRIPT) '= 0) shift += (textHeιght+3)/4 - 1, if ((itsStyle & SUPSCRIPT) '= 0) shift -= (textHeιght+3)/4 - 1 , if (g '= null) { if (doUnderlrne) g drawLme(x, y + 2 + shift, x + d width, y + 2 + shift), if (doLineStπke) g drawLrne(x, y - (textHeιght+3)/4 + shift, x + d width, y - (textHeιght+3)/4 + shift), g drawStrmg( wordBlock, x, y + shift), } if ( hyperLmks sιze() > 0 && hyperLmks firstElement() '= null ) { // if (debug && g '= null) g drawRect(x, y - d y + shift, d width + readerEnWιdth/2, d y + d height), lmkHeads addElement(hyperLιnks firstElement()), lmkRects addElement(new Rectangle(x, y - d y + shift, d width + readerEnWιdth/2, d y + d height)), } } x += d width, mdexincr += d x, if ( linelmages sιze() > 0 && data Values sιze() > 0 && wordBlocks sιze() > 0 && hyperLinks.size() > 0 && styleCodes.size() > 0 && wordColors. size() > 0 && charsFonts.size() > 0 ) { linelmages.removeElementAt(O); dataValues.removeElementAt(O); wordBlocks.removeElementAt(O); hyperLinks.removeElementAt(O); styleCodes.removeElementAt(O); wordColors.removeElementAt(O); charsFonts.removeElementAt(O); } else { /* dbg ( "unexpected size(s) in paintRow("+retain+"):\n" + "linelmages. size() " + linelmages. size() + "\n" + "data Values. size() " + dataValues.size() + "\n" + "wordBlocks.size() " + wordBlocks. size() + "\n" + "hyperLinks.sizeO " + hyperLinks.sizeO + "\n" + "styleCodes.size() " + styleCodes.size() + "\n" + "wordColors.size() " + wordColors.size() + "\n" + " charsFonts. size() " + charsFonts.size() + "\n" ); */ } } max Width = Math.max(max Width, line Width); maxHeight = Math.max(maxHeight, yb - readerRect.y); savePageData(readerPageNum, endlndex + indexlncr); // for the next page // dbg("... final stack("+data Values. size()+")"); remm indexlncr; } private final synchronized void paintScreen(int width) // test (null) paint for sizing { // dbg("paintScreen("+width+")"); Dimension s = getToolkit().getScreenSize(); int wide = width + insets. left + insets.right + 2; // one column wide int tall = s.height; // super column height Rectangle r = new Rectangle ( 0 , 0 , Math.min(wide, s.width) // set to indicated width , tall ); paintScreen(null, r); } private final synchronized void paintScreen( Graphics g) { // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").paintScreen(g): getBackground() = "+getBackground()); Rectangle r = bounds(); // set to full area (this.bounds()) paintScreen(g, r); } private final synchronized void paintScreen( Graphics g, Rectangle r) { // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").paintScreen(g): getBackground() = "+getBackground()); setReaderRect(r); // set to full area (this.bounds()) if (g != null) { g.setColor(getBackground()); g.fillRect(0, 0, r.width, r.height); for (int i = 0; i < border; i++) g.draw3DRect ( i + spacing/2 , i + spacing/2 , r.width - 1 - spacing - 2*i , r.height - 1 - spacing - 2*i , false ); // background fill, if requested Image background = ez_HTML.getBackImage(); if (background != null) { Point p = this.location(); int w = background.getWidth(this); int h = background.getHeight(this); if (w > 0 && h > 0) { int x = this.size().width; int y = this.size().height; for (int i = 0; i < x; i += w) { for (int j = 0; j < y; j += h) { g.drawImage(background,i-p.x,j-p.y,this); } } } } } clearPage(); maxHeight = 0; int numCols = calculateReaderColumnsO; if (numCols != readerNumCols) { readerNumCols = numCols; resetReaderView(); } if (readerFrame) readerLeading = 2; // make it more comfortable else readerLeading = 0; // make it more compact // paint the content area loadPageData(readerPageNum-l); // for the cunent page markings = readerMarker && ireaderFooter; readerEndlndex = paintArea ( g , readerStartlndex , readerContent , readerNumCols ); readerStartlndex = readerEndlndex - 1 ; estimateNumPages(); if (prefeπedSize.width < 0 || prefenedSize.height < 0) // set and forget { Dimension screenSize = getToolkit().getScreenSize(); prefenedSize.width = Math.min ( screenSize.width , Math.max ( minimumSize. width , insets. left + insets.right + 2 + maxWidth // single column format ) ); prefenedSize.height = Math.min ( screenSize.height , Math.max ( minimumSize.height , insets.top + insets.bottom + 2 + maxHeight * (colNum + 1) + (readerFooter?readerFontSize [readerFootlndex]* 3/2:0) ) ); dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").paintScreen(): new prefenedSize("+prefenedSize.width+","+prefenedSize.height+"); complete = "+(readerEndIndex = readerTextLength)+"; maxHeight = "+maxHeight+", readerNumCols = "+readerNumCols); } } public final Dimension prefeπedSize() { remm prefenedSize(standardLineWidth()); } public final Dimension prefenedSize(int prefLine Width) { if (prefenedSize.width < 0 || prefenedSize.height < 0) { resetReaderView(); paintScreen(prefLine Width); resetReaderView(); // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").prefenedSize("+prefenedSize.width+","+prefenedSize.height+" ) - from null screen layout"); remm prefenedSize; } else { // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").prefenedSize("+prefenedSize.width+","+prefenedSize.height+" ) - prior layout"); remm prefenedSize; } } public synchronized void removeAll() // ovenide, because some browsers fail here w/o layout manager { super.removeA_l(); int n = countComponents(); if(n > 0) this.invalidate(); while (n > 0) { Component c = getComponent(n-l); c.hide(); c.invalidateO; remove(c); n = countComponents(); } } public final void repaintReaderScreen() { // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").repaintReaderScreen()"); if (readerPageImage.elementAt(readerPageNum - 1) == null) { readerScreenDirty = true; } this.repaint(); } public final synchronized void resetReaderView() { // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").resetReaderView()"); readerStartlndex = 0; readerEndlndex = 1; readerNumPages = 0; readerEstPages = 1; readerPageNum = 1; readerPageImage.removeAHElements(); readerListAccts.removeAllElements(); readerL-nkHeads.removeAllElements(); readerLinkRects.removeAllElementsO; readerZoomHeads.removeAHElements(); readerZoomRects.removeAllElements(); readerPageComps.removeAHElements(); readerPageStart.removeAHElements() ; readerLinkStart.remove AUElements() ; readerTypeStart.removeAHElements() ; readerFontStart.remove AllElements() ; readerTintStart.removeAHElements(); clearPage(); maxWidth = 0; newListltem = false; plaintext = false; readerScreenDirty = trae; restoreStyle(O); this.setFont(readerScreenFont,getForeground()); savePageData(0, readerEndlndex); } public void reshape(int x, int y, int width, int height) { super.reshape(x, y, width, height); resetReaderView(); // dbg("_p_rs_db("+readerContent.substring(0,Math.min(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substring(readerContent.length()):MT)+").reshape("+x+", "+y+", "+width+", "+height+")"); repaint(); } public final void restoreStyle(Integer theStyleCode) { restoreStyle(theStyleCode.intValue()); } public final void restoreStyle(int itsStyle) { textAlign = (itsStyle & POSITION ); underlining = (itsStyle & UNDERLINE ) != 0; strikethrough = (itsStyle & STRIKETHRU ) != 0; subscript = (itsStyle & SUBSCRIPT ) != 0 && (itsStyle & SUPSCRIPT ) = 0; supscript = (itsStyle & SUPSCRIPT ) != 0 && (itsStyle & SUBSCRIPT ) = 0; hyperLink = (itsStyle & HYPERLINK ) != 0; leftlndent = (itsStyle & LEFTINDENT ) != 0, πghtlndent = (itsStyle & RIGHTINDENT) != 0; hidmgText = (itsStyle & HIDDENTEXT ) != 0; unorderList = (itsStyle & UNORDERLIST) != 0; orderedList = (itsStyle & ORDEREDLIST) != 0; } private final void savePageData(ιnt nextPagelndex, int cunEndlndex) { // dbg("j_rs_db("+readerContent.substπng(0,Math.mm(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.length()):MT)+").savePageData("+nextPageIndex+","+cunEndIndex+"): new = "-(-(readerNumPages == 0 && nextPagelndex == readerPageStart.sιze())+", readerEndlndex = "+readerEndIndex+", linelmages. sιze() = "+hnelmages.sιze()+"; hstAccount.sιze() = "+hstAccount.sιze()); if (readerNumPages == 0 && nextPagelndex = readerPageStart sιze()) // the first time reaching this page { readerPagelmage.addElement(null), // readerScreen is loaded by pamt(g) Vector cuπList = new Vector(hstAccount.sιzeO), for (int I = 0, I < hstAccount.sιze(), ι++) { Point p = (Poιnt)hstAccount.elementAt(ι), cunLιst.addElement(new Pomt(p.x, p.y)), } listAccount = cunList; readerLιstAccts.addElement(hstAccount); readerLmkHeads.addElement(new Vector()); readerLιnkRects.addElement(new Vector()); readerZoomHeads.addElement(new Vector()); readerZoomRects.addElement(new Vector()); readerPageComps.addElement(new Vector()); // components are added by placeTable(g) readerPageStart.addElement(new Integer( cunEndlndex - 1)), if (nextPagelndex > 0 && linelmages. sιze() > 0) // unpamted elements in stack { readerLιnkStart.addElement((URL)hyperLιnks.firstElement()), readerFontStart.addElement((Font)charsFonts.firstElement()); readerTmtStart.addElement((Color)wordColors.firstElement()), readerTypeStart.addElement((Integer)styleCodes.firstElement()); } else { readerLιnkStart.addElement(hyperHead); readerFontStart.addElement(textFont); readerTιntStart.addElement(textColor), readerTypeStart.addElement(styleCode()); } } else // update next page initial state vectors { readerPageStart.setElementAt(new Integer(cunEndIndex - 1), nextPagelndex); if (nextPagelndex > 0 && linelmages. sιze() > 0) // unpamted elements in stack { readerLrnkStart.setElementAt((URL)hyperLιnks.firstElement(), nextPagelndex); readerFontStart.setElementAt((Font)charsFonts.firstElement(), nextPagelndex), readerTmtStart.setElementAt((Color)wordColors.firstElement(), nextPagelndex); readerTypeStart.setElementAt((Integer)styleCodes.firstElement(), nextPagelndex); } else { readerLιnkStart.setElementAt(hyperHead, nextPagelndex); readerFontStart.setElementAt(textFont, nextPagelndex); readerTιntStart.setElementAt(textColor, nextPagelndex); readerTypeStart.setElementAt(styleCode(), nextPagelndex); } } } public void setAHFonts() { readerFooterFont = new Font(FS, Font PLAIN, readerFontSιze[readerFootIndex]); readerScreenFont = new Font(FS, Font.PLAIN, readerFontSize [readerSizelndex]); footerTextHeight = readerFontSιze[readerFootIndex]*5/4; setFont(readerScreenFont, getForeground()); readerEn Width = getFontMetπcs(readerScreenFont).strmgWιdth("n"), } public final void setFont(Font f, Color c) { textColor = c; fhιs.setFont(f); } pubhc final void setFont(Font f) { textFont = f, textMetπcs = getFontMetπcs(f); textHeight = f getSιze()*5/4, textHalfSpace = (textHeight + readerLeadmg)/2; // dbg("__p_rs_db("+readerContent.substπng(0,Math.mιn(30,readerContent length()))+(readerContent length()<30 ?ZZ.substπng(readerContent length()):MT)+").setFont() textHeight = "+textHeιght), } public synchronized final void setFontSιzeIndex(mt newSizelndex) { // dbg("_p_rs_db("+readerContent.substrmg(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.length()).MT)+").setFontSιze("+newSιzeIndex+"). # comps = "+countComponents()); readerSizelndex = newSizelndex; readerFootlndex = readerSizelndex - 2, readerSizelndex = Math.max(Math.ιmn(readerSιzeIndex,readerFontSιze. length - 1),0); readerFootlndex = Math.max(Math.mιn(readerFootIndex,readerFontSιze.length - 1),0), setAHFonts(), } public void setMarkers(Graphιcs g, int controlSize) { aheadRect reshape ( readerRect.x + readerRect width - 2 - (controlSιze+4)*l , readerRect.y + readerRect.height - 4 - controlSize , controlSize + 4 , controlSize + 4 ), } public void setReaderRect() { // dbg("_p_rs_db("+readerContent.substnng(0,Math.mιn(30,readerContent.length()))+(readerContent length()<30 ?ZZ substπng(readerContent.length()):MT)+").setReaderRect()"); setReaderRect(thιs.bounds()), } pubhc void setReaderRect(Rectangle r) { readerRect.reshape ( msets.left , insets.top , r width - 1 - msets.left - insets.right , r.height - 1 - insets.top - insets.bottom - (readerFooter readerFontSιze[readerFootIndex]*3/2:0) ), firstWord = true; // dbg("_p_rs_db("+readerContent substπng(0,Math mm(30,readerContent.length()))+(readerContent.length()<30 9 ZZ substπng(readerContent.lengthO) MT)+") setReaderRect("+r x+","+r y+","+r wιdth+","+r.heιght+") readerRect reshape("+readerRect.x+","+readerRect.y+","+readerRect.wιdth+","+readerRect.heιght+")"), } public final void setZoomable(boolean zoomable) { this.zoomable = zoomable, } public final mt standardLmeWιdth() { mt numChar = 30, // the control parameter: mm # of n's per line of text mt stndLineWidfh = numChar * readerEnWidth; // dbg("_p rs_db("+readerContent.substπng(0,Math.mιn(30,readerContent.length()))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.length()):MT)+").standardLmeWIdth() = "+stndLιne Width); remm stndLine Width; } public final boolean startNewParagraph(mt halfSpaces) { if (yb > readerRect.y) // unless we're at the top { yb += halfSpaces * textHalfSpace; // drop down to next baselme if (yb > ye) { // not enough room m this (partial?) column if (lastColumn) remm false; // no more columns left to fill nextColumn(); } } te = xb + ιndent( false); // start a new lme maxHeight = Math.max(maxHeιght, yb - readerRect y); remm trae, } pubhc void stepFontSιze(boolean smaller) { // dbg("_p_rs_db("+readerContent.substnng(0,Math.mm(30,readerContent length()))+(readerContent.length()<30 ?ZZ.substrιng(readerContent.length()):MT)+").stepFontSιze(smaller = "+smaller+")"); if (smaller) readerSizelndex—; else readerSιzeIndex++; setFontSizelndex(readerSizelndex), } public final Integer styleCodeO { retum new Integer ( textAlign + ((underlining) UNDERLINE :0) + ((stπkethrough) ? STRIKETHRU :0) + ((subscript && isupscπpt) ? SUBSCRIPT -0) + ((supscπpt && isubscπpt) 9 SUPSCRIPT :0) + ((hyperLink) ? HYPERLINK :0) + ((leftlndent) ? LEFTINDENT :0) + ((πghtlndent) ? RIGHTINDENT :0) + ((hidmgText) ? HIDDENTEXT :0) + ((unorderList) ? UNORDERLIST :0) + ((orderedList) ? ORDEREDLIST :0)); } public void update(Graphιcs g) { // fillRect is NOT performed here to eliminate blank screen boredom durmg offscreen drawing // g.setColor(getBackground()); // g.fillRect(0, 0, width, height), // g.setColor(getForeground()); pamt(g), } public _p_rs_db ( Strmg readerContent , ez html ez_HTML , _f_rs_db frame , boolean readerFrame , mt maxColumns , boolean marker , boolean footer , boolean zoomable ) { this ( readerContent , ez HTML , frame , readerFrame , maxColumns , marker , footer , readerFrame?new Color(239,239,239).ez_HTML.getBackColor() , readerFrame?Color.black:ez_HTML.getForeColor() , 0 // no border , 10 // no padding , 0 // no spacing , zoomable // zoomability ), } public _p_rs_db ( String readerContent , ez_html ez HTML , _f_rs_db frame , boolean readerFrame , mt maxColumns , boolean marker , boolean footer , Color panelBg , Color panelFg , mt border , mt padding , mt spacing , boolean zoomable ) { // dbg("_p rs_db("+readerContent.substπng(0,Math.mm(30,readerContent length()))+(readerContent.length()<30 ?ZZ.substrmg(readerContent.length()):MT)+") <mιt>\n"+readerContent), thιs.setLayout(null), this ez_HTML = ez_HTML; this. frame = frame; this readerFrame = readerFrame; this.readerHeader = ez_HTML.getTιtle() '= null; this.readerContent = readerContent; this.readerTextLength = readerContent.length(); this.charEntConverter = new _o_nt_db(); thιs.maxColumns = Math.max(l, maxColumns); this readerMarker = marker; this.readerFooter = footer; setBackground(panelBg); setForeground(panelFg); this.border = border, this.paddmg = padding; this spacmg = spacmg; this.zoomable = zoomable; insets.top = msets.left = border + padding + spacmg/2; msets bottom = insets.right = border + paddmg + spacing - spacing/2; setAHFonts(); if (readerFrame) { stepFontSιze(false); // larger font for reader screens } readerEnWidth = getFontMetπcs(readerScreenFont) strmg Wιdth("n"), } } /** * %W% %E% Everett Stoub * Copyright (c) '96- '97 ION Web Products, Inc All Rights Reserved * a frame for presentinginteractive multicolumn text and graphics * @author Everett Stoub %I%, %G% */ import java.awt.*; import java.applet.*, importjava.net.*; importjava.io.*, import java.lang.*, import java.util *; pubhc final class _f_rs_db extends Frame implements Runnable { public ez_html ez HTML = null; public _p_rs_db panel = null; public _p_pm_db locator = null, pubhc Panel control = null; public Panel subpanel = null; public Thread runner = null, pubhc mt messageNumber = 0; pubhc Label messageLabel = null; public boolean stopped = false; public Strmg[] message = { "About: EZ HTML Version 0.95al..." // , ".. Certified 100% Pure Java" , "...More mfo: 888.ION.JAVA" , "...URL: www.ionsystems.com" , "...Created by Everett Stoub" , "...(c)'97, ION Systems, Inc " }, private Strmg buttonNamef] = { "Next" . "Previous" , "Font +" , "Font -" // , "Home" }; pubhc Stπng CP = "Center"; pubhc void start() { if (runner = null) { runner = new Thread(thιs); ranner.start(); } } public void stop() { if (runner '= null && runner.ιsAlιve()) runner.stop(); runner = null, } pubhc void run() { while (runner != null) { if (messageNumber < message. length) messageLabel.setText(message[messageNumber++]); try { Thread.sleep(3000); } catch (InterruptedException e) {} } } public boolean actιon(E vent e, Object o) { if (e.target mstanceof Button) { if (o = (buttonName[0])) doVιewerRιght(); else if (o = (buttonName[l])) doVιewerLeft(); else ιf (o = (buttonName[2])) doVιewerSιze(false); else if (o = (buttonName[3])) doVιewerSιze(rrae); /* else if (o == (buttonName[4])) doVιewerHome(); */ messageLabel.setText(message[messageNumber = 0]); } remm false; } private final void dbg( Strmg s) { if (debug) System.out prmtln(s), } private boolean debug = false; // Print debugging info 9 /* public final void doVιewerHome() { // dbg("_f_rs_db.doVιewerHome()"); if (panel.readerPageNum > 1) { subpanel.remove(panel), panel.removeAll(); panel.readerPageNum = 1 , panel.loadPageData(panel.readerPageNum-l), subpanel.add(CP, panel), } panel.repaιntReaderScreen(), if (locator != null) { locator.repamt(), } } */ public final void do VιewerLeft() { // dbg("_f_rs_db doVιewerLeft()"); if (panel.readerPageNum > 1) { subpanel.remove(panel); panel.removeAll(); panel.readerPageNum—, panel loadPageData(panel.readerPageNum-l), subpanel.add(CP, panel); } panel.repamtReaderScreen(); if (locator != null) { locator.reρaιnt(); } } pubhc final void doVιewerRιght() { // dbg("_f_rs_db.doVιewerRιght(): readerPageNum = "+panel.readerPageNum+", readerEstPages = "+ρanel.readerEstPages); if (panel.readerPageNum < panel.readerEstPages) { panel.readerPageNum++, } else if (panel.readerNumPages = 0) { panel.readerNumPages = panel readerPageNum; } subpanel.remove(panel); panel.removeAll(); panel. loadPageData(panel.readerPageNum-l), panel repamtReaderScreenO; subpanel.add(CP, panel); if (locator != null) { locator ,repaιnt(); } } public final void doVιewerSιze(boolean smaller) { // dbg("_f_rs_db.doVιewerSιze(boolean "+smaller+")"); panel doVιewerSιze(smaller), subpanel remove(panel), panel.removeAll(), if (locator != null) { subpanel.remove(locator), panel.resize ( panel.sιze() width , panel. sιze(). height + locator. sιze(). height - locator prefenedSιze().heιght ), locator.move ( locator.locatιon().x , locator. locatιon().y + locator sιze().heιght - locator.prefenedSιze().heιght ); locator.resize ( locator.sιze().wιdth , locator.ρrefenedSιze().heιght ), subpanel.add("South", locator), locator.repaιnt(), } subpanel.add(CP, panel), } public synchronized void dιspose() { thιs.stop(), super.dιspose(), } public final boolean handleEvent(Event evt) { // dbg("_fχs_db handleEvent("+evt+")"), switch (evt.id) { case Event. WINDOW EXPOSE: panel requestFocus(), break, case Event. WINDOW_DEICONIFY: thιs.show(), break, case Event. WINDOW CONIFY: thιs.hιde(); break, case Event. WINDOW DESTROY: ez_HTML.dιsposeFrame(thιs), break, } remm super.handleEvent(evt); } public final boolean keyDown(Event evt, mt key) // note: keyUp is not utilized at all (missing m JDK 1.02 on Mac) { // dbg("_f_rs_db.keyDown("+evt+", "+key+")"); boolean down = key == Event.DOWN; switch (key) { // case EventHOME: doVιewerHome(); break; case Event.PGDN: case Event.RIGHT: doVιewerRιght(); break; case Event.PGUP case Event.LEFT: doVιewerLeft(); break; case Event.UP. case Event.DOWN: doVιewerSιze(down); break; default: remm false; } messageLabel.sefText(message[messageNumber = 0]); retum trae; } public final Dimension mιmmumSιze() { Dimension s = getToo-kιt().getScreenS ze(); if (debug) { s wιdth /= 2; s.height /= 2; } else { s.height - = 50; // hack for menus } Dimension b = control.mmιmumS-ze(); Dimension r = subpanel.mιnιmumSιze(), Dimension f = new Dιmensιon(Math.max(b. width, r.width), b.height + r.height), double fArea = f.height * f. width; double sArea = s.height * s.width, if (fArea > sArea) // more than the screen area { f. width = s.width, f.height = s.height; } else // adjust dimensions to screen aspect { f. width = (ιnt)Math.round(Math.sqrt(fArea * s.width / s.height)), f.height = (mt)Math round(Math.sqrt( fArea * s.height / s.width )); } s.width = Math.mιn(s width, f. width ); s.height = Mafh.mιn(s.heιght, f.height), remm s, } pubhc boolean mouseDown(Event evt, mt x, int y) { if (runner != null && ranner.ιsAlιve()) { if (runner != null && ranner.isAhveO) { if (stopped) { messageNumber = 0; runner.resume(); } else { runner.suspend(); } stopped = [stopped; } else { stopped = false; runner = new Thread(thιs); runner. start(); } } return false; } public final Dimension prefenedSιze() { Dimension s = getToolkιt().getScreenSιze(); if (debug) { s wιdth /= 2; s.height /= 2, } else { s height -= 50; // hack for menus } Dimension b = control.prefenedSιze(), Dimension r = subpanel.prefenedSrze(); Dimension f= new Dιmensιon(Math.max(b.wιdfh, r.width), b.height + r height); double fArea = f.height * f. width; double sArea = s.height * s.width, if (fArea > sArea) // more than the screen area { f.width = s.width; f.height = s.height, } else // adjust dimensions to screen aspect { f width = (ιnt)Math round(Math.sqrt(f Area * s.width / s.height)), f height = (mt)Math round(Math.sqrt(fArea * s height / s width )), } s width = Math mm(s.wιdth, f. width ); s.height = Math.mιn(s.heιght, f.height), remm s, } public synchronized void reshape(mt x, mt y, mt width, mt height) { messageLabel setText(message[messageNumber = 0]), super.reshape(x, y, width, height), } public void update(Graphιcs g) { // g setColor(getBackground()), // g fillRect(0, 0, width, height); // g.setColor(getForeground()); paιnt(g), } public _f_rs_db ( Strmg title , Strmg readerContent , ez html ezJHTML , mt maxColumns , boolean marker , boolean footer ) { super(tιtle); // dbg("_f rs_db.<mιt>"); thιs.ez_HTML = ez_HTML; thιs.setLayout(new BorderLayout()); subpanel = new Panel(); subpanel. setLayout(new BorderLayout()); thιs.add(CP, subpanel); this.panel = new _p_rs_db ( readerContent , ez HTML , this , tme , maxColumns , false // marker , false // footer , false // not zoomable ); this.panel.msets.left += 10; this.panel.msets.nght += 10; subpanel.add(CP, panel); if (footer) { locator = new _p_pm_db(panel, this); subpanel.add("South", locator); } // control.add(new Label("ION EZ HTML v0.94a6 ")); // [?n-major] [ n-mmor][ 9 n-tweak][ a-fix] control = new Panel(), control setBackground(Color.gray), control. setLayout(new FlowLayout(FlowLayout.LEFT)); thιs.add("South", control); for (mt 1 = 0, K buttonName. length; ι++) { Button b = new Button(buttonName[ι]), b.setBackground(Color white), control. add(b); } boolean mac = System.getPropertyC'os.name") equals("macos"), // control.add(new Label((mac?"©":"(c)")+'"97, ION Systems, Inc 888. ION. JAVA")); messageLabel = new Label(message[0]), control.add(messageLabel); thιs.pack(); // dbg("_f_rs_db.ιmt<>: thιs.sιze() = ("+thιs.sιze().wιdth+","+thιs.sιze().heιght+"), panel.sιze() = ("+panel.sιze().wιdth+","+panel.sιze() heιght+")"), thιs.show(); thιs.start(); } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc All Rights Reserved. * a simple panel to display page position and interactive markers * @author Everett Stoub %I%, %G% */ import java.awt.*; public final class _p_pm_db extends Panel { pπvate _p_rs_db panel = null; private _f_rs_db frame = null; pπvate mt controlSize = 8; public Rectangle aheadRect = new Rectangle(); // cunent page public Rectangle closeRect = new Rectangle(); // cunent page public Rectangle abackRect = new Rectangle(); // cunent page pπvate final void dbg(Stπng s) { if (debug) System.out.pnntln(s); } pnvate boolean debug = false; // Print debuggmg info? public final Dimension mimmumSize() { Strmg test = "Screen 00 of ~00"; remm new Dimension ( controlSize + 4 // marker width + ( panel != null ? panel.textMetπcs.stπngWιdth(test) : panel.readerEn Width * test.length() ) , Math.max ( panel footerTextHeight + 1 , controlSize + 4 // marker height ) ); } public boolean mouseUp(Event evt, mt x, mt y) { // dbg("_p_pm_db.mouseUp()"); if (aheadRect.ιnsιde(x, y)) { frame.doVιewerRight(); remm trae; } else if (closeRect.ιnsιde(x, y)) { frame.ez_HTML.disposeFrame(frame); retum true; } else if (abackRect.msιde(x, y)) { frame. do VιewerLeft(); return tme, } return false; } pubhc final void paιnt(Graphιcs g) { Rectangle r = thιs.bounds(); ιf (g != null) { g.setColor(panel.getBackground()); g.fillRect(0, 0, r.width, r.height); g.draw3DRect(0, 0, r.width - 1, r.height - 1, false), g.setColor(panel.getForeground()); g.setFont(panel.readerFooterFont), } controlSize = panel footerTextHeιght*2/3; setMarkers(g), paιntMarkers(g); StnngBuffer pi = new StrιngBuffer(); pI.append("Screen ").aρρend( Stnng valueOf(panel.readerPageNum)).append(" of "); if (panel.readerNumPages = 0) pl.append("~"); pI.append(Stπng.valueOf(panel readerEstPages)), Strmg pagelnfo = pI.toStπng(); mt mfo Width = getFontMetπcs(panel.readerFooterFont).stnngWιdth(pageInfo); int xLoc = (r.width - ιnfoWιdfh)/2; mt yLoc = r.height - panel.footerTextHeιght/5 - 1 ; if (g != null) g.drawStπng(pageInfo, xLoc, yLoc); } pubhc final void pamtMarkers(Graphιcs g) { if (g == null) remm, Rectangle r = thιs.bounds(), g.setColor(panel getForegroundO), if (panel readerPageNum > 1) // left anow { mt x = abackRect.x + 2 , y = abackRect y + abackRect heιght/2; for (int anow = 0; anow < controlSize; anow++) { g.drawLme(x + anow,y - anow/2,x + anow,y + anow/2), } } if (panel.readerFrame) // close box { mt x = closeRect.x + 2 , y = closeRect y + 2 , w = closeRect.width - 5 , h = closeRect.height - 5, g.drawRect( x, y, w, h), g.drawLme( x, y, x+w, y+h), g drawLιne(x+w, y, x, y+h), } if (panel.readerPageNum < panel.readerEstPages) // right anow { mt x = aheadRect.x + aheadRect.width - 2 , y = abackRect.y + abackRect.heιght/2; for (mt anow = 0; anow < controlSize; anow++) { g.drawLme(x - anow.y + anow/2,x - anow,y - anow/2); } } } public final Dimension prefenedSιze() { remm mmιmumSιze(); } pubhc void setMarkers(Graphιcs g) { Rectangle r = thιs.bounds(); mt w = thιs.sιze().wιdth; mt h = thιs.sιze() height; abackRect reshape ( w - 2 - (controlSιze+4)*3 , h - 4 - controlSize , controlSize + 4 , controlSize + 4 ), closeRect.reshape ( w - 2 - (controlSιze+4)*2 , h - 4 - controlSize , controlSize + 4 , controlSize + 4 ); aheadRect.reshape ( w - 2 - (controlSιze+4)* 1 , h - 4 - controlSize , controlSize + 4 , controlSize + 4 ); } pubhc void update(Graphιcs g) { // g.setColor(getBackground()), // g.fillRect(0, 0, width, height), // g.setColor(getForeground()), paιnt(g); } _p_pm_db(_p_rs_db panel, _f_rs_db frame) { this.panel = panel, this.frame = frame, } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * an object to store form element data * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt.*; importjava.net *; import java.util *; pubhc class _o_fe_db extends Object { public final static mt NONE = -1 ; pubhc final static int BUTTON = 0, public final static mt CHECKBOX = 1; public final static int FILE = 2; public final static int HIDDEN = 3; public final static mt IMAGE = 4; pubhc final static mt PASSWORD = 5; pubhc final static mt RADIO = 6; public final static mt RESET = 7; public final static mt SUBMIT = 8; pubhc final static mt TEXT = 9; pubhc final static mt SELECT = 10; public final static mt TEXTAREA = 11; // state vanables pubhc mt forrr-Number; // ez_HTML formsDB entry number (1,2,...) pubhc mt elemNumber; // the form's element number (1,2,...) pubhc mt tlndex, // input element type index public Strmg name; // I/O: element name to be passed to the designated form-processing application // twin value state variables. [0] - initial (for reset function) and [1] - cunent pubhc Strmg value[] = new Stπng[2]; // i/o: value strmg(s) to be passed to the designated form- processing application public Strmg acceptf] = new Stnng[2]; // state, list of file types for file mput selection pubhc boolean checked[][] = new boolean[2][]; // state: selector option or checkbox or radio selection state: trae for passmg name & value(s) pubhc mt maxlength[] = new ιnt[2]; // state: number of accepted characters to be passed from file, password, and text elements public boolean multiplef] = new boolean[2]; // state: multiple item selection capability m selector options list public URL src[] = new URL[2]; // mput: source url for image pubhc int ahgn[] = new ιnt[2]; // view: mdex for _p_rs_db top, _p_rs_db.mιddle, or _p_rs_db.bottom image alignment pubhc int border[] = new mt[2]; // view: width of image border mset in pixels public mt cols[] = new int[2]; // view: number of displayed characters across selector panes or textarea fields public mt rows[] = new mt[2], // view: number of displayed rows of textarea public mt sιze[] = new ιnt[2]; // view: number of displayed characters m file, password, and test fields, or rows of selector panes public _o_fe_db(ιnt formNumber, int elemNumber, String tagText) { dbg("new _o_fe_db("+formNumber+","+elemNumber+",["+tagText+"])"), this.formNumber = formNumber, this. elemNumber = elemNumber, this tlndex = _o_fe_db getTagAttπbTypeΙnt(tagText); this.name = _o_tg_db.getTagAttπbStπng(tagText, "name"); this value[0] = thιs.value[l] = _0_tg_db.getTagAttπbStπng(tagText, "value"), thιs.accept[0] = thιs.accept[l] = _o_tg_db.getTagAttπbStrmg(tagText, "accept"); } // static methods pπvate static final void dbg(Strmg s) { if (debug) System.out.prmtln(s); } pπvate static boolean debug = true, // Print debugging mfo? public static final mt getTagAttπbTypeInt(Strmg itsText) { String itsLabel = _o_tg_db.getTagAttπbStπng(ιtsText, "type"); if (itsLabel = null) { remm NONE, } Stnng lowLabel = ιtsLabel.toLowerCase(), if (lowLabel.equals("button")) remm BUTTON, else if (lowLabel.equals("checkbox")) remm CHECKBOX;else if (lowLabel.equals("file")) remm FILE, else if (lowLabel.equals("hιdden")) remm HIDDEN; else if (lowLabel.equals("ιmage")) remm IMAGE; else if (lowLabel.equals("password")) remm PASSWORD;else if (lowLabel.equals("radιo")) remm RADIO; else if (lowLabel.equals("reset")) remm RESET; else if (lowLabel.equals("submιt")) remm SUBMIT, else if (lowLabel.equals("text")) remm TEXT; else if (lowLabel.equals("select")) retum SELECT; else if (lowLabel.equals("textarea")) remm TEXTAREA;else remm NONE, } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved * an object to present html forms in panels * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *; importjava.io.*; importjava.net.*; import java.util *, public class _o_fm_db extends Object { public final static mt NONE = -1, public final static int GET = 0, public final static mt POST = 1; pubhc final static int STND = 2, public final static mt TEXT = 3; public final static mt DATA = 4; // state variables public int mlndex; // method mdex value public int elndex; // encode mdex value public Strmg action; // target for submit command pubhc int formNumber; // ez HTML formsDB entry number (1,2,...) public Vector formElements; // the elements of this form public Strmg replaceContent(Stπng formContent) { // create pπvate form attπbute: the form number StrmgBuffer formsTag = new StπngBufferO, formsTag. append(_p_rs_db.PF) .append(_p_rs_db.FM); // pπvate form tag StringBuffer formAttr = new StπngBufferO; formAttr.append(_p_rs_db.BL) ,append(_p_rs_db.FN) // private form attribute .append(_p_rs_db.EQ) .append(formNumber), // form number insertion string String newContent = formContent; Strmg LCnContent = newContent.toLowerCase(), // create private form element attnbutes: the form & element sequence numbers mt elemNumber = 0; Stnng ιnsert[] = { _p_rs_db.IN // mput elements (buttons, etc.) // , _p_rs_db.OP // selector option elements , _p_rs_db.ST // selector elements , _p_rs_db.TA // textarea elements } ; for (mt l = 0; K insert. length; ι++) { Strmg insertion = _p_rs_db.PF + ιnsert[ι]; mtj = LCnContent.ιndexOf(ιnsertιon); // the first of this kind of tag mt k = LCnContent.ιndexOf(_p_rs_db.SF, j); // its terminus while (-1 < j &&j < k) { elemNumber++; j += ιnsertιon.length(); k += _p_rs_db SF.length(), // post-tag content range start pomt // add this new element to this form formElements. addElement ( new _o_fe_db ( formNumber , elemNumber , LCnContent.substrmg(j,k) // the entire element input tag ) ); StringBuffer elemAttr = new StπngBuffer(), elemAttr.append(j)_rs_db.BL) .append(_p_rs_db.EN) ,append(_p_rs_db.EQ) .append(elemNumber) // element number insertion string .append(_p rs db.SF), StringBuffer text = new StrmgBuffer(); text.append(newContent.substnng(0,j)) // preceedmg text, including oπg input tag preface .append(formAttr.toStrmgO) // private form attribute .append(elemAttr.toStrmg()) // private element attribute append(newContent substrmg(k)), // succeeding text, excluding oπg input tag suffix newContent = text.toStπngO, LCnContent = newContent toLowerCase(), j = LCnContent ιndexOf( insertion, j); k = LCnContent.mdexOf(_p_rs_db SF, j); } } StringBuffer finalTag = new StrιngBuffer(), finalTag append(_ρ_rs_db.PF) append(_p_rs_db.SL) .append _pχs_db.FM) // private end form tag apρend(_p_rs_db.SF); StringBuffer output = new StπngBufferO; output.append(formsTag.toStπng()) .append(formAttr toStrmgO) .append(_p_rs_db.SF) .append(newContent) append(fmalTag.toStrmg()), remm output toStrmgO, } public mt sιze() { retum formElements sιze(); } public _o_fm_db(ιnt formNumber, Stnng formTag) { dbg("new _o_fm_db("+foπnNumber+",["+formTag+"])"); thιs.mlndex = _o_fm_db.getTagAttπbMethodInt(formTag); this.elndex = _o_fm_db getTagAttribEncodelnt(formTag), this.action = _o_tg_db.getTagAttπbStπng(formTag, "action"); this formNumber = formNumber, formElements = new Vector(lO), } // static methods private static final void dbg(Stπng s) { if (debug) System out prmtln(s), } private static boolean debug = trae, // Prmt debuggmg mfo? pubhc static mt addForm ( Strmg tagText , Strmg itsText , _p_rs_db panel , int addlndexValue , Graphics g ) { dbg("_o_fm_db.addForm(["+ιtsText+"],panel,"+addIndexValue+",g)"), int addlndex = addlndexValue, mt n = _°_tg_db getTagAttπbInt(tagText, _p_rs_db FN, 0), _o_fm_db form = panel ez_HTML.getFormDB() getForm(n), if (form = null) { remm -addlndex, } else { remm addlndex, } } public static mt addlnput ( Stnng tagText , String itsText , _p_rs_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db.addInput(["+ιtsText+"],panel,"+addIndexValue+",g)"); mt addlndex = addlndexValue; remm addlndex; } pubhc static mt addOption ( Stnng tagText , Strmg itsText , _p_rs_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db.addOptιon(["+ιtsText+"],panel,"+addIndexValue+",g)"), int addlndex = addlndexValue, remm addlndex, } public static mt addSelector ( Strmg tagText , Strmg itsText , _p_rs_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db.addSelector(["+ιtsText+"],panel,"+addIndexValue+",g)"), mt addlndex = addlndexValue; return addlndex; } pubhc static int addTextArea ( Strmg tagText , Strmg itsText , _p_rs_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db.addTextArea(["+ιtsText+"],panel,"+addIndexValue+",g)"), mt addlndex = addlndexValue, remm addlndex, } pubhc static int endForm ( String tagText , String itsText , _p_rs_db panel , int addlndexValue , Graphics g ) { dbg("_o_fm_db.endForm(["+ιtsText+"],panel,"+addIndexValue+",g)"), mt addlndex = addlndexValue, remm addlndex, } public static int endOption ( String tagText , Strmg itsText , _P_ r s_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db.endOptιon(["+ιtsText+"],panel,"+addIndexValue+",g)"), mt addlndex = addlndexValue; return addlndex, } pubhc static int endSelector ( Strmg tagText , Strmg itsText , _p_rs_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db endSelector(["+ιtsText+"],panel,"+addIndexValue+",g)"), int addlndex = addlndexValue; return addlndex, } public static mt endTextArea ( Strmg tagText , Strmg itsText , _pχs_db panel , mt addlndexValue , Graphics g ) { dbg("_o_fm_db.endTextArea(["+ιtsText+"],panel,"+addIndexValue+",g)"), int addlndex = addlndexValue, remm addlndex, } public static final int getTagAttπbEncodeInt(Stπng itsText) { Strmg itsLabel = _o_tg_db.getTagAttπbStrmg(ιtsText, "enctype"), if (itsLabel = null) { retum NONE; } Strmg lowLabel = ιtsLabel.toLowerCase(); if (lowLabel.equals("apphcatιon/x-www-form-urlencoded")) remm STND; else if (lowLabel.equals("text/plaιn")) remm TEXT, else if (lowLabel.equals("multιpart/form-data")) remm DATA; else remm NONE; } public static final mt getTagAttnbMethodInt(Stπng itsText) { Strmg itsLabel = _o_tg_db.getTagAttπbStnng(ιtsText, "method"), if (itsLabel == null) { remm NONE, } String lowLabel = ιtsLabel.toLowerCase(); if (lowLabel equals("get")) remm GET; else if (lowLabel.equals("post")) remm POST; else remm NONE, } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * an object to maintain html form objects list * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *, import java util.*, public class _o fl db extends Object { pubhc Vector formObjects; pπvate ez_html ez_HTML; public o fm db getForm(ιnt formNumber) { if (0 < formNumber && formNumber <= formObjects sιze()) remm (_o_fm_db)formObjects.elementAt(formNumber-l), else return null; } public void newForm(_o_fm_db newForm) { formObjects.addElement(newForm); } pubhc _o_fl_db(ez_html ez_HTML) { formObjects = new Vector(lO); thιs.ez_HTML = ez_HTML; } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * a frame for displaying an image, with static methods for handlmg images * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *; importjava.io *; importjava.net *, public class _f_ιm_db extends Frame { Image itslmage = null; private ez html ez HTML = null, pubhc final static Strmg Dl = "Release to display image.. "; public final static String DM = "Drag to move image..."; mt xlmg = 0, xDown = 0, xWide = 0; mt ylmg = 0, yDown = 0, yTall = 0; private static final void dbg(Stπng s) { if (debug) System.out.pπntln(s), } private static boolean debug = false, // Print debugging mfo? pubhc final boolean handleEvent(Event evt) { switch (evt.id) { case Event. WINDOW_DEICONIFY: thιs.show(); break, case Event. WINDOW CONIFY: thιs.hιde(); break; case Event WINDOW_DESTROY: itslmage flush(); thιs.dιspose(); break; } remm super.handleEvent(evt); } public final Dimension minimumSize() { Dimension ltsSize = getToolkιt().getScreenSιze(); itsSize.width = Math.mιn(ιtsSιze. width, xWide), itsSize.height = Math.mιn(ιtsSιze.heιght - 50, yTall), // hack for menus remm itsSize; } pubhc boolean mouseDown(Event evt, t x, mt y) { // dbg("_f_ιm_db.mouseDown()"); if (itslmage != null) ez_HTML.showStatus(DM); xDown = x; yDown = y; remm trae, } public boolean mouseDrag(Event evt, mt x, mt y) { if (itslmage != null) ez_HTML.showStatus(DI); xlmg = Math.mιn(0,xlmg + x - xDown); ylmg = Math.mιn(0,ylmg + y - yDown); xDown = x; yDown = y; repaιnt(), retum tme; } public boolean mouseEnter(Event evt, int x, mt y) { ez_HTML.showStatus(DM); retum trae; } public boolean mouseExιt(Event evt, mt x, mt y) { ez_HTML.showStatus(_p_rs_db.MT); remm false; } public boolean mouseMove(Event evt, int x, mt y) { ez_HTML.showStatus(DM); remm tme; } pubhc final void paιnt(Graphιcs g) { if (itslmage != null && g != null) g.drawlmage(ιtslmage, xlmg, ylmg, this); } pubhc final Dimension prefenedSrze() { return mmιmumSιze(), } public _f_im_db(Stnng itsTitle, Image itslmage, ez html ez_HTML) { this. itslmage = itslmage; this.ez HTML = ez_HTML; xWide = itslmage. getWιdth(thιs); yTall = itslmage. getHeιght(thιs), thιs.setTιtle(ιtsTιtle); thιs.pack(); thιs.show(); } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * an object to load images from files * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *; importjava.net *, import java io.*, import java.util *, public class _o ιm_db extends Object { private ezjbtml ez HTML = null, pπvate Vector imageFileNames = null, // vector of all image file names for document private Vector graphicsURLs = null, // vector of all graphic image URLs for document private Vector graphicslmages = null, // vector of all graphic images for document public static mt placelmage ( Strmg tagText , ez html ez_HTML , _p_rs_db panel , mt addlndexValue , Graphics g ) { Strmg theFileName = _o_tg_db.getTagAttnbStrmg(tagText,panel SR); int addlndex = addlndexValue; if (theFileName != null) { Image thelmage = ez HTML getlmageDBO.fetchlmage(theFileName); int theWidth = 0, if (thelmage != null) { mt theAhgnment = _o tg db getTagAhgnment(tagText, panel.BOTTOM), the Width = addlmage(thelmage, theFileName, theAhgnment, panel tagLength, ez_HTML, panel); panel.tagLength = 0; // value saved m buffer vectors } if (panel. te + the Width >= panel.xe - ρanel.ιndent(trae)) // it won't fit on this line- draw pendmg line { addlndex += panel paιntRow(g,l); // try to punch out pendmg lme elements while (panel.yb > panel ye) // start a new column 9 { if (panel lastColumn) { remm -addlndex; // no more columns left to fill } panel nextColumn(), } panel.te = panel.xb + panel.mdent(false) + the Width, } else { panel te += the Width, } if (panel te == panel.xe - panel mdent(trae)) // it fills this line draw it out { addlndex += ρanel.ρaιntRow(g,0), // try to punch out pendmg lme elements while (panel yb > panel ye) // start a new column 9 { if (panel. lastColumn) { remm - addlndex, // no more columns left to fill } panel nextColumn(), } panel te = panel.xb + panel.mdent(false), } } remm addlndex, } private static final mt addlmage ( Image thelmage , Strmg theFileName , mt theAhgnment , mt tagLength , ez html ez HTML , _p_rs_db panel ) { mt wlm = thelmage getWιdth(ez_HTML); int him = thelmage getHeιght(ez_HTML), mt wCl = panel.effectιveWιdth(), // available width of the column if (wlm = 0 || him = 0) remm 0, // nothing to draw if (wlm > wCl) // scale graphic down to column width { him = Math.round( (float)wCl * (fioat)hlm / (floaf)wIm ); wlm = wCl, } if (him > panel readerRect height) // scale graphic down to column height { wlm = Math.round( (float)panel.readerRect.heιght * (float)wlm / (float)hlm ), him = panel readerRect height, } Image anOfflmage = ez_HTML createlmage(wlm,hlm); Graphics itsGraphic = anOfflmage getGraphιcs(); // ιtsGraphιc.setColor(panel.getBackgroundO), // ιtsGraphιc.fillRect(0, 0, wlm, him); ιtsGraphιc.drawImage(theImage, 0, 0, wlm, him, panel), itsGraphic dιspose(); mt maxAscent = him; // default case (BOTTOM) if (theAhgnment = panel MIDDLE) maxAscent = him/2; else if (theAhgnment = panel TOP) maxAscent = panel textHalfSpace*3/2, // cases LEFT & RIGHT are not handled yet panel.hnelmages addElement(anOfflmage), panel dataValues.addElement ( new Rectangle ( tagLength // "x" mcrement for endlndex (character count) , maxAscent // "y" for vertical placement of image (ascent) above baseline , wlm // "width" element width on line , him - maxAscent // "height" element drop below baseline (descent) ) ); panel.wordBlocks.addElement(theFιleName), // image cross reference panel.hy erLιnks.addElement(panel.hyperHead), panel styleCodes.addElement(panel.styleCode()); // ignored m rendering images panel.wordColors.addElement(panel.textColor); panel.charsFonts.addElement(ρanel.textFont); remm wlm, // the width of this element on the lme } pubhc Image fetchImage(Stπng fileName) { if (fileName == null) { remm null, } else { Image thelmage = null, mt imageDatabaselndex = // get reference to image database file name ιmageFιleNames.mdexOf(fileName), if (imageDatabaselndex < 0) // not registered yet add it m { URL theURL = null, try // look m the documentBase { theURL = new URL(ez_HTML getDocumentBase(), fileName), InputStream is = theURL.openStream(), // test connection thelmage = ez HTML.getlmage(theURL); ez_HTML.getTracker() addlmage(thelmage,0), //jump-start image loading boolean status = ez_HTML.getTracker().checkID(0,trae); try { ez_HTML.getTracker().waitForID(0); } catch ( InterraptedException ie ) { } Image bufferedlmage = ez_HTML.createImage(l,l); if (bufferedlmage != null) { Graphics bg = bufferedlmage. getGraphics(); if (bg != null) { bg.dτawImage(theImage,0,0,this.ez_HTML); bg.dispose(); } } bufferedlmage.flush(); } catch (MalformedURLException u) { System.out.println("_o_im_db.fetchImage("+fileName+"): MalformedURLException = "+u); thelmage = null; } catch (IOException io) { System.out.println("_o_im_db.fetchImage("+fileName+"): InputStream IOException = "+io); thelmage = null; } // update image database for document imageFileNames.addElement(fileName); // the filename is the main key to image database access graρhicsURLs.addElement(theURL); // in case we need to download it again later graphicslmages. addElement(thelmage); // this may be reset to null with imageUpdate } else { thelmage = (Image)graphicsImages.elementAt(imageDatabaselndex); } remm thelmage; } } public static final void zoomlmage // new frame with full-size rendering ( String theFileName , ez_html ez_HTML ) { Image thelmage = ez_HTML.getImageDB().fetchImage(theFileName); if (thelmage != null) { f im db itsFrame = new _f_im_db(theFileName, thelmage, ez_HTML); itsFrame.setBackground(ez_HTML.getBackground()); itsFrame. setForeground(ez_HTML.getForeground()); } } public _o_im_db(ez_html ez HTML) { this.ez HTML = ez HTML; imageFileNames = new Vector(lO); // must be created before calls to fetchlmage graphicsURLs = new Vector( 10); // must be created before calls to fetchlmage graphicslmages = new Vector(lO); // must be created before calls to fetchlmage } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * a frame for displaying a table * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt.*; importjava.io.*; import java.net.*; public class _f_fb_db extends Frame { private boolean fullSize = trae; // appearance switch public final static String DT = "Drag to move table..."; public final static String RT = "Release to view table..."; public final static String WT = "Wait for new table view..."; private _p_tb_db itsTable = null; private ez_html ez_HTML = null; private int xTbl = 0, xDown = 0; private int yTbl = 0, yDown = 0; public boolean justDragging = false; private static final void dbg( String s) { if (debug) System.out.println(s); } private static boolean debug = false; // Print debugging info? public final boolean handleEvent(Event evt) { switch (evt.id) { case Event. WINDOW_DEICONIFY: this.show(); break; case Event. WINDOW CONIFY: this.hide(); break; case Event. WINDOW_DESTROY: this.dispose(); break; } return super.handleEvent(evt); } public final Dimension minimumSize() { Dimension s = getToolkit().getScreenSize(); if (debug) { s.width /= 2; s.height /= 2; } else { s.height -= 50; // hack for menus } Dimension t = itsTable.minimumSize(); s.width = Math.min(s.width, t.width ); s.height = Math.min(s. height, t.height); // dbg("_f_tb_db.minimumSize(): screen "+getToolkit0.getScreenS-ze().width+"x"+getToolkit().getScreenSize().height+", min table "+t.widt__+"x"+t.__eight+", min frame "+s.width+"x"+s.height); remm s; } public boolean mouseDown(Event evt, int x, int y) { // dbg("_f_tb_db.mouseDown("+x+","+y+")"); if (itsTable != null) ez_HTML.showStatus(DT); xTbl = itsTable.location().x; yTbl = itsTable.location().y; xDown = x; yDown = y; justDragging = false; retum trae; } public boolean mouseDrag(Event evt, int x, int y) { xTbl += x - xDown; yTbl += y - yDown; xDown = x; yDown = y; if (itsTable != null) { ez_HTML.showStatus(RT); itsTable.move(xTbl, yTbl); } justDragging = true; repaint(); remm trae; } public boolean mouseEnter(Event evt, mt x, mt y) { ez_HTML.showStatus(DT), remm trae, } public boolean mouseExιt(Event evt, mt x, int y) { ez_HTML.showStatus(_p_rs_db.MT), remm false; } public boolean mouseMove(Event evt, mt x, int y) { ez_HTML showStatus(DT), remm true, } public boolean mouseUp(Event evt, int x, mt y) { // dbg("_f_tb_db.mouseUp()"); if (justDragging) { ez_HTML.showStatus(WT), repamt(); justDragging = false; retum true; } return tme; } pubhc final Dimension prefenedSιze() { Dimension s = getToolkιt() getScreenSιze(), if (debug) { s wιdth /= 2, s height /= 2, } else { s.height -= 50, // hack for menus } Dimension t = ιtsTable.prefeπedSιze(); s.width = Math.mm(s. width, t.width * (fullSιze?5 4)/4); s.height = Math.mιn(s.heιght, t height * (fullSιze 5 4)/4), // dbg("_f_tb_db.prefenedSιze(): screen "+getToolkιtO getScreenSιze().wιdth+"x"+getToolkιt().getScreenSιze().heιght+", pref table "+t.wιdth+"x"+t.heιght+", pref frame "+s.wιdth+"x"+s.heιght); remm s, } pubhc _f_tb_db( Strmg itsTitle, _p_tb_db itsTable, _p_rs_db panel) { // dbg("new _f_tb_db("+ιtsTιtle+", "+ιtsTable.theTableNumber+")"); thιs.ez_HTML = panel.ez HTML; this. itsTable = itsTable; itsTable. setFontSizelndex(panel.readerSizelndex), thιs.setTιtle(ιtsTιtle); thιs.setBackground(panel.getBackground()); thιs.setForeground(panel.getForeground()); thιs.setLayout(new BorderLayout()); Panel p = new Panel(); // help prevent WinOS header/footer covemp thιs.add("Center", p); if (fullSize) // want overlarge tables to stretch beyond wmdow? { p.add(ιtsTable), // default flow layout } else // or overlarge tables to shrink to wmdow area { p.setLayout(new BorderLayout()); p. add(" Center", itsTable); } this pack(); thιs.show(); xTbl = ιtsTable.location().x, yTbl = ιtsTable.locatιon().y; } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * an object to load tables from specifications * this class is not downloaded unless needed * ©author Everett Stoub %I%, %G% */ import java.awt.*; unportjava.net.*; importjava.io.*; import java.util.*; public class _o_tb_db extends Object { private ez html ez_HTML = null; private Vector tableObjects = null; // vector of all table objects for document public void addTable(_p_tb_db newTable) { tableObjects. addElement(newTable); } public _p_tb_db getCopy(ιnt number, boolean readerFrame) { _p_tb_db oπg = getTable(number); if (oπg = null) { remm null, } else { __p_tb_db aCopy = oπg.copy(); aCopy .readerFrame = readerFrame; remm aCopy, } } private _p_tb_db getTable(ιnt number) { if (number < 1 || number > tableObjects. sιze()) { remm null; } else { remm (_p_tb_db)tableObjects.elementAt(number - 1); } } public mt sιze() { remm tableObjects.sιze(), } pubhc _o_tb_db(ez_html ez HTML) { thιs.ez_HTML = ez_HTML; tableObjects = new Vector(lO), } // static methods private static final void dbg(Strmg s) { if (debug) System.out.pπntln(s), } private static boolean debug = false; // Prmt debuggmg mfo? public static mt placeTable ( Strmg tagText , ez_html ez_HTML , _p_rs_db panel , mt addlndexValue , Graphics g ) { mt addlndex = addlndexValue; mt tableNumber = _0_tg_db.getTagAttπbInt(tagText, _p_rs_db.VL, 0); // dbg("_o_tb_db.placeTable("+tableNumber+"): panel("+ρanel.readerContent.substrmg(0,Math.mm(30,panel.readerContent.length()))+(panel.readerContent.len gth()<30?panel.ZZ.substrmg(panel.readerContent.length()):panel.MT)+")"), if (tableNumber > 0) { _p_tb_db theTable = ez_HTML.getTableDB().getCopy(tableNumber, panel.readerFrame), if (theTable != null) { addlndex += panel.pamtRow(g,0); // try to punch out pending lme elements theTable. setBackground(panel getBackground()); theTable. setForeground(panel. getForegroundO); panel. add( theTable); // reshapmg below panel.pageComps.addElement(theTable); // for playback theTable.setFontSιzeIndex(panel.readerSιzeIndex - 1), Dimension c = panel.columnSιze(); // as big as it can be Dimension p = theTable.prefenedSιze(); // as good as it can be Dimension m = theTable. mιnιmumSιze(); // as small as it can be Dimension t = new Dιmensιon(c), // new table dimensions: default to column // dbg("_o_tb_db.placeTable("+tableNumber+"): panel col "+c wιdth+"x"+c.heιght+", pref table "+p.wιdth+"x"+p.heιght+", mm table "+m.wιdth+"x"+m.heιght); if (p.width < c.width) // reduce width to prefened width? t. width = p.width; // prefened width OK if (p.height < c.height) // reduce height to prefened height? t.height = p.height; // prefened height OK mt clearH = panel ye - panel.yb; // headroom in column for table if (clearH < t.height) // table height too tall 9 { if // room for nice first row? ( theTable.prefRowHeιght(O) < clearH || m.height < clearH // or room for all minimum rows? || 10*clearH > c.height // or a full column won't help (much) ) { t.height = clearH; // at least one row fits into the headroom } else // this is the last column: try harder if (!panel.lastColumn) //just start a new column { panel.nextColumn(); } else // it'll have to wait for the sequel { panel.remove(theTable); // drop it panel.pageComps removeElementAt(panel.pageComps.sιze() - 1), remm -addlndex, // no more columns left to fill } } // dbg("_o_tb_db.placeTable(): reshape table to "+t.wιdth+"x"+t.heιght); theTable. reshape ( panel.xb + Math.max(0, (panel effectιveWιdth() - t.width)) / 2 , panel.yb , t.width , t.height ), theTable.show(); panel. linelmages. addElement(null), panel.data Values. addElement ( new Rectangle ( panel.tagLength // "x" mcrement for endlndex (character count) , 0 // "y" for vertical placement of image (ascent) above baseline , t.width // "width" element width on line , t height // "height" element drop below baselme (descent) ) ); panel. wordBlocks. addElement(theTable), // table reference panel.hyperLιnks.addElement(panel.hyperHead); panel.styleCodes.addElement(panel.styleCode()); panel.wordColors.addElement(panel.textColor); panel.charsFonts.addElement(panel.textFont); panel.tagLength = 0; // value saved m buffer vectors } } remm addlndex; } public static final void zoomTable // new frame with full-size rendermg ( Integer theTableNumber , _p_rs_db panel ) { // dbg("_o_tb_db.zoomTable("+theTableNumber+","+ez_HTML+")"); mt tableNumber = theTableNumber.mtValue(); if (tableNumber <= panel.ez_HTML.getTableDB().sιze()) { _p_tb_db theTable = panel.ez_HTML.getTableDB().getCopy(tableNumber, tme), Strmg itsTitle = ( theTable.theCaption = null ? "Table "+tableNumber : theTable.theCaption ); _f_tb_db itsFrame = new _f_tb_db(ιtsTιtle, theTable, panel); } } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * an object to store table row data * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *; import java.util.*; pubhc class _o_tr_db extends Object { public Color rowBg = null; public mt align = _p_rs_db.LEFT; pubhc mt vAhgn = _p_rs_db. CENTER; pubhc Vector itsCells = new Vector(); pubhc _o_tr_db ( Color rowBg , mt align , mt vAhgn ) { this.rowBg = rowBg; this.ahgn = align; this.vAhgn = vAhgn; } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved * an object to handle html tables * this class is not downloaded unless needed * HTML tag parsing honors the following commands and attributes * " <table>...</table> standard new table tag * ahgn=type left, center, right * bgcolor=color rgb or color name * border=pιxels cell embossed border size * cellpaddmg=pιxels cell mset size * cellspacιng=pιxels border embossement size * hspace=pιxels table width mset * vahgn=type top, bottom * vspace=ριxels table height mset * width=ριxels or % table rel or abs width preference * " <tr>...</tr> standard new row tag * ahgn=type left, center, right * bgcolor=color rgb or color name * vahgn=type top, bottom * " <td>...</td> standard new column data tag * " <th>...</th> standard new column header tag * ahgn=type left, center, right * bgcolor=color rgb or color name * vahgn=type top, center, bottom * " <captιon>...</captιon> standard new row tag * ahgn=type top, bottom * @author Everett Stoub %I%, %G% */ import java.awt *; import java awt.image.*, import java.util.*; public class _p_tb_db extends Panel { public final static String BC = "bgcolor"; public final static Stnng BO = "border"; pubhc final static Stnng CP = "cellpadding", public final static Stnng CS = "cellspacing"; public final static Strmg HT = "height"; public final static Strmg SH = "hspace"; public final static String SV = "vspace"; public final static Strmg TA = "table"; public final static String TC = "caption"; public final static Stnng TD = "td"; public final static Strmg TH = "th"; public final static Strmg TR = "tr"; pubhc final static Strmg VN = "vahgn"; public final static Stnng ZM = "Click to zoom table..."; public final static Strmg ZR = "Release for fullsize table view...", public final static Strmg ZW = "Wait for fullsize table view..."; pubhc ez html ez_HTML = null; public Integer theTableNumber = new Integer(O); public mt fontSizelndex = 2; public boolean readerFrame = false; public boolean tableSpecParsed = false; pubhc boolean layoutComplete = false; pπvate String tableSpec = null; // table parameters private mt align = _p_rs_db.LEFT; // cunent setting private mt vAhgn = _p_rs_db.CENTER; private mt hSpace = 0; // cunent settmg private int vSpace = 0, // cunent settmg private mt border = 0, // cunent setting private mt cellPaddmg = 0; // cunent setting private mt ce-lSpacing = 0, // cunent setting private mt mm Width = 0; // cunent guideline for whole table private int minHeight = 0, // cunent guideline for whole table private Insets msets = new lnsets(0,0,0,0); private Vector tableRows = new Vector(); // each entry is a row object private _p_tc_db tableCells[][]; // anay of _p_tc_db cell objects private Dimension tableSize = new Dιmensιon(); private mt nRows = l; private int nCols = l; private mt its Width = 0; private int itsHeight = 0; pubhc Strmg theCaption = null; private int capAhgn = _p_rs_db.TOP; // cunent settmg pubhc Strmg addCaptιon(boolean upperCaption) { if ( ( theCaption = null) || ( upperCaption && capAhgn l= _p_rs_db.TOP) || (! upperCaption && capAhgn = _p_rs_db TOP) ) remm _p_rs_db.MT; StrmgBuffer itsContent = new StπngBuffer(); itsContent // new break, with center formattmg .append(_p_rs_db.PF) .append(_p_rs_db.BR).append(_p_rs_db.BL) .append(_p_rs_db.AL).append(_p_rs_db.EQ) .append(_p_rs_db.CJ) .append(_p_rs_db.SF); itsContentappend(theCaption); itsContent // end paragraph .append(_p_rs_db.PF) .append(_p_rs_db.SL) .aρpend(_p_rs_db.PA) .apρend(_p_rs_db.SF); // dbg("_p_tb_db("+theTableNumber+").addCaptιon("+upperCaptιon+"): "+ιtsContent.toStrmg()); retum itsContent.toStrmgO; } private void addContent(Stπng content) { // dbg(" _p_tb_db("+theTableNumber+").addContent("+content+")"); if (theCaption = _p_rs_db.MT) // load content as the caption { if (content == _p_rs_db.MT) // preclude regression { theCaption = null; // complete the load } else { // dbg("... theCaption = "+content); theCaption = content; // capmre the load } } else if (tableRows. sιze() > 0) // content could be extraneous { _o_tr_db thisRow = (_o_tr_db)tableRows.lastElement(); if (thιsRow.ιtsCells.sιze() > 0) { _p_tc_db thisCell = (_p_tc_db)thιsRow.ιtsCells.lastElement(); // dbg("... the cell(R"+tableRows.sιze()+"C"+thisRow _tsCells.sιze()+") = "+content); thisCell.content += content, // capture the load } } } private void addElement(Stπng itsText) { // dbg("_p_tb_db("+theTableNumber+").addElement("+ιtsText+")"), String tagText = itsText. toLowerCase(); if (tagText.startsWιth(TA)) // an html new table tag w/ attributes { setBackground ( _o_tg_db.parseColorValue ( _o_tg_db.getTagAttribString(tagText, BC) , getBackground().getRGB() ) ); align = _o_tg_db.getTagAlignment(tagText, align); vAlign = _o_tg_db.getTagAlignment(tagText, VN, vAlign); hSpace = _0_tg_db.getTagAttribInt(tagText,SH,hSpace); vSpace = _0_tg_db.getTagAttribInt(tagText,SV,vSpace); min Width = _o_tg_db.getTagPerCentWidth(tagText); // coded negative for per cent value, positive for pixel value minHeight = _o_tg_db.getTagAttribInt(tagText,HT,minHeight); if (tagText.indexOf(BO) > -1) border = _o_tg_db.getTagAttribInt(tagText,BO, 1); cellPadding = _0_tg_db.getTagAttribInt(tagText,CP,cellPadding); cellspacing = _o_tg_db.getTagAttribInt(tagText,CS,cellSpacing); } else if (tagText. starts With(TR)) // an html new row tag w/ attributes { // dbg("... new table row: tagText = "÷tagText); _o_tr_db thisRow = new _o_tr_db ( _o_tg_db.parseColorValue ( _o_tg_db.getTagAttribString(tagText, BC) , getBackground().getRGB() ) , _o_tg_db.getTagAlignment(tagText, align) , _o_tg_db.getTagAlignment(tagText, VN, vAlign) ); tableRows. addElement(thisRow); // align, bgcolor, valign, cells vector nRows = tableRows.size(); } else if (tagText. starts With(TH) // an html column header tag w/ attributes for cunent row || tagText. starts With(TD)) // an htinl column data tag w/ attributes for cunent row { _o_tr_db thisRow = (_o_tr_db)tableRows.lastElement(); _p_tc_db thisCell = new _p_tc_db // background color ( _o_tg_db.parseColorValue ( _o_tg_db.getTagAttribString ( tagText, BC) , thisRow.rowBg.getRGBO ) , getForegroundO > _o_tg_db.getTagAlignment(tagText, thisRow. align) // horizontal alignment , _o_tg_db.getTagAlignment( tagText, VN,thisRow.vAlign) // vertical alignment , _0_tg_db.getTagPerCentWidth(tagText) // minimum cell width , _o_tg_db.getTagAttribInt(tagText,"colspan",l) // column group value , _o_tg_db.getTagAttribInt(tagText,"rowspan",l) // row group value , _0_tg_db.getTagAttribInt(tagText,HT,23) // minimum cell height , border , cellPadding , cellspacing , tagText.startsWith(TD) // boolean isData ); thisRow.itsCells.addElement(thisCell); int rowCells = 0; for (int i = 0; i < thisRow.itsCells.size(); i++) rowCells += ((_p_tc_db)thisRow.itsCells.elementAt(i)).colSpan; nCols = Math.max(nCols, rowCells); } else if (tagText.startsWith(_p_rs_db.TB)) // a private table in a cell tag { // dbg("... finding row "+tableRows.size()+" object"); _o_tr_db thisRow = (_o_tr_db)tableRows.lastElement(); // dbg("... finding cell "+thisRow.itsCells.size()+" object"); _p_tc_db thisCell = (_p_tc_db)thisRow.itsCells.lastElement(); thisCell.content += "<"+tagText+">"; // capmre the load } else if (tagText. starts With(TC)) // an html caption tag w/ attributes { theCaption = _p_rs_db.MT; // code: next content value is caption capAlign = _o_tg_db.getTagAlignment(tagText, capAlign); } else if ( tagText.startsWith(_p_rs_db.SL+TA) // an html end new table tag w/ attributes || tagText. starts With(_p_rs_db.SL+TR) // an html end new row tag w/ attributes || tagText.startsWith(_p_rs_db.SL+TH) // an html end column header tag w/ attributes for cunent row || tagText.startsWith(_p_rs_db.SL+TD) // an html end column data tag w/ attributes for cunent row || tagText.startsWith(__p_rs_db.SL+_p_rs_db.TB) // a private end table in a cell tag || tagText.startsWith(_p_rs_db.SL+TC) // an html end caption tag w/ attributes ) { //just ignore these } else { // dbg("... unhandled tagText = <"+tagText+">"); _o_tr_db thisRow = (_o_tr_db)tableRows.lastElement(); _p_tc_db thisCell = (_p_tc_db)thisRow.itsCells.lastElement(); thisCell.content += "<"+tagText+">"; // capture the load } } public _p_fb_db copy() { // dbg("_p_tb_db("+theTableNumber+").copy()"); _p_tb_db aCopy = new _p_tb_db ( this.tableSpec , this.theTableNumber , this.ez_HTML ); return aCopy; } private final void dbg(Strmg s) { if (debug) System out pπntln(s), } private boolean debug = false; // Print debugging info 9 public synchronized void doLayout() { // dbg("_pχb_db("+theTableNumber+") doLayout() "+nRows+"x"+nCols+" table"), if (itableSpecParsed) parseTableSpec(); boolean zoomableCells = false; // true if top level is _f_tb_db Component ancestor = getParent(), while (ancestor != null) { if (ancestor instanceof f fb db) zoomableCells = true, ancestor = ancestor getParent(); } tableCells = new _p_tc_db [nRows] [nCols]; for (mtj = 0; j < nRows; j++) // assign row & column #'s to each cell { _o_tr_db thisRow = (χχtr db)tableRows.elementAt(j); int nCells = thιsRow.ιtsCells.sιze(); for (mt 1 = 0; K nCells, ι++) // locate all cells in this row { _p_tc_db thisCell = (_p_tc_db)thιsRow.ιtsCells.elementAt(ι); StringBuffer itsContent = new StπngBufferO, if (thιsCell.content.length() > 0) { ιtsContent.apρend o_rs_db.PF).append _p_rs_db.PA); if (IthisCell.isData // center formattmg || thisCell.align = _p_rs_db.CENTER) ιtsContent.append(_p_rs_db.BL).append(_p rs_db.AL).append(_p_rs_db.EQ).append(_p_rs_db.CJ); ιtsContent.apρend(_p_rs_db.SF), if (IthisCell.isData) // bold formattmg itsContent. append(_p rs_db.PF).append(_p_rs_db.BD).apρend(j_rs_db SF).append(thιsCell.content) append( _P_rs_db PF).apρend(_p_rs_db SL) append(_p_rs_db.BD).append(_p_rs_db.SF); else // normal formattmg ιtsContent.append( thisCell content), ιtsContent.append(_p_rs_db.PF).append(_ρ_rs_db.SL).append(_p_rs_db PA).append(_p_rs_db.SF); } _p_rs_db aPane = new jp_rs_db // a panel component ( itsContent toStπng() // specified html content , ez_HTML // the applet , null // no frame , false // NOT the reader screen , 1 // maxColumns , false // no paging indicator marks , false // no page position footer , thisCell.cellBg , thisCell.cellFg , (ιtsContent.length() > 0 ? border. 0) , cellPadding , cellspacing , zoomableCells // zoomabihty ); aPane.setFontSizelndex(this.fontSizelndex); mt c = 1, r = j; while (tableCells [r][c] != null)// find first empty table cell (r,c) if (++c = nCols) // start a new row! { c = 0; // start new row with 1st column if (++r = nRows) // no more rows: attempt recovery { c = ι; r = j; break; // could replace prior cell } } if (tableCells[r][c] = null) // prevent cell replacement { thisCell.colNum = c; thisCell.rowNum = r; for (int f = 0; f < thisCell.rowSpan && r + f < nRows; f++) for (mt g = 0, g < thisCell.colSpan && c + g < nCols; g++) tableCells[r + f][c + g] = thisCell; // fill the element's footprint } thιs.add(thιsCell); // add the cell to this table panel (reshape later) thisCell.add("Center", aPane), // add the reader panel to the cell thιsCell.show(); } } layoutComplete = true; thιs.reshapeAll(); thιs.mvahdate(); thιs.vahdate(); } pubhc Insets msets() { remm msets; } pnvate mt mιnColLoc(ιnt c) { mt x = msets.left, for (mt l = 0; I < c; ι++) x += mmColWιdth(ι); return x, } private mt minColLoc(_p_tc_db c) { remm mmColLoc(c.colNum); } private int mιnColWιdth(ιnt c) { int mmColWidth = 0, for (mt r = 0, r < nRows; r++) if (tableCells [r][c] != null) nunColWidth = Math.max ( mmColWidth , tableCells[r][c].mιnιmumS_ze().w_dth / tableCells[r][c].colSρan ), remm mmColWidth; } private mt mmColWιdth(_p_tc_db c) { remm mιnColWιdth(c.colNum), } public Dimension mmιmumSιze() { if (! layoutComplete) doLayout(); // dbg("_p_tb_db("+theTableNumber+") mmimumS-ze("+mmTableSize0.width+","+minTableSize().height+")"), remm mmTableSιze(), } public int mιnRowHeιght(mt r) { int minRowHeight = 0; for (mt c = 0; c < nCols, C++) if (tableCells [r][c] != null) minRowHeight = Math.max ( minRowHeight , tableCells [r][c].mmιmumSιze(). height / tableCells [r][c].rowSpan ); remm minRowHeight; } private int mmRowHeιght(_p_tc_db c) { retam mmRowHeιght(c rowNum), } pπvate int mιnRowLoc(ιnt r) { ιnt y = insets top, for (int j = 0, j < r, j++) y += mmRowHeιght(j), return y, } private int mιnRowLoc(_p_tc_db c) { remm mmRowLoc(c rowNum), } public Dimension mιnTableSιze() { Dimension d = new Dιmensιon(), for (mt c = 0, c < nCols, C++) d width += mιnColWιdth(c), for (mt r = 0, r < nRows, r++) d height += mιnRowHeιght(r), d width += insets left + insets right, d height += msets top + insets bottom, remm d, } public boolean mouseDown(Event evt, int x, int y) { // dbg("_p_tb_db mouseDown("+x+","+y+")"), if (getParen-0 '= null) { if (getParent() instanceof _ rs_db) { ez_HTML showStatus(ZR), remm trae, } remm false, } remm trae, } public boolean mouseEnter(Event evt, int x, int y) { if (getParent() instanceof _j-_rs_db) ez_HTML showStatus(ZM), remm trae, } pubhc boolean mouseMove(Event evt, int x, mt y) { if (getParent() instanceof _p_rs_db) ez_HTML showStatus(ZM), remm trae, } pubhc boolean mouseExιt(Event evt, mt x, mt y) { ez HTML showStatus(_p_rs_db MT), return tme, } public boolean mouseUp(Event evt, mt x, mt y) { // dbg("_p_tb_db mouseUpO"), if (getParent() '= null) { if (getParent() instanceof _p rs_db) { // dbg("_p_tb_db mouseUp() zooming table "+thιs theTableNumber), ez_HTML showStatus(ZW), _o_tb_db zoomTable ( this theTableNumber , (_p_rs_db)getParent() ), remm trae, } else { remm false, } } remm super mouseUρ(evt, x, y), } public synchronized void paιnt(Graphιcs g) { // dbg("_p tb_db("+theTableNumber+", "+countComponents()+" components "+sιze() wιdth+" x "+sιze() heιght+") pamt(g) lsEnabled = "+ιsEnabled()+", isShowmg = "+ιsShowmg()+", is Valid = "+ιsVahd()+", lsVisible = "+ιsVιsιble()+", layoutComplete = "+layoutComplete), if ('layoutComplete) doLayout(), Rectangle r = bounds(), if (g '= null) { g setColor(getBackground()), g fillRect(0, 0, r width, r height), for (mt I = 0, K border, ι++) g draw3DRect ( I + hSpace + cellSpacmg/2 , l + vSpace + cellSpacιng/2 , r width - 1 - 2*hSρace - cellSpacmg - 2*ι , r height - 1 - 2*vSpace - cellSpacmg - 2*ι , true ), g setColor(getForeground()), } } private void parseTableSρec() { StπngTokemzer tagBlocks = new StπngTokemzer // break up the text mto normal tagBlocks (tableSpec,_p_rs_db PF,tme), // final true returns token on next call while (tagBlocks hasMoreTokens()) // tag block to follow { Strmg tagBlock = tagBlocks nextToken(_p_rs_db PF), // [<tag text>content],[<tag text>content], ,[<tag text>] // handle all html table instructions if (tagBlock equals(_p_rs_db PF)) // an html "<" (PF) tag prefix 9 { Strmg tagText = tagBlocks nextToken(_p_rs_db SF), // should be tag text if (tagBlocks hasMoreTokens()) tagBlock = tagBlocks nextToken(), // should be ">" (SF) tag suffix else tagBlock = J_rs_db MT, // syntax enor if (tagBlock equals(_p_rs_db SF)) // the normal case { addElement( tagText), tagBlock = _p_rs_db MT, // tagText handled, transfer text capmre } else // recover from syntax enor { tagBlock = jp_rs_db PF + tagText + tagBlock,// restore tagBlock to body text } } // handle all html text content if ('tagBlock equals(_p_rs_db PF) && 'tagBlock equals(_p_rs_db MT)) // not an html tag 9 must be content { addContent(tagBlock), } } tableSpecParsed = tme, } private mt prefColLoc(ιnt c) { mt x = msets left, for (int l = 0, l < c, ι++) x += prefColWιdth(ι), remm x, } private mt prefColLoc(_p_tc_db c) { retum prefColLoc(c colNum), } pπvate mt prefColWιdth(mt c) { int prefColWidth = 0, for (int r = 0, r < nRows, r++) ιf (tableCells[r][c] '= null) prefColWidth = Math max ( prefColWidth , tableCells[r][c] prefenedSιze() width / tableCells [r][c] colSpan ), remm prefColWidth, } private mt prefColWιdth(_p_tc_db c) { retum prefColWιdth(c colNum), } public Dimension prefenedSιze() { if ('layoutComplete) doLayout(), // dbg("_p_tb_db("+theTableNumber+") prefenedSιze("+prefTableSιze() wιdth+","+prefTableSιze() heιght+")"), remm prefTableSιze(), } public int prefRowHeιght(ιnt r) { mt prefRowHeight = 0, for (mt c = 0, c < nCols, C++) if (tableCells [r][c] '= null) prefRowHeight = Math max ( prefRowHeight , tableCells [r] [c] ρrefenedSιze() height / tableCells[r][c] rowSpan ), remm prefRowHeight, } pπvate mt prefRowHeιght(_p_tc_db c) { remm prefRowHeιght(c rowNum), } private int prefRowLoc(ιnt r) { mt y = msets top, for (int j = 0, j < r, j++) y += prefRowHeιght(j), return y, } private mt prefRowLoc(j._tc_db c) { remm prefRowLoc(c rowNum), } pubhc Dimension prefTableSιze() { Dimension d = new Dιmensιon(), for (int c = 0, c < nCols, C++) d width += prefColWιdth(c), for (mt r = 0, r < nRows, r++) d height += prefRowHeιght(r), d width += insets left + insets right, d height += insets top + insets bottom, remm d, } public synchronized void reshape(ιnt x, int y, mt width, mt height) { // dbg("_p_tb_db("+theTableNumber+") reshape("+x+", "+y+", "+wιdth+", "+heιght+")"), super reshape(x, y, width, height), if ('layoutComplete) doLayout(), mt lW = insets left + insets right, int IH = msets top + insets bottom, if (width > IW && height > iH && (width '= tableSize width || height '= tableSize height)) this reshapeAll(wιdth, height), repaιnt(), } public final void reshapeAll() { // dbg("_p_tb_db("+theTableNumber+") reshapeAll()"), _p_tc_db firstCell = null, for (mt j = 0, j < nRows- 1 && firstCell == null, j++) for (mt l = 0, K nCols && firstCell == null, ι++) firstCell = tableCells[j][ι], _p_rs_db firstPanel = null, if (firstCell '= null && firstCell countComponents() > 0) if (firstCell getComponent(O) mstanceof _p_rs_db) firstPanel = (_p_rs_db)firstCell getComponent(O), int sW = this sιze() width == 0 Math min ( getToolkιt() getScreenSιze() width , ( firstPanel '= null 9 firstPanel standardLmeWιdth() 180 ) * nCols ) this srze() width , mt sH = this sιze() height = 0 9 getToolkιt() getScreenSιze() height this sιze() height , reshapeAll(sW, sH), } public final void reshape AU(ιnt sW, mt sH) { // dbg("_p_tb_db("+theTableNumber+") reshapeAll("+sW+", "+sH+")"), mt[] x = new mt[nCols], x[0] = msets left, ιnt[] y = new ιnt[nRows], y[0] = msets top, ιnt[] w = new ιnt[nCols], mt[] h = new ιnt[nRows], boolean zoomableCells = tme, // optimistic, to be sure Dimension p = prefTableSιze(), Dimension m = mιnTableSιze(), if (sW < m width) // at least 1 col set below mm width { zoomableCells = false, // set false to zoom table instead for (mt l = 0, l < nCols-1 , ι++) { x[ι+l] = Math min ( sW - msets right // just truncate final column(s) , x[ι] + mmColWιdth(ι) ), w[ι] = x[ι+l] - x[ι], // result is always non-negative } w[nCols-l] = Math max // the last column ( 0 , Math mm ( mιnColWιdth(nCols-l) , sW - insets right - x[nCols-l] ) ), } else if (sW < p width) // at least 1 col set below pref width { zoomableCells = false, // set false to zoom table mstead ιnt[] z = new ιnt[nCols], int nW = sW - msets left - insets right, for (mt l = 0, l < nCols, ι++) { z[ι] = mιnColWιdth(ι), w[ι] = prefColWιdth(ι), nW -= w[ι], } while (nW < 0) // decrement last column with most slack { mt xs = 0, xi = 0, for (mt I = 0, I < nCols, ι++) if (xs < w[ι] - z[ι]) // column slack = excess over minimum width xs = w[ι] - z[xl = l], // get the column number w[xl]— , // nanow the target column nW++, // overshoot value mcrements closer to zero } for (mt ι = 0, l < nCols-l, ι++) x[ι+l] = x[ι] + w[ι], } else // pref width is nanower than spec'd width { for (mt l = 0, l < nCols- 1 , ι++) x[ι+l ] = x[ι] + (w[ι] = prefColWιdth(ι)), w[nCols-l] = prefColWιdfh(nCols-l), } if (sH < m height) // at least 1 row set below mm height { zoomableCells = false, // set false to zoom table mstead for (int = 0, j < nRows- l, j++) { y[)+l] = Math mm ( sH - msets bottom // just truncate final row(s) , y|j] + mιnRowHeιght(j) ), h[j] = y[]+l] - y|j], // result is always non-negative } h[nRows-l] = Math max // the last row ( 0 , Math mm ( mmRowHe-ght(nRows-l) , sH - insets.bottom - y [nRows- 1] ) ), } else if (sH < p height) // at least 1 row set below pref height { zoomableCells = false, // set false to zoom table mstead mt[] z = new mt[nRows]; int nH = sH - insets.top - msets bottom, for (int j = 0; j < nRows; j++) { zjj] = mιnRowHeιght(j), h[j] = prefRowHeιght(j); nH -= h[j], } while (nH < 0) // decrement last row with most slack { int xs = 0, xJ = 0, for (mt j = 0, j < nRows; j++) if (xs < h|j] - z|j]) // row slack = excess over minimum height xs = h[j] - z[xJ = j]; // get the row number h[χj]— , // nanow the target row nH++, // overshoot value increments closer to zero } for (mtj = 0, j < nRows- l, j++) y[)+l] = y_] + h[j], } else // pref height is shorter than spec'd height { for (mt j = 0, j < nRows-1; j++) y[]+l] = y_] + ( _] = prefRowHeight )), h[nRows-l] = prefRowHeιght(nRows-l), } thιs.setZoomable(zoomableCells); for (int j = 0; j < nRows; j++) { for (int ι = 0; K nCols; ι++) if (tableCells[]][ι] '= null) { _p_tc_db c = tableCells[)][ι]; int cWide = 0, cN = c.colNum; for (mt n = 0; n < c.colSpan && n < nCols - cN; n++) cWide += w[cN + n]; mt cHigh = 0, rN = c.rowNum; for (mt n = 0; n < c rowSpan && n < nRows - rN; n++) cHigh += h[rN + n]; // dbg("_p_tb_db("+theTableNumber+").reshape cell["+j+"]["+ι+"]: ("+x[cN]+", "+y[rN]+", "+cWιde+", "+cHιgh+")"), c.reshape ( x[cN] , y[rN] , cWide , cHigh ); } } tableSize = new Dιmensιon(sW, sH), // dbg("_p_tb_db("+theTableNumber+").reshapeAll("+sW+", "+sH+") complete- table prefSize = "+p wιdth+"x"+p.heιght+", mimSize = "+m.wιdth+"x"+m.heιght), } public fmal void setFontSιzeIndex(ιnt newSizelndex) { // dbg("_p_tb_db("+theTableNumber+") setFontSιzeIndex("+newSιzeIndex+"): # comps = "+countComponents()), this.fontSizelndex = newSizelndex; for (mt l = 0; K thιs.countComponents(); ι++) { if (thιs.getComponent(ι) instanceof _p_tc_db) { ((_p_tc_db)thιs.getComponent(ι)). setFontSizelndex(fontSizelndex); } } } public void setZoomable(boolean zoomableCells) { // dbg("_p_tb_db("+theTableNumber+") setZoomable("+zoomableCells+"): # comps = "+countComponents()); for (mt l = 0, l < this. countComponents(); ι++) { if (thιs.getComponent(ι) instanceof _p_tcχlb) { ((_p_tc_db)thιs getComponent(ι)). setZoomable(zoomableCells); } } } pubhc synchronized void update(Graphιcs g) { // fillRect is NOT performed here to eliminate blank screen boredom during offscreen drawing // g.setColor(getBackground()); // g.fillRect(0, 0, width, height); // g.setColor(getForeground()); pamt(g); } public void vahdate() { // dbg("_pJb_db("+theTableNumber+").valιdate()"); if (!thιs.ιsVahd() && ! layoutComplete) doLayout(), super. vahdate(); } pubhc _p_tb_db(Stπng tableSpec, Integer theTableNumber, ez itml ez_HTML) { // dbg("new _p_tb_db("+tableSpec+", "+theTableNumber+")"); thιs.ez_HTML = ez_HTML; this.tableSpec = tableSpec; this. theTableNumber = theTableNumber; thιs.setLayout(null); msets.top = vSpace + 1 + border + cellSpacιng/2; msets.left = hSpace + 1 + border + cellSpacιng/2; msets.bottom = vSpace + 1 + border + cellSpacmg - cellSpacιng/2; insets.right = hSpace + 1 + border + cellSpacmg - cellSpacιng/2; } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved * an object to store table cell data * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt.*; import java.util.*; pubhc class _p_tc_db extends Panel { pubhc Color cellBg = null, public Color cellFg = null, public int align = _p_rs_db.LEFT; public mt vAhgn = _p_rs_db. CENTER; public int min Width = 0, pubhc mt minHeight = 0; public mt colSpan = 1 ; pubhc int rowSpan = 1 ; public mt colNum = 1 ; pubhc int rowNum = 1 ; public mt border = 0; public mt cellPadding = 0, public mt cellSpacmg = 0, pubhc boolean lsData = trae; public Strmg content = _p_rs_db.MT; private final void dbg(Stπng s) { if (debug) System out prmtln(s), } private boolean debug = false; // Prmt debugging mfo? public boolean mouseDown(Event evt, mt x, mt y) { // dbg("_p_tc_db.mouseDown("+x+","+y+")"); remm false; } public final void setFontSιzeIndex(mt newSizelndex) { // dbg("_p_tc_db().setFontS_zeIndex("+newSιzeIndex+") # comps = "+countComponents()); for (int 1 = 0; 1 < thιs.countComponents(); ι++) { if (thιs.getComponent(ι) instanceof _P_ rs _db) ((_p_rs_db)thιs.getComponent(ι)). setFontSizelndex(newSizelndex); else if (thιs.getComponent(ι) instanceof _p_tb_db) ((_p_tb_db)thιs.getComponent(ι)). setFontSizelndex(newSizelndex); } } public void setZoomable(boolean zoomable) { // dbg("_p_tc_db().setZoomable("+zoomable+"): # comps = "+countComponents()); for (int l = 0; l < this countComponents(); ι++) { if (this. getComponent(ι) instanceof _p_rs_db) { ((_p_rs_db)thιs.getComρonent(ι)) setZoomable(zoomable), } else if (this. getComponent(ι) instanceof _p_tb_db) { ((_p_tb_db)thιs.getComponent(ι)). setZoomable(zoomable), } } } public synchronized void update(Graphιcs g) { // fillRect is NOT performed here to eliminate blank screen boredom during offscreen drawing // g.setColor(getBackground()), // g fillRect(0, 0, width, height), // g.setColor(getForeground()), pamt(g); } public _p_tc_db ( Color cellBg , Color cellFg , int align , int v Align , mt mmWidth , mt colSpan , mt rowSpan , mt mmHeight , int border , mt cellPadding , int cellSpacmg , boolean lsData // false if header, trae if data ) { this.cellBg = cellBg; this.cellFg = cellFg; this.ahgn = align; this vAhgn = vAhgn; this.minWidth = min Width; this.colSpan = colSpan; this.rowSpan = rowSpan; this.minHeight = mmHeight; this.border = border; this.cellPaddmg = cellPadding; this.cellSpacing = cellSpacmg; this.isData = lsData; thιs.setLayout(new BorderLayout()); } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * an object to handle html horizontal rules * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *; importjava.io.*; import java.net.*; public class _o_hr_db extends Object { pubhc static int placeRule ( String tagText , _p_rs_db panel , mt addlndexValue , Graphics g ) { mt addlndex = addlndexValue; mt itsSize = _o_tg_db.getTagAttπbInt(tagText, panel.SZ, 3); mt itsWidth = _o_tg_db.getTagWιdth(tagText,panel.effectιveWιdth()), addlndex += panel.paintRow(g,0); // try to punch out pending line elements if (! panel startNewParagraph(l)) { remm -addlndex; // no more room on the page } while (panel.yb + itsSize > panel ye) { if (panel lastColumn) { remm -addlndex, // no more columns left to fill } panel.nextColumnO; } if (itsSize > 0 && its Width > 0) { ιnt ιtsAhgn = _o_tg_db.getTagAhgnment(tagText, panel CENTER); int itsStart = panel.xb + panel.mdent(false) + ιtsAhgn*(panel.effectιveWιdth() - ιtsWιdth)/2; float[] hsbvals = new float[3], hsbvals = Color.RGBtoHSB(panel.getBackground().getRed(), panel.getBackground().getGreen(), panel.getBackground().getBlue(), hsbvals); ιf(g != null) { if (hsbvals[2] > 0.5f) { g.setColor(panel.getBackground().darker().darker()), } else { g.setColor(panel.getBackground().brιghter().brιghter()), } if (tagText.mdexOf("noshade") > -l) { g.fillRoundRect(ιtsStart,panel.yb,ιtsWιdth,ιtsSιze,ιtsSιze,ιtsSιze); } else { g.draw3DRect(_tsStart,panel.yb,ιtsWιdth,ιtsSιze,false); } } panel yb += itsSize; if (!panel.startNewParagraph(l)) { remm -addlndex; } } // textAlign = LEFT; // it's supposed to be reset this way, but PageMill does not! remm addlndex; } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved * an object to handle html lists * this class is not downloaded unless needed * @author Everett Stoub %I%, %G% */ import java.awt *; importjava.io *; importjava.net *, public class _o_lι_db extends Object { public final static String ST = "start", // unordered list bullet types public final static int DISC = 1, public final static mt CIRCLE = 2, public fmal static int BLOCK = 3, pubhc final static int SQUARE = 4, // ordered list numbering types public final static int UCROMAN = 1 ; // list type "I" public final static mt UCLETTER = 2; // list type "A" public final static int ARABIC = 3, // list type "1" public final static mt LCROMAN = 4; // list type "l" pubhc final static mt LCLETTER = 5; // list type "a" public static int addltem ( Strmg tagText , String itsText , jp_rs_db panel , mt addlndexValue , Graphics g ) { // dbg("_o_h_db.addItem(["+ιtsText+"],panel,"+addIndexValue+",g)"); int addlndex = addlndexValue; if (panel. lιstAccount.sιze() > 0) { addlndex += panel.pamtRow(g,0); // try to punch out pendmg lme elements if ('panel.startNewParagraph(O)) { remm -addlndex, } if (tagText startsWιth(panel.LI)) { Point itsltem = (Poιnt)panel.hstAccount firstElement(); itsltem x = _o_tg_db.getTagAttnbInt ( tagText // optional start value , ST , itsltem.x // increment its counter in panel.pamtRow ); itsltem.y = o li db.getTagAttribTypelnt ( itsText // as asserted by user , itsltem y // inherited list element type ); } else // a definition list element? { panel. termDefimtion = tagText equals(panel.DD), // if true: added mdentation } panel.newListltem = trae, } remm addlndex, } pubhc static int addList ( String tagText , Strmg itsText , _p_rs_db panel , int addlndexValue , Graphics g ) { mt addlndex = addlndexValue, addlndex += panel.paintRow(g,0), // try to punch out pending line elements if ('panel.startNewParagraph( (panel hstAccount sιze() > 0)?0:1)) { remm - addlndex; } if (tagText starts Wιth(panel.OL)) { panel.orderedList = trae; } else { panel.unorderList = trae, } if (tagText.equals(panel.DL)) { panel listAccount.insertElementAt(new Point(l,0),0), } else { mt htlndex = _0_tg_db.getTagAttπbInt(tagText, ST, 1 ) - 1 , int hstType = _o_lι_db.getT agAttπbTypelnt ( itsText , panel.lιstAccount.sιze() % (panel.unorderLιst?4:5) + 1 ); Point listElement = new Point ( htlndex // start value , hstType // element type ); panel. hstAccount.insertElementAt(listElement,0); } retum addlndex; } pubhc static mt endList ( Strmg tagText , Strmg itsText , _p_rs_db panel , mt addlndexValue , Graphics g ) { mt addlndex = addlndexValue, addlndex += panel.ρaιntRow(g,0); // try to punch out pendmg lme elements if (!panel.startNewParagraph((panel.hstAccount.sιze() > 0)?0: 1)) { return -addlndex; } mt itsSize = panel.hstAccount.sizeO, if (itsSize == 1) { if (tagText.equals(panel.SL+panel.OL)) { panel.orderedList = false, } else { panel.unorderList = false; } } if (itsSize > 0) { panel.hstAccount.removeElementAt(O), // LIFO list } retum addlndex, } pnvate static final void dbg(Stπng s) { if (debug) System.out.pπntln(s), } private static boolean debug = false, // Print debugging mfo? public static void drawBullet ( _p_rs_db panel , mt x , ιnt y , Graphics g ) { if (panel hstAccount.sιze() == 0 || !(panel.lιstAccount.firstElement() instanceof Point)) remm, Point itsltem = (Pomt)panel.hstAccount.firstElement(); mt D = (panel.textHeιght+3)/4; if (g '= null && itsltem.x > 0) switch (itsltem.y) { case DISC. g.fillOval(x - 2*D - 3, y - D - 2, D + 1, D + 1), case CIRCLE: g.drawOval(x - 2*D - 3, y - D - 2, D + 1, D + 1); break; case BLOCK g.fillRect(x - 2*D - 1, y - D - 2, D, D), case SQUARE: , g.drawRect(x - 2*D - 1, y - D - 2, D, D), break, } panel.newListltem = false, } public static void drawLabel ( _p_rs_db panel , mt x , mt y , Graphics g ) { if (panel. hstAccount. sιze() == 0 || !(panel.lιstAccount.firstElement() instanceof Point)) remm; Point itsltem = (Poιnt)panel.hstAccount.firstElementO; Stnng itsLabel = ". "; if (itsltem.x > 0) switch (itsltem.y) { case UCROMAN: // up to 100 entries before starting over case LCROMAN: { Stnng lab = panel.MT; switch ((itsltem.x - 1) % 10 + 1) { case 1: lab = "I"; break; case 2- lab = "u"; break, case 3: lab = "in"; break, case 4: lab = "ιv"; break, case 5: lab = "v"; break, case 6: lab = "vi", break, case 7: lab = "vn"; break; case 8: lab = "vin"; break; case 9: lab = "IX"; break; } switch ((ιtsltem.x/10 - 1) % 10 + 1) { case 1. lab = "x" + lab; break; case 2: lab = "xx" + lab; break; case 3: lab = "xxx" + lab, break, case 4: lab = "xl" + lab; break; case 5 lab = "1" + lab; break, case 6. lab = "lx" + lab, break; case 7- lab = "lxx" + lab; break, case 8: lab = "lxxx" + lab; break, case 9. lab = "xc" + lab; break, } if (itsltem y == UCROMAN) lab = lab toUpperCase(); itsLabel = lab + itsLabel, } break, case UCLETTER- // up to 26**2 entries before starting over case LCLETTER { char[] lab = {(char)(97 + (itsltem.x - 1) % 26)}; itsLabel = (new Stπng(lab)) + itsLabel, } if (itsltem x > 26) { char[] lab = {(char)(97 + (ιtsItem.x/26 - 1) % 26)} ; itsLabel = (new Stπng(lab)) + itsLabel; } if (itsltem y == UCLETTER) itsLabel = ιtsLabel.toUpperCase(); break, case ARABIC: itsLabel = itsltem x + itsLabel, break; } if (g '= null) g.drawStrmg(ιtsLabel, x - panel textMetncs.stπngWιdth(ιtsLabel), y); panel.newListltem = false, } pubhc static final mt getTagAttnbTypelnt ( Strmg itsText , mt itsDefault ) { Strmg itsLabel = _o_tg_db.getTagAttπbStrmg(ιtsText, _p_rs_db.TP); if (itsLabel == null) { remm itsDefault; } Strmg lowLabel = ιtsLabel.toLowerCase(), if (lowLabel.equals("cιrcle")) remm CIRCLE; else if (lowLabel.equals("square")) remm SQUARE; else if (lowLabel.equals("dιsc")) remm DISC; else if (ιtsLabel.equals('T')) remm ARABIC; else if (itsLabel equals("A")) remm UCLETTER; else if (ιtsLabel.equals("a")) remm LCLETTER; else if (ιtsLabel.equals('T')) remm UCROMAN; else if (ιtsLabel.equals("ι")) retum LCROMAN, else re m itsDefault; } } /** * %W% %E% Everett Stoub * Copyright (c) '96-'97 ION Web Products, Inc. All Rights Reserved. * platform-specific html character entity converter * Character Entity parsing honors the following characters * NOTE: each JVM will yield some variations due to internal font implementations * CHARACTER REMAPPING * NAMED NUMERIC DESCRIPTION ALL MAC ALT * ===== ===== =- == _____= =____. =__= * &quot; &# 034; double quotation mark * &amp, &# 038; ampersand * &lt; &# 060; less than sign * &gt, &#062; greater than sign * &# 130, comma 44 * &# 131; florin 159 102 * &# 132; right double quote 155 34 * &# 133; ellipsis 138 ".. " * &# 134, dagger 221 n/a * &# 135; double dagger 253 n/a * &#136; circumflex 150 n/a * &#137; permιl 148 "0/00" * &# 138, underscore 95 * &#139, less than sign 60 * &# 140; capital OE ligature 145 "OE" * &# 145; left single quote 140 39 * &# 146; right smgle quote 140 39 * &# 147; left double quote 155 34 * &# 148; right double quote 155 34 * &# 149; bullet 128 183 * &#150; em dash 173 45 * &#151; en dash 139 45 * &#152; tilde 126 * &#153; trademark 129 "(TM)" * &#154; underscore 95 * &#155; greater than sign 62 * &#156; small OE ligature "oe" * &#159; capital Y umlaut 141 n/a * &nbsp; &# 160; nonbreaking space * &ιexcl, &# 161; inverted exclamation point * &cent; &# 162; cents sign * &pound; &# 163; pound sign * &cunen, &# 164, general cunency sign * &yen; &# 165, Yen sign * &brvbar; &# 166; broken vertical bar "|" * &sect, &# 167; section mark * &uml, &# 168, umlaut * &copy, &#169; copyright mark * &ordf; &# 170; femmine ordinal * &laguo; &# 171, left angle quote * &not, &# 172, not sign * &shy; &# 173; soft hyphen * &reg, &#174, registered trade mark * &macr, &#175; macron accent * &deg; &#176; degree sign * &plusmn; &# 177; plus or minus * &sup2, &# 178; superscript 2 "2" * &sup3, &# 179; superscript 3 "3" * &acute; &# 180; acute accent * &mιcro, &# 181; micro sign (Greek mu) * &para; &#182; paragraph sign * &mιddot, &# 183, middle dot mark * &cedιl, &#184; cedilla * &supl; &#185, superscript 1 "1" * &ordm, &# 186, masculine ordinal * &raquo, &# 187, right angle quote * &fracl4, &# 188, fraction one-fourth "1/4" * &fracl2, &# 189, fraction one-half "1/2" * &frac34, &# 190, fraction three-fourths "3/4" * &ιquest, &# 191, inverted question mark * &Agrave, &# 192, cap A with grave accent * &Aacute, &# 193, cap A with acute accent * &Acιrc, &# 194, cap A with circumflex accent * &Atιlde, &# 195, cap A with tilde accent * &Auml, &#196, cap A with unlaut accent * &Armg, &# 197, cap A with ring accent * &AElιg, &# 198, cap AE ligature * &Ccedιl, &# 199, cap cedilla * &Egrave, &#200, cap E with grave accent * &Eacute, &#201, cap E with acute accent * &Ecιrc, &#202, cap E with circumflex accent * &Euml, &#203, cap E with unlaut accent * &Igrave, &#204, cap I with grave accent * &Iacute, &#205, cap I with acute accent * &Icιrc, &#206, cap I with circumflex accent * &Iuml, &#207, cap I with unlaut accent * &ETH, &#208, cap eth, Icelandic 127 * &Ntιlde, &#209, cap N with tilde accent * &Ograve, &#210, cap O with grave accent * &Oacute, &#211, cap O with acute accent * &Ocιrc, &#212, cap O with circumflex accent * &Otιlde, &#213, cap O with tilde accent * &Ouml, &#214, cap O with unlaut accent * &tιmes, &#215, multiply sign 183 * &Oslash, &#216, cap O with slash * &Ugrave, &#217, cap U with grave accent * &Uacute, &#218, cap U with acute accent * &Ucιrc, &#219, cap U with circumflex accent * &Uuml, &#220, cap U with unlaut accent * &Yacute, &#221, cap U with acute accent 89 * &THORN, &#222, cap THORN, Icelandic 127 * &szlιg, &#223, small sz ligature, German * &agrave, &#224, small A with grave accent * &aacute, &#225, small A with acute accent * &acιrc, &#226, small A with circumflex accent * &atιlde, &#227, small A with tilde accent * &auml, &#228, small A with unlaut accent * &aπng, &#229, small A with nng accent * &aehg, &#230, small AE ligature * &ccedιl, &#231, small cedilla * &egrave, &#232, small E with grave accent * &eacute, &#233, small E with acute accent * &ecιrc, &#234, small E with circumflex accent * &euml, &#235, small E with unlaut accent * &ιgrave, &#236, small I with grave accent * &ιacute, &#237, small I with acute accent * &acιrc, &#238, small I with circumflex accent * &ιuml, &#239, small I with unlaut accent * &eth, &#240, small eth, Icelandic 143 * &ntιlde, &#241 , small N with tilde accent * &ograve, &#242, small O with grave accent * &oacute, &#243, small O with acute accent * &ocuc, &#244, small O with circumflex accent * &otιlde, &#245, small O with tilde accent * &ouml, &#246, small O with unlaut accent * &dιvιde, &#247, divide sign * &oslash, &#248, small O with slash * &ugrave, &#249, small U with grave accent * &uacute, &#250, small U with acute accent * &ucιrc, &#251, small U with circumflex accent * &uuml, &#252, small U with unlaut accent * &yacute, &#253, small Y with acute accent 121 * &thorn, &#254, small THORN, Icelandic 127 * &yuml, &#255, small Y with unlaut accent * * @author Everett Stoub %I%, %G% */ import java awt *, import java util *, public class _o_nt_db extends Object { public Strmg convertCharacterEntιtιes(Stπng itsText) { // dbg("_o_nt_db convertCharacterEntιtιes(["+ιtsText+"])"), if (itsText == null) remm itsText, boolean mac = System getProperty("os name") equals("macos"), StrmgTokenizer entities = new StπngTokemzer(ιtsText,"&",tme), StrmgBuffer newText = new StπngBuffer(70), while (entities hasMoreTokens()) { Strmg entity = // [body text], [&][#nnn,body text], ,[&][#nnn,body text] entities nextToken("&"), if (entity equals("&") && entities hasMoreTokens()) { String eText = // should be character entity text #nnn or name entities nextToken(","), if (entities hasMoreTokens()) entity = entities nextToken(), // should be "," if eText is valid character entity value else entity = _p_rs_db MT, // avoid making thmgs up if (entity equals(",")) // replace character entity with local character (set) { mt e = 0, if (!eText.startsWith("# ")) // named entity: assign numeric entity value { if (eText.equals("quot")) e = 34; else if (eText.equals("amp")) e = 38; else if (eText.equals("lt")) e = 60; else if (eText.equals("gt")) e = 62; else if (eText.equals("nbsp")) e = 160; else if (eText.equals("iexcl")) e = 161 ; else if (eText.equals("cent")) e = 162; else if (eText.equals("pound")) e = 163; else if (eText.equals("cunen")) e = 164; else if (eText. equals( "yen")) e = 165; else if (eText.equals("brvbar")) e = 166; else if (eText.equals("sect")) e = 167; else if (eText.equals("uml")) e = 168; else if (eText.equals("copy")) e = 169; else if (eText.equals("ord )) e = 170; else if (eText.equals("laguo")) e = 171; else if (eText.equals("not")) e = 172; else if (eText.equals("shy")) e = 173; else if (eText.equals("reg")) e = 174; else if (eText.equals("macr")) e = 175; else if (eText.equals("deg")) e = 176; else if (eText.equals("plusmn")) e = 177; else if (eText.equals("sup2")) e = 178; else if (eText.equals("sup3")) e = 179; else if (eText.equals("acute")) e = 180; else if (eText.equals("micro")) e = 181; else if (eText.equals("para")) e = 182; else if (eText.equals("middot")) e = 183; else if (eText.equals("cedil")) e = 184; else if (eText.equals("supl")) e = 185; else if (eText.equals("ordm")) e = 186; else if (eText.equals("raquo")) e = 187; else if (eText.equals("fracl4")) e = 188; else if (eText.equals("fracl2")) e = 189; else if (eText.equals("frac34")) e = 190; else if (eText.equals("iquest")) e = 191; else if (eText. equals("Agrave")) e = 192; else if (eText.equals("Aacute")) e = 193; else if (eText.equals("Acirc")) e = 194; else if (eText.equals("Atilde")) e = 195; else if (eText.equals("Auml")) e = 196; else if (eText.equals("Aring")) e = 197; else if (eText.equals("AElig")) e = 198; else if (eText.equals("Ccedil")) e = 199; else if (eText.equals("Egrave")) e = 200; else if (eText.equals("Eacute")) e = 201; else if (eText.equals("Ecirc")) e = 202; else if (eText.equals("Euml")) e = 203; else if (eText.equals("Igrave")) e = 204; else if (eText.equals("Iacute")) e = 205; else if (eText.equals("Icirc")) e = 206; else if (eText.equals("Iuml")) e = 207; else if (eText.equals("ETH")) e = 208; else if (eText.equals("Ntilde")) e = 209; else if (eText.equals("Ograve")) e = 210; else if (eText.equals("Oacute")) e = 211; else if (eText.equals("Ocirc")) e = 212; else if (eText.equals("Otilde")) e = 213; else if (eText.equals("Ouml")) e = 214; else if (eText.equals("times")) e = 215; else if (eText.equals("Oslash")) e = 216; else if (eText.equals("Ugrave")) e = 217; else if (eText.equals("Uacute")) e = 218; else if (eText.equals("Ucirc")) e = 219; else if (eText.equals("Uuml")) e = 220; else if (eText.equals("Yacute")) e = 221; else if (eText.equals("THORN")) e = 222; else if (eText.equals("szlig")) e = 223; else if (eText.equals("agrave")) e = 224; else if (eText.equals("aacute")) e = 225; else if (eText.equals("acirc")) e = 226; else if (eText.equals("atilde")) e = 227; else if (eText.equals("auml")) e = 228; else if (eText.equals("aring")) e = 229; else if (eText.equals("aelig")) e = 230; else if (eText.equals("ccedil")) e = 231; else if (eText.equals("egrave")) e = 232; else if (eText.equals("eacute")) e = 233; else if (eText.equals("ecirc")) e = 234; else if (eText.equals("euml")) e = 235; else if (eText.equals("igrave")) e = 236; else if (eText.equals("iacute")) e = 237; else if (eText.equals("acirc")) e = 238; else if (eText.equals("iuml")) e = 239; else if (eText.equals("eth")) e = 240; else if (eText.equals("ntilde")) e = 241; else if (eText.equals("ograve")) e = 242; else if (eText.equals("oacute")) e = 243; else if (eText.equals("ocirc")) e = 244; else if (eText.equals("otilde")) e = 245; else if (eText.equals("ouml")) e = 246; else if (eText.equals("divide")) e = 247; else if (eText.equals("oslash")) e = 248; else if (eText.equals("ugrave")) e = 249; else if (eText.equals("uacute")) e = 250; else if (eText.equals("ucirc")) e = 251; else if (eText.equals("uuml")) e = 252; else if (eText.equals("yacute")) e = 253; else if (eText.equals("yuml")) e = 255; else { e = 32; // space } // dbg("_o_nt_db convertCharacterEntιtιes() the named character entity &"+eText+", was mapped to numeric code "+e), } else // numeric entity look after the pound sign { try { e = Integer parselnt( eText substπng(l)), } catch (NumberFormatException ne) { // dbg("_o_nt_db convertCharacterEntιtιes() the numeric entity &"+eText+", was not parsed"), e = 160, // nonbreakmg space } , } // character or string remapping (internal font mapping exceptions) Strmg g = null, switch (e) { case 130 e = 44, break, case 138 case 154 e = 95, break, case 139 e = 60, break, case 152 e = 126, break, case 155 e = 62, break, case 156 g = "oe", break, } if (mac) switch (e) { case 131 e = 159, break, case 132 case 147 case 148 e = 155, break, case 133 e = 138, break, case 134 e = 221 , break, case 135 e = 253, break, case 136 e = 150, break, case 137 e = 148, break, case 140 e = 145, break, case 145 case 146 e = 140, break, case 149 e = 128, break, case 150 e = 173, break, case 151 e = 139, break, case 153 e = 129, break, case 159 e = 141 , break, case 166 g = "|", break, case 178 g = "2", break, case 179 g = "3", break, case 185 g = "l", break, case 188 g = "1/4", break, case 189 g = "1/2", break, case 190 g = "3/4", break, case 208 case 222 case 254 e = 127, break, case 215 e = 183, break, case 221 e = 89, break, case 240 e = 143, break, case 253 e = 121, break, } else switch (e) { case 131 e = 102, break, case 132 case 147 case 148 e = 34, break, case 133 g = " ", break, case 137 g = "0/00", break, case 140 g = "OE", break, case 145 case 146 e = 39, break, case 149 e = 183, break, case 150 case 151 e = 45, break, case 153 g = "(TM)", break, } char[] sub = {(char)e}, newText append((g == null 9 new Strmg(sub) g)), // dbg("_o_nt_db convertCharacterEntιtιes() the character entity &"+eText+", converted to ["+(g == null 9 new Stπng(sub) g)+"]") > } e l se // syntax enor { newText append("&") append(eText) append(entιty), } } else { newText append(entιty), // standard text } } remm newText toStπng(), } public static final void dbg(Strmg s) { if (debug) System out prmtln(s), } private static boolean debug = false, // Print debuggmg mfo 9 } /** * sam pi e we pag e with applet tag */ <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="Adobe PageMill 2 0 Mac"> <TITLE></TITLE> </HEAD> <BODY> <APPLET CODE="ez_html class" CODEBASE="ez_h_cls/" WIDTH="640" HEIGHT="480" ALIGN="BOTTOM"> <PARAM NAME="fileName" VALUE="ezsample htm"> <PARAM NAME="maxColumns" VALUE="4"> </APPLET> </BODY> </HTML> /** * ezsample htm web page for applet */ <HTML> <HEAD> <META NAME="GENERATOR" CONTENT=" Adobe PageMill 2 0 Mac"> <TITLE>EZ HTML Sample Artιcle</TITLE> </HEAD> <BODY BGCOLOR="#e8e8e8"> <P>EZ HTML is an <FONT COLOR="#00BA00">applet</FONT> for delivering substantial text and graphics content while enhancing your web page's appearance A mouse click on the applet will evoke a reader screen window, or if over a hypertext link, will open the <A HREF="ez_html html">selected page with a really long hypertext label which can show up m multiple lmes and across column and page boundaπes</A> m the browser </P> <P>NOTE this is a test document, m which samples of various html features are rendered by the EZ HTML applet for comparison with standard browser rendermg The table cells below contains very little mformation (most or all of each cell should be displayed) Any cell can be viewed m a readmg wmdow by clicking m it The status bar provides context-sensitive help text You can also click on a table or cell boundary to view the entire table m a larger wmdow EZ HTML is still in alpha - not all features have been implemented, and not all implemented features are fully debugged </P> <P><TABLE BORDER="l" CELLSPACI G="0" CELLPADDING="5"> <CAPTION ALIGN="BOTTOM">Kumquat versus a poked eye, by gender</CAPTION> <TR> <TD COLSPAN="2" ROWSPAN="2"><FONT COLOR="#0000FF">Note This table is taken from <I>HTML, The Definitive Guιde,</I> by Chuck Musciano and Bill Kennedy, an O'Reilly &amp, Associates, Inc publication The table is merely designed to illustrate multiple-row and column headers, blank areas and other special aspects to HTML table structures.</FONTX/TD> <TH COLSPAN="2"><I><FONT COLOR="#FF0000" SIZE=+2>Preference</FONT></Ix/TH></TR> <TR> <TH>Eatmg Kumquats</TH> <TH>Poke In The Eye</TH></TR> <TR ALIGN="CENTER"> <TH ROWSPAN="2">Gender</TH> <TH>Male</TH> <TD>73%</TD> <TD>27%</TD></TR> <TR ALIGN="CENTER"> <TH>Female</TH> <TD>16%</TD> <TD>84%</TDx/TR> </TABLE> </P> <P ALIGN=CENTER><FONT COLOR="#330099" SIZE=+lxHR NOSHADE>&quot;Chck on the applet&quot;<HR NOSHADE></FONT></P> <P>The reader screen presentation of content is interactive and optimized for readability. Font size can be changed by pressing up or down anow keys, or by clicking the Font+ or Font- buttons. Pages can be mmed by pressing home, left, or right keys, or by clicking the Home, Previous, or Next buttons </P> <P ALIGN=CENTER><FONT COLOR="#330099" SIZE=+l><HR NOSHADE>&quot;optιmιzed for readabιlιty&quot;<HR NOSHADE></FONTx/P> <P>One of the key advantages of this reader screen presentation is its careful avoidance of a particular form of eye-stram known as optokinetic nystagmus Nystagmus, a reflexive jump in the muscles directing the eye, is triggered by, for example, vertical scrolling of text on a computer screen </P> <P ALIGN=CENTER><IMG SRC="ez_eye gif WIDTH="74" HEIGHT="72" NATURALSIZEFLAG= "3" ALIGN="BOTTOM"x P> <P>As nystagmus stram increases, muscle jumps can become exaggerated and even enatic, finally resulting m a perception of visual weariness Nystagmus is well-known as a side-effect of excessive alcohol, a simple road-side test conducted by law officers can aid m determination of a possible DWI offense. Other possible causes of nystagmus include general physical exhaustion and illness. </P> <P> While the term &quot;nystagmus&quot; may have been unfamiliar, the condition is encountered m many circumstances, none of which is very pleasant.</P> <P ALIGN=CENTER><FONT COLOR="#330099" SIZE=+1><HR NOSHADE>&quot;optokιnetιc nystagmus&quot;<HR OSHADE></FONTx/P> <P>The mam side effect of optokmetic nystagmus mduced by scrollmg text is a tendency to prmt the document, so that it can be read later with greater comfort This interrupts delivery of content and consumes resources It is very possible that the demise of the paperless office dreams of the '80's was caused m part by nystagmus Another major cause of its demise was the difference in formattmg between standard paper, height being typically 30% greater than width, and standard computer monitors, width being typically 33% greater than height Word processors targeted paper formattmg, so that documents delivered from computer to computer were not easily adapted to screen formats This pattern also resulted m a tendency to print such documents rather than straggle to consume their contents on screen.</P> <P>EZ HTML solves these twin problems nicely First, there is no scrollmg text, resultmg m reduced eye-stram Font sizing can be adjusted by the reader for his particular situation of lighting, momtor quality and size, and his personal visual comfort Second, the content is automatically laid out m columns of text, with neither too few words m a line, about 30 characters minimum, nor too many, about 60 characters maximum. The upper limit yields a lme length which, as the human eye executes its rapid raster motion to the begmnmg of the next line, is not too long to accurately and easily find the conect next new lme. If lines are much shorter, below the minimum, lmes of text contain too little content, and the frequent raster motions can mduce eye-straιn.</P> <P ALIGN=CENTER><FONT COLOR="#330099" SIZE=+1><HR NOSHADE>&quot,Web pages become a rewarding experience with EZ&nbsp,HTML &quot,<HR NOSHADE></FONTx/P> <P>Thιs sample document contains about 3300 characters m about 640 words At normal reading speeds, it should take about 5 minutes to absorb its mam content The effort required to read this article on the screen, using EZ HTML, should be noticeably less than required by other channels For mstance, using a word processor, two approaches are common The first is to prmt it out, collect the page(s), and finally read it Altematively, one could open the document in a word processor, adjust wmdow widths and zoom factors, and finally read it, occasionally scrollmg to bring unseen parts into view With EZ HTML, just sit back, tap the up anow to adjust the font, and tap the right anow to mm the page as needed Web pages, known widely as challenging when it comes to delivering on-screen content, can become a rewarding experience with EZ HTML </P> <P><IMG SRC="ιwpmdlgo gif ' WIDTH=" 186" HEIGHT=" 181" ALIGN="BOTTOM" NATURALSIZEFLAG= "3"></P> <P ALIGN=CENTER><IMG SRC="otsdetaιls gif WIDTH="630" HEIGHT="509" NATURALSIZEFLAG= "3" ALIGN="BOTTOM"x/P> <OL> <LI>numbered list 1 level 1 item 1 <OL> <LI>numbered list 2 level 2 item 1 <LI>numbered list 2 level 2 item 2 <LI>numbered list 2 level 2 item 3 </OL> <LI>numbered list 1 level 1 item 2 <OL> <LI>numbered list 3 level 2 item 1 <LI>numbered list 3 level 2 item 2 <OL> <LI>numbered list 4 level 3 item 1 <OL> <LI>numbered list 5 level 4 item 1 <OL> <LI>numbered list 6 level 5 item 1 <LI>numbered list 6 level 5 item 2 <LI>numbered list 6 level 5 item 3 </OL> <LI>numbered list 5 level 4 item 2 <LI>numbered list 5 level 4 item 3 </OL> <LI>numbered list 4 level 3 item 2 <LI>numbered list 4 level 3 item 3 </OL> <LI>numbered list 3 level 2 item 3 <LI>numbered list 3 level 2 item 4 </OL> <LI>numbered list 1 level 1 item 3 </OL> <DL> <DT>term 1 <DD>definιtιon 1 the wordy part of the two part definition item <DT>term 2 <DD>definιtιon 2 the wordy part of the two part definition item </DL> <UL> <LI>bullet list 1 level 1 item 1 <UL> <LI>bullet list 2 level 2 item 1 <UL> <LI>bullet list 3 level 3 item 1 <UL> <LI>bullet list 4 level 4 item 1 <LI>bullet list 4 level 4 item 2 <UL> <LI>bullet list 5 level 5 item 1 <LI>bullet list 5 level 5 item 2 <LI>bullet list 5 level 5 item 3 </UL> <LI>bullet list 4 level 4 item 3 </UL> <LI>bullet list 4 level 3 item 2 <LI>bullet list 4 level 3 item 3 </UL> <LI>bullet list 2 level 2 item 2 <LI>bullet list 2 level 2 item 3 </UL> <LI>bullet list 1 level 1 item 2 <UL> <LI>bullet list 6 level 2 item 1 <LI>bullet list 6 level 2 item 2 <UL> <LI>bullet list 7 level 3 item 1 <LI>bullet list 7 level 3 item 2 <LI>bullet list 7 level 3 item 3 </UL> <LI>bullet list 6 level 2 item 3 </UL> <LI>bullet list 1 level 1 item 3 </UL> <P>Thιs is normal paragraph text <B>Thιs is bold text </B> This is normal paragraph text <FONT SIZE=+l>Thιs is big text </FONT> This is normal paragraph text <CITE>Thιs is a citation </CITE> This is normal paragraph text <CODE>Thιs is code text </CODE> This is normal paragraph text <EM>Thιs is emphasis text </EM> This is normal paragraph text </P> <BLOCKQUOTE> <P>Thιs is blockquote justified text <I>Thιs is italic text </I> This is normal paragraph text <KBD>Thιs is keyboard text </KBD> This is normal paragraph text <FONT SIZE=-l>Thιs is small text </FONT> This is normal paragraph text <stπke>Thιs is strike text </stnke> This is normal paragraph text <STRONG>Thιs is strong text </STRONG> This is normal paragraph text <sub>Thιs is subscript text </sub> This is normal paragraph text <sup>Thιs is superscript text </sup> This is normal paragraph text </P> </BLOCKQUOTE> <P>Thιs is left justified paragraph text <TT>Thιs is teletype text.</TT> This is normal paragraph text. <u>This is underline text.</u> This is normal paragraph text. <VAR>This is variable text.</VAR> This is normal paragraph text.</P> </BODY> </HTML> It is to be understood that while certain forms of the present invention have been illustrated and described herein, it is not to be limited to the specific forms or anangement of parts described and shown.

Claims: CLAIMS What is claimed and desired to be secured by Letters Patent is as follows 1 A computer system for converting a scrollable source document mto a page display document, the source document havmg information m the form of text, graphics, tables, or combinations thereof, which source document is too large to be fully displayable without scrolling on a display window of a screen associated with the system, the system comprising (a) first formattmg means for automatically formatting a screen page that is fully displayable in the display window and comprises at least one column, each havmg a column width conespondmg to a number of characters per line withm a predetermined range of characters per lme, (b) second formattmg means for automatically reformatting the source document to conform with said column width to form a display document comprising a plurality of sequential display pages; and (c) displaying means for automatically filling said at least one column of the display window with a selected one of said plurality of display pages, each said display page bemg separately and fully displayable in the display window, and (d) paging means for selectively paging, without scrolling, through said plurality of display pages. 2. The system accordmg to claim 1, wherem said first formattmg means mcludes column determmmg means for automatically determmmg the quantity of said at least one column compnsmg each said display page. 3. The system accordmg to claim 2, further compnsmg said column determining means configured to automatically determine the actual width of said at least one column 4. The system according to claim 1, wherem said second formatting means and said display means are configured to automatically utilize a user selected font for said plurality of display pages 5 The system according to claim 1 , wherein said second formattmg means and said display means are configured to automatically utilize a user selected size of font for said plurality of display pages 6. The system accordmg to claim 1 , wherem said second formattmg means is responsive to m-lme formattmg commands included in the source document The system accordmg to claim 5, mcludmg (a) font changmg means for selectively changmg the size of the font utilized for said plurality of display pages, and (b) said first formattmg means, responsive to said font changmg means, being operable to reformat said screen page such that said at least one column maintains said column width withm said predetermined range of characters per line The system according to claim 1, wherem said second formatting means further comprises resizing means for automatically resizing a graphic image or table included in the source document to fit within said at least one column The system accordmg to claim 8, wherem said resizing means mcludes icon formmg means for automatically displaying the graphic image or table as an icon m said at least one column m a respective one of said plurality of display pages The system according to claim 9, wherem said resizmg means further mcludes expandmg means for selectively displaying the graphic image or table in the size anticipated by the source document by mouse clicking respective said icon The system accordmg to claim 10, wherein said resizmg means is configured to automatically mamtam the height-to- width ratio of the graphic image or table during said resizing and expandmg A computer system for automatically converting a scrollable electronic document, mcludmg text, graphics, tables and combinations thereof, from a scrollable format to a non-scrollable format, the system compnsmg (a) a page-formmg mechamsm configured to operatively and automatically anange the scrollable electronic information document into a plurality of non-scrollable pages, each havmg at least one column wherem each said column has a width conespondmg to a number of characters per lme within a predetermined range of characters per lme, (b) a screen havmg a display wmdow configured to simultaneously display a selected one of said plurality of non-scrollable pages m its entirety, and (c) a page-turning mechamsm configured to selectively, sequentially and individually display said plurality of non-scrollable pages in said display wmdow The system accordmg to claim 12, wherein said page-forming mechanism includes a content formatter mechanism configured to be operatively responsive to formatting commands embedded m the electronic document The system according to claim 13, wherein said page-forming mechanism includes a font-sizmg mechanism configured to operatively permit a user to selectively alter the size of the characters comprising said non-scrollable pages The system accordmg to claim 12, further mcludmg an image sizing mechamsm configured to automatically alter the widths of graphic images and tables in the electronic document to conform to the width of said at least one column The system accordmg to claim 12, including an image sizmg mechanism configured to automatically and proportionately alter the widths of graphic images and tables m the electronic information document to conform to the width of said at least one column The system according to claim 15, the means for reducing the size of a graphic image or table being operable to selectively display the graphic image or table m the size originally anticipated by the electronic mformation document A method for converting a scrollable source document mto a page display document wherem the source document has mformation m the form of text, graphics, tables, or combmations thereof and wherein the source document is too large to be fully displayable without scrollmg on a display wmdow of a screen, the method compnsmg the steps of (a) automatically formatting a screen page that is fully displayable m the display wmdow wherein said screen page comprises at least one column, each having a column width conespondmg to a number of characters per line withm a predetermined range of characters per lme, (b) automatically reformatting the source document to conform with said column width to form a display document comprising a plurality of sequential display pages, and (c) automatically filling said at least one column of the display wmdow with a selected one of said plurality of display pages, each said display page being separately and fully displayable in the display window, and (d) selectively paging, without scrolling, through said plurality of display pages The method accordmg to claim 18, wherem said step of automatically formattmg a screen page mcludes the step of automatically determining the quantity of said at least one column comprising each said display page The method according to claim 19, wherein said step of automatically formattmg a screen page further includes automatically determining the actual width of each of said at least one column The method accordmg to claim 18, wherein each of said step of automatically reformatting the source document and said step of automatically filling said at least one column includes automatically utilizing a user selected font for said plurality of display pages The method according to claim 18, wherem each of said step of automatically reformatting the source document and said step of automatically filling said at least one column mcludes automatically utilizing a user selected size of font for said plurality of display pages The method accordmg to claim 18, wherem said step for automatically reformatting the source document mcludes automatically respondmg to in-line formattmg commands mcluded m the source document The method accordmg to claim 22, further mcludmg the steps of (a) selectively changmg the size of the font utilized for said plurality of display pages, and (b) automatically reformatting said screen page such that said at least one column mamtams said column width within said predetermined range of characters per line The method accordmg to claim 18, wherem said step of automatically reformatting the source document mcludes automatically resizmg a graphic image or table mcluded m the source document to fit within said at least one column The method accordmg to claim 25, wherem said step of automatically resizing a graphic image or table mcludes automatically displaying the graphic image or table as an icon m said at least one column m a respective one of said plurality of display pages The method accordmg to claim 26, wherem said step of automatically resizmg a graphic image or table further includes selectively expanding and displaying the graphic image or table m the size anticipated by the source document by mouse clicking respective said icon The method according to claim 27, wherein said step of automatically resizmg a graphic image or table includes automatically maintaining the height-to- width ratio of the graphic image or table during said resizing and expanding 29. A method for automatically converting a scrollable electronic document, including text, graphics, tables and combinations thereof, from a scrollable format to a non-scrollable format, the method comprising the steps of: (a) automatically ananging the scrollable electronic information document into a plurality of non- scrollable pages, each having at least one column wherein each said column has a width conespondmg to a number of characters per line within a predetermined range of characters per line based on a user selected font size; (b) simultaneously displaying a selected one of said plurality of non-scrollable pages in its entirety; and (c) selectively, sequentially and individually displaying said plurality of non-scrollable pages in said display window. 30. The method according to claim 29, wherein said step of automatically ananging the scrollable electronic document includes automatically responding to formattmg commands embedded in the electronic document. 31. The method according to claim 30, wherein said step of automatically ananging the scrollable electronic document includes selectively altering the size of the characters comprising said non- scrollable pages. 32. The method according to claim 29, wherein the step of automatically ananging the scrolling electronic document includes automatically altering the widths of graphic images and tables in the electronic document to conform to the width of said at least one column. 33. The method according to claim 29, wherein the steps of automatically ananging the scrolling electronic document includes automatically and proportionately altering the widths of graphic images and tables in the electronic document to conform to the width of said at least one column. 34. The method according to claim 32, wherein the step of altering the widths of graphic images and tables includes selectively displaying the graphic image or table in the size originally anticipated by the electronic document.

Inventors: STOUB EVERETT W, STOUB, EVERETT, W.
Applicants: ION SYSTEMS INC, STOUB EVERETT W, ION SYSTEMS, INC., STOUB, EVERETT, W.
Application year: 1999
Main classification: G06F17
IPC codes: G06F17