home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: article.c
- Author: Neil Cafferkey
- Copyright (C) 2000 Neil Cafferkey
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- */
-
-
- #include "viewer.h"
- #include <stdlib.h>
- #include <exec/memory.h>
- #include <intuition/screens.h>
- #include <intuition/imageclass.h>
- #include <intuition/gadgetclass.h>
-
- #include "article_protos.h"
- #include "section_protos.h"
- #include "general_protos.h"
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/exec.h>
- #include <proto/gadtools.h>
-
-
- const TEXT *sysiclass_name="sysiclass";
- const TEXT *buttongclass_name="buttongclass";
-
-
- static VOID RefreshArticle(Article article);
- static VOID DrawLines(Article article,UWORD line_count,WORD top,
- UWORD section_no,UWORD line_no);
- static BOOL RethinkArticle(Article article);
- static VOID WriteScrollBar(Article article);
- static VOID CorrectTextPosition(Article article);
- static UWORD LineNoToSectionNo(Article article,UWORD global_line_no);
-
-
-
- /* Function: CreateArticle
- * =======================
- * Creates an Article.
- */
-
- Article CreateArticle(Sequence raw_article,struct MsgPort *msg_port)
- {
- UBYTE *data=raw_article->data,*section_data;
- Article article;
- BOOL success=TRUE;
- ULONG i;
- struct Screen *screen=NULL;
- struct DrawInfo *draw_info;
-
- if((article=(Article)AllocMem(sizeof(Article_imp),MEMF_CLEAR))!=NULL)
- {
-
- article->node.ln_Type=NT_ARTICLE;
-
- article->data=raw_article;
-
- /* Skip uninteresting strings */
-
- data+=0x28;
-
- /* Extract info from article header */
-
- article->section_count=*(data++);
- article->something29_count=*(data++);
- article->reference_count=GetLittleEndianUWord(data);
- data+=2;
- article->something2c_count=GetLittleEndianUWord(data);
- data+=2;
- article->something2e_count=GetLittleEndianUWord(data);
- data+=2;
- article->string_block_length=GetLittleEndianUWord(data);
- data+=2;
- article->body_length=GetLittleEndianUWord(data);
-
- /* Skip more uninteresting strings */
-
- data+=6;
-
- /* Extract more info from article header */
-
- data+=14;
- data+=2;
-
- article->something48_count=*(data++);
-
- data+=9;
- section_data=data;
-
- /* Skip ahead to start of string block */
-
- article->title=data+article->section_count*8+
- article->something29_count*8+article->reference_count*10+
- article->something2c_count*6+
- article->something2e_count*4+
- article->something48_count*10;
-
- data=article->title+article->string_block_length+12;
-
- /* printf("title=%s\n",article->title);
- printf("title offset=0x%lx\n",article->title-raw_article->data);*/
-
- /* Create sections from raw data */
-
- if(article->sections=AllocMem(sizeof(Section)*
- article->section_count,MEMF_CLEAR))
- {
- for(i=0;(i<article->section_count)&&success;i++)
- {
- article->sections[i]=CreateSection(data+GetLittleEndianULong(
- section_data));
- if(article->sections[i]==NULL)
- success=FALSE;
- section_data+=8;
- }
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
- success=FALSE;
- }
-
- if(success)
- {
-
- /* Set default window settings */
-
- article->left=20;
- article->top=20;
- article->width=300;
- article->height=200;
-
- /* Open a window for this article */
-
- article->window=OpenWindowTags(NULL,
- WA_Left,article->left,
- WA_Top,article->top,
- WA_Width,article->width,
- WA_Height,article->height,
- WA_Flags,WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|
- WFLG_SIZEGADGET|WFLG_GIMMEZEROZERO|WFLG_ACTIVATE|
- WFLG_NEWLOOKMENUS,
- WA_Title,article->title,
- WA_MinWidth,50, /*250,*/
- WA_MinHeight,100,
- WA_MaxWidth,-1,
- WA_MaxHeight,-1,
- TAG_END);
-
-
- if(article->window)
- {
-
- /* Set up the window's message port and IDCMP flags */
-
- article->window->UserPort=msg_port;
-
- ModifyIDCMP(article->window,IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|
- IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_MOUSEBUTTONS|
- IDCMP_RAWKEY);
-
- /* Store article pointer in its window */
-
- (Article)article->window->UserData=article;
-
- /* Set drawing colours */
-
- SetAPen(article->window->RPort,1);
- SetBPen(article->window->RPort,0);
-
- /* Set the screen font as the font to be used for the article
- * text */
-
- screen=article->window->WScreen;
- article->font=OpenFont(screen->Font);
- if(article->font!=NULL)
- SetFont(article->window->RPort,article->font);
-
- /* Create a size gadget image for the sole purpose of finding
- * out how big it is */
-
- draw_info=GetScreenDrawInfo(screen);
-
- if(draw_info!=NULL)
- {
- article->button_resolution=(screen->Flags&SCREENHIRES)?
- SYSISIZE_MEDRES:SYSISIZE_LOWRES;
-
- article->size_image=NewObject(NULL,sysiclass_name,
- SYSIA_DrawInfo,draw_info,
- SYSIA_Which,SIZEIMAGE,
- SYSIA_Size,article->button_resolution,
- TAG_END);
-
- /* Create the images for the up and down buttons */
-
- article->up_image=NewObject(NULL,sysiclass_name,
- SYSIA_DrawInfo,draw_info,
- SYSIA_Which,UPIMAGE,
- SYSIA_Size,article->button_resolution,
- TAG_END);
-
- article->down_image=NewObject(NULL,sysiclass_name,
- SYSIA_DrawInfo,draw_info,
- SYSIA_Which,DOWNIMAGE,
- SYSIA_Size,article->button_resolution,
- TAG_END);
-
- FreeScreenDrawInfo(screen,draw_info);
- }
-
- /* Allocate memory for scroll bar gadget */
-
- struct Image *knob_image=AllocMem(sizeof(
- struct Image),MEMF_PUBLIC|MEMF_CLEAR);
- struct PropInfo *prop_info=AllocMem(sizeof(
- struct PropInfo),MEMF_PUBLIC|MEMF_CLEAR);
- struct Gadget *scroll_bar=AllocMem(sizeof(
- struct Gadget),MEMF_PUBLIC|MEMF_CLEAR);
-
- article->scroll_bar=scroll_bar;
- article->prop_info=prop_info;
- article->knob_image=knob_image;
-
- if((article->size_image!=NULL)&&(article->up_image!=NULL)&&
- (article->down_image!=NULL)&&
- (scroll_bar!=NULL)&&(prop_info!=NULL)&&(knob_image!=NULL))
- {
-
- /* Initialise scroll bar structures */
-
- scroll_bar->NextGadget=NULL;
- scroll_bar->LeftEdge=-(article->window->BorderRight-5);
- scroll_bar->TopEdge=article->window->BorderTop+1;
- scroll_bar->Width=article->window->BorderRight-8;
- scroll_bar->Height=-(article->window->BorderTop+
- article->size_image->Height+article->down_image->Height+
- article->up_image->Height+2);
- if(article->button_resolution==SYSISIZE_LOWRES)
- {
- scroll_bar->LeftEdge--;
- scroll_bar->Width+=2;
- }
- scroll_bar->Flags=GFLG_GADGHNONE|GFLG_RELRIGHT|GFLG_RELHEIGHT;
- scroll_bar->Activation=GACT_RIGHTBORDER|GACT_IMMEDIATE|
- GACT_RELVERIFY;
- scroll_bar->GadgetRender=knob_image;
- scroll_bar->GadgetType=GTYP_PROPGADGET|GTYP_GZZGADGET;
- scroll_bar->SpecialInfo=prop_info;
-
- prop_info->Flags=AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS;
- prop_info->VertPot=0;
- prop_info->VertBody=MAXBODY;
-
- /* Create the up and down buttons */
-
- article->up_button=NewObject(NULL,buttongclass_name,
- GA_Previous,article->scroll_bar,
- GA_Immediate,TRUE,
- GA_RelRight,-(article->window->BorderRight-1),
- GA_RelBottom,-(article->size_image->Height+
- article->down_image->Height+article->up_image->Height-1),
- GA_Height,article->up_image->Height,
- GA_RelVerify,TRUE,
- GA_GZZGadget,TRUE,
- GA_RightBorder,TRUE,
- GA_Image,article->up_image,
- GA_ID,1,
- TAG_END);
-
- article->down_button=NewObject(NULL,buttongclass_name,
- GA_Previous,article->up_button,
- GA_Immediate,TRUE,
- GA_RelRight,-(article->window->BorderRight-1),
- GA_RelBottom,-(article->size_image->Height+
- article->down_image->Height-1),
- GA_Height,article->down_image->Height,
- GA_RelVerify,TRUE,
- GA_GZZGadget,TRUE,
- GA_RightBorder,TRUE,
- GA_Image,article->down_image,
- GA_ID,2,
- TAG_END);
-
- /* Add scroll gadgets to window and make them visible */
-
- if(article->up_button&&article->down_button)
- {
- AddGList(article->window,article->scroll_bar,-1,3,NULL);
- RefreshGList(article->scroll_bar,article->window,NULL,3);
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
- success=FALSE;
- }
-
- /* Initialise article display */
-
- if(RethinkArticle(article))
- {
- RefreshArticle(article);
- WriteScrollBar(article);
- }
- else
- {
- success=FALSE;
- }
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
- success=FALSE;
- }
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_WIN,NULL,0);
- success=FALSE;
- }
- }
-
- if(!success)
- {
- KillArticle(article);
- article=NULL;
- }
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
- }
-
- return article;
- }
-
-
-
- /* Function: UpdateArticleDimensions
- * =================================
- * Adjust article's window contents to a new size.
- */
- /*
- VOID UpdateArticleDimensions(Article article)
- {
- RethinkArticle(article);
- RefreshArticle(article);
-
- return;
- }
- */
-
-
- /* Function: RethinkArticle
- * ========================
- * Adjust article's window contents to a new size.
- */
-
- static BOOL RethinkArticle(Article article)
- {
- BOOL success=TRUE;
- Paragraph paragraph;
- Section section;
- UWORD line_count,i,j,char_count,current_char,*q,char_base,
- font_height,window_height,global_line_no;
- UBYTE *p;
-
- SetWindowPointer(article->window,WA_BusyPointer,TRUE,
- WA_PointerDelay,TRUE,TAG_END);
-
- article->line_count=0;
-
- for(i=0;i<article->section_count;i++)
- {
-
- section=article->sections[i];
-
- section->start_line_no=article->line_count;
-
- /* Free old line point memory */
-
- if(section->line_count!=0)
- FreeMem(section->line_points,section->line_count*2*sizeof(UWORD));
-
-
- /* Count lines in this section */
-
- line_count=0;
-
- for(j=0;j<section->paragraph_count;j++)
- {
-
- paragraph=section->paragraphs[j];
-
- /* Count lines in this paragraph */
-
- char_count=0;
-
- for(current_char=0;(char_count=FitParagraphLine(paragraph,
- article->window,current_char))!=0;line_count++)
- {
-
- /* Move on to first word of next line */
-
- current_char+=char_count;
- for(p=paragraph->text+current_char;*(p++)==' ';current_char++);
-
- }
-
- /* Put a blank line between each paragraph */
-
- line_count++;
- }
- section->line_count=line_count;
- article->line_count+=line_count;
-
- /* Allocate new line point memory */
-
- section->line_points=AllocMem(section->line_count*2
- *sizeof(UWORD),MEMF_ANY);
-
- if(section->line_points)
- {
-
- char_base=0;
- q=section->line_points;
- for(j=0;j<section->paragraph_count;j++)
- {
-
- paragraph=section->paragraphs[j];
-
- /* Get line start points and widths */
-
- current_char=0;
-
- for(line_count=0;(char_count=FitParagraphLine(paragraph,
- article->window,current_char))!=0;line_count++)
- {
-
- *(q++)=char_base+current_char;
- *(q++)=char_count;
-
- /* Move on to first word of next line */
-
- current_char+=char_count;
- for(p=paragraph->text+current_char;*(p++)==' ';
- current_char++);
-
- }
-
- char_base+=paragraph->length;
-
- /* Set position and length of blank line between paragraphs */
-
- *(q++)=0;
- *(q++)=0;
- }
- }
- else
- {
- success=FALSE;
- }
- }
-
- if(success)
- {
-
- /* Recalculate number of complete lines that fit in window */
-
- font_height=article->window->RPort->TxHeight;
- window_height=article->window->GZZHeight;
-
- article->window_line_count=window_height/font_height;
-
- /* Calculate the latest line and pixel that should be displayed at the
- * top of the window. */
-
- if(article->line_count-1>article->window_line_count)
- {
- global_line_no=article->line_count-1-article->window_line_count;
- article->max_pixel_no=font_height-window_height%font_height;
- }
- else
- {
- global_line_no=0;
- article->max_pixel_no=0;
- }
- article->max_section_no=LineNoToSectionNo(article,global_line_no);
- article->max_line_no=global_line_no-article->sections[article->
- max_section_no]->start_line_no;
-
-
-
- article->current_line_no=0;
- article->current_pixel_no=0;
-
- CorrectTextPosition(article);
-
- article->new_size=TRUE;
-
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
- }
-
- SetWindowPointer(article->window,TAG_END);
-
- return success;
- }
-
-
-
- /* Function: RefreshArticle
- * ========================
- * Redraws an article's display.
- */
-
- static VOID RefreshArticle(Article article)
- {
- struct Window *window=article->window;
- Section section;
- UWORD window_height,font_height,window_width,draw_line_count,
- draw_line_no,draw_section_no;
- ULONG old_pixel_position,new_pixel_position;
- LONG scroll_amount;
-
- /* Calculate useful numbers */
-
- font_height=article->window->RPort->TxHeight;
- window_width=article->window->GZZWidth;
- window_height=article->window->GZZHeight;
-
- old_pixel_position=article->old_pixel_position;
-
- article->old_pixel_position=new_pixel_position=(article->sections[
- article->current_section_no]->start_line_no+
- article->current_line_no)*font_height+article->current_pixel_no;
-
- scroll_amount=(LONG)new_pixel_position-old_pixel_position;
-
- /* Check if some visible text will be kept */
-
- if(!article->new_size&&(abs(scroll_amount)<window_height))
- {
-
- /* Scroll text that should remain visible */
-
- ScrollRaster(article->window->RPort,0,scroll_amount,0,0,window_width,
- window_height);
-
- /* Draw newly visible text */
-
- if(scroll_amount>0)
- {
-
- /* Draw new lines at bottom of window */
-
- draw_line_count=(scroll_amount-(LONG)(font_height
- +article->current_pixel_no-1))/(LONG)font_height+2;
-
- draw_line_no=(new_pixel_position+window_height-scroll_amount)
- /font_height;
-
- draw_section_no=LineNoToSectionNo(article,draw_line_no);
- section=article->sections[draw_section_no];
-
- DrawLines(article,(window_height-draw_line_no*font_height
- +new_pixel_position-1)/font_height+1,draw_line_no*font_height
- -new_pixel_position,draw_section_no,
- draw_line_no-section->start_line_no);
-
- }
- else if(scroll_amount<0)
- {
-
- /* Draw new lines at top of window */
-
- draw_line_count=(-scroll_amount-(LONG)(font_height
- -article->current_pixel_no+1))/(LONG)font_height+2;
-
- /*
- printf("scroll_amount=%ld\n",scroll_amount);
- printf("draw_line_count=%u\n",draw_line_count);
- */
-
- DrawLines(article,draw_line_count,-article->current_pixel_no,
- article->current_section_no,article->current_line_no);
-
- }
- }
- else
- {
- article->new_size=FALSE;
-
- /* Clear window */
-
- SetRast(window->RPort,0);
-
- /* Fill entire window with text */
-
- DrawLines(article,(window_height-1)/font_height+1,
- -article->current_pixel_no,article->current_section_no,
- article->current_line_no);
-
- }
-
- return;
- }
-
-
-
- /* Function: DrawLines
- * ===================
- * Draw a number of article text lines.
- */
-
- static VOID DrawLines(Article article,UWORD line_count,WORD top,
- UWORD section_no,UWORD line_no)
- {
- UWORD text_left,i,j,k,*p;
- WORD baseline;
- Section section;
- struct RastPort *rast_port=article->window->RPort;
-
- /* Calculate starting point for text drawing */
-
- text_left=MARGIN_WIDTH;
- baseline=top+rast_port->TxBaseline;
-
- k=line_count;
-
- for(i=section_no;(i<article->section_count)&&(k>0);i++)
- {
-
- section=article->sections[i];
- p=section->line_points+(line_no<<1);
-
- for(j=line_no;(j<section->line_count)&&(k>0);j++,k--)
- {
-
- /* Move pen position to beginning of line */
-
- Move(rast_port,text_left,baseline);
-
- /* Draw line of text */
-
- Text(rast_port,section->text+*p,*(p+1));
- p+=2;
-
- /* Move baseline down a line */
-
- baseline+=rast_port->TxHeight;
- }
-
- /* Reset line number for next section */
-
- line_no=0;
- }
-
- return;
- }
-
-
-
- /* Function: HandleArticleInput
- * ============================
- */
-
- BOOL HandleArticleInput(Article article,struct IntuiMessage *msg)
- {
- BOOL close=FALSE;
- struct IntuiMessage *mod_msg;
-
- mod_msg=GT_FilterIMsg(msg);
- if(mod_msg!=NULL)
- {
-
- switch(msg->Class)
- {
-
- case IDCMP_NEWSIZE:
- if(RethinkArticle(article))
- {
- RefreshArticle(article);
- WriteScrollBar(article);
- break;
- }
-
- case IDCMP_CLOSEWINDOW:
- close=TRUE;
- break;
-
- case IDCMP_MOUSEBUTTONS:
- case IDCMP_GADGETUP:
- ModifyIDCMP(article->window,article->window->IDCMPFlags&
- ~IDCMP_INTUITICKS);
- break;
-
- case IDCMP_GADGETDOWN:
- ModifyIDCMP(article->window,article->window->IDCMPFlags|
- IDCMP_INTUITICKS);
- article->current_gadget=(struct Gadget *)msg->IAddress;
- article->tick_count=0;
-
- case IDCMP_INTUITICKS:
- article->tick_count++;
- if(!(article->current_gadget->Flags&GFLG_SELECTED)&&
- (article->tick_count>2)&&(article->current_gadget->GadgetID!=0))
- {
- ModifyIDCMP(article->window,article->window->IDCMPFlags&
- ~IDCMP_INTUITICKS);
- }
- else
- {
- switch(article->current_gadget->GadgetID)
- {
- case 0:
- ReadScrollBar(article);
- RefreshArticle(article);
- break;
- case 1:
- if(article->current_section_no||article->current_line_no)
- {
- if(article->current_line_no)
- article->current_line_no--;
- else
- {
- article->current_section_no--;
- article->current_line_no=article->sections[
- article->current_section_no]->line_count-1;
- }
- }
- else
- article->current_pixel_no=0;
- RefreshArticle(article);
- WriteScrollBar(article);
- break;
- case 2:
- article->current_line_no++;
- if(article->current_line_no==article->sections[article->
- current_section_no]->line_count)
- {
- article->current_section_no++;
- article->current_line_no=0;
- }
- CorrectTextPosition(article);
-
- RefreshArticle(article);
- WriteScrollBar(article);
- }
- }
- break;
-
- case IDCMP_RAWKEY:
-
- if(!(msg->Code&IECODE_UP_PREFIX))
- {
- switch(msg->Code)
- {
- case CURSORUP:
- if(article->current_section_no||article->current_line_no)
- {
- if(article->current_line_no)
- article->current_line_no--;
- else
- {
- article->current_section_no--;
- article->current_line_no=article->sections[
- article->current_section_no]->line_count-1;
- }
- }
- else
- article->current_pixel_no=0;
- RefreshArticle(article);
- WriteScrollBar(article);
- break;
-
- case CURSORDOWN:
- article->current_line_no++;
- if(article->current_line_no==article->sections[article->
- current_section_no]->line_count)
- {
- article->current_section_no++;
- article->current_line_no=0;
- }
- CorrectTextPosition(article);
-
- RefreshArticle(article);
- WriteScrollBar(article);
-
- default:
- }
- }
-
- default:
-
- }
-
- GT_PostFilterIMsg(mod_msg);
- }
-
- ReplyMsg((struct Message *)msg);
-
- if(close)
- {
- Remove(&article->node);
- KillArticle(article);
- }
-
- return;
- }
-
-
-
- /* Function: ReadScrollBar
- * =======================
- * Convert the scroll bar position into a position within the article text.
- */
-
- VOID ReadScrollBar(Article article)
- {
- UWORD global_line_no,font_height,window_height;
- ULONG pixel_no;
-
- /* Get new position in article in terms of pixels */
-
- font_height=article->window->RPort->TxHeight;
- window_height=article->window->GZZHeight;
-
- if(article->line_count*font_height>window_height)
- pixel_no=((ULONG)article->prop_info->VertPot*(article->line_count
- *font_height-window_height))/MAXPOT;
- else
- pixel_no=0;
-
- /* Calculate corresponding overall line number and pixel */
-
- article->current_pixel_no=pixel_no%font_height;
- global_line_no=pixel_no/font_height;
-
- /* Find the right section */
-
- article->current_section_no=LineNoToSectionNo(article,global_line_no);
- article->current_line_no=global_line_no-article->sections[article->
- current_section_no]->start_line_no;
-
-
- /* printf("%u\t%u\t%u\n",article->current_section_no,article->current_line_no,article->current_pixel_no);*/
-
- /* article->current_section_no=0;
- article->current_line_no=0;
- */
-
-
- return;
- }
-
-
-
- /* Function: WriteScrollBar
- * ========================
- * Update the scroll bar to reflect the current article settings.
- */
-
- static VOID WriteScrollBar(Article article)
- {
- UWORD font_height,window_height,scroll_pot,scroll_body;
-
- font_height=article->window->RPort->TxHeight;
- window_height=article->window->GZZHeight;
-
- /* Update scroll bar settings */
-
- /*printf("wsb:%u\t%u\t%u\n",article->current_section_no,article->current_line_no,article->current_pixel_no);*/
-
- if(article->line_count*font_height>window_height)
- scroll_pot=(UWORD)(((ULONG)(
- (article->sections[article->current_section_no]->start_line_no+
- article->current_line_no)*font_height+article->current_pixel_no)
- *MAXPOT)/(article->line_count*font_height-window_height));
- else
- scroll_pot=0;
-
- if(article->line_count*font_height>window_height)
- scroll_body=(UWORD)(((ULONG)window_height*MAXBODY)/
- (article->line_count*font_height));
- else
- scroll_body=MAXBODY;
-
- /* Update scroll bar to reflect new settings */
-
- NewModifyProp(article->scroll_bar,article->window,NULL,
- AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS,0,scroll_pot,0,
- scroll_body,1);
-
- /*
- printf("wsb:scroll_pot=%u\tscroll_body=%u\n",scroll_pot,scroll_body);
- printf("wsb:VertPot=%u\tVertBody=%u\n",article->prop_info->VertPot,article->prop_info->VertBody);
- */
-
- /*ReadScrollBar(article);*/
-
-
- return;
- }
-
-
-
- /* Function: CorrectTextPosition
- * =============================
- * Ensure that the current text position is valid.
- */
-
- static VOID CorrectTextPosition(Article article)
- {
-
- if((article->current_section_no>article->max_section_no)||
- (article->current_section_no==article->max_section_no)&&
- ((article->current_line_no>article->max_line_no)||
- (article->current_line_no==article->max_line_no)&&
- (article->current_pixel_no>article->max_pixel_no)))
- {
- article->current_section_no=article->max_section_no;
- article->current_line_no=article->max_line_no;
- article->current_pixel_no=article->max_pixel_no;
- }
-
- return;
- }
-
-
-
- /* Function: LineNoToSectionNo
- * ===========================
- * Locate the section containing the given global line number.
- */
-
- static UWORD LineNoToSectionNo(Article article,UWORD global_line_no)
- {
- UWORD l,m,h;
- Section *p;
-
- /* Do a binary search to find the right section */
-
- p=article->sections;
- l=0;
- h=article->section_count;
- while(h-l!=1)
- {
- m=l+(h-l)/2;
- if(global_line_no<p[m]->start_line_no)
- h=m;
- else
- l=m;
- }
-
- return l;
- }
-
-
-
- /* Function: SetArticlePosition
- * ============================
- * Sets the position of an article's window.
- */
-
- VOID SetArticlePosition(Article article,UWORD left,UWORD top)
- {
- article->left=left;
- article->top=top;
- return;
- }
-
-
-
- /* Function: SetArticleDimensions
- * ==============================
- * Sets the dimensions of an article's window.
- */
-
- VOID SetArticleDimensions(Article article,UWORD width,UWORD height)
- {
- article->width=width;
- article->height=height;
- return;
- }
-
-
- /* Function: KillArticle
- * =====================
- * Destroys an article.
- */
-
- VOID KillArticle(Article article)
- {
- UWORD i;
-
- if(article->sections!=NULL)
- {
- for(i=0;i<article->section_count;i++)
- if(article->sections[i]!=NULL)
- KillSection(article->sections[i]);
- FreeMem(article->sections,article->section_count*sizeof(Section));
- }
-
- if(article->window!=NULL)
- {
- Forbid();
- StripWindowMessages(article->window);
- article->window->UserPort=NULL;
- ModifyIDCMP(article->window,0);
- Permit();
- CloseWindow(article->window);
- }
-
- if(article->font!=NULL)
- CloseFont(article->font);
-
- /* Free images */
-
- if(article->size_image!=NULL)
- DisposeObject(article->size_image);
-
- if(article->up_image!=NULL)
- DisposeObject(article->up_image);
-
- if(article->down_image!=NULL)
- DisposeObject(article->down_image);
-
- /* Free memory for scroll bar structures */
-
- if(article->knob_image!=NULL)
- FreeMem(article->knob_image,sizeof(struct Image));
-
- if(article->prop_info!=NULL)
- FreeMem(article->prop_info,sizeof(struct PropInfo));
-
- if(article->scroll_bar!=NULL)
- FreeMem(article->scroll_bar,sizeof(struct Gadget));
-
- /* Free up and down gadgets */
-
- if(article->up_button!=NULL)
- DisposeObject(article->up_button);
-
- if(article->down_button!=NULL)
- DisposeObject(article->down_button);
-
- /* Free raw article data */
-
- FreeMem(article->data->data,article->data->length);
- KillSequence(article->data);
-
- /* Free article structure */
-
- FreeMem(article,sizeof(Article_imp));
-
- return;
- }
-
-
-