home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  27.9 KB  |  1,448 lines

  1. /*
  2. **    Scroll.c
  3. **
  4. **    Support routines for optimized screen scrolling.
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14.     /* ScrollFrameUpdate(VOID):
  15.      *
  16.      *    Optimize the area to be scrolled by moving the top and
  17.      *    bottom lines as needed.
  18.      */
  19.  
  20. STATIC VOID
  21. ScrollFrameUpdate(VOID)
  22. {
  23.     while(ScrollLineFirst < RasterHeight && !ScrollLines[ScrollLineFirst] . Width)
  24.         ScrollLineFirst++;
  25.  
  26.     while(ScrollLineLast > 0 && !ScrollLines[ScrollLineLast] . Width)
  27.         ScrollLineLast--;
  28. }
  29.  
  30.     /* ScrollLineRectFill():
  31.      *
  32.      *    Fill a rectangular portion of the window raster with the help
  33.      *    of the scrolling information.
  34.      */
  35.  
  36. VOID
  37. ScrollLineRectFill(struct RastPort *RPort,LONG MinX,LONG MinY,LONG MaxX,LONG MaxY)
  38. {
  39.     if(MinX < MaxX && MinY < MaxY)
  40.     {
  41.         LONG    Start,Stop;
  42.         LONG    BackPen;
  43.  
  44.         if(FgPen == BgPen || (Attributes & ATTR_INVERSE))
  45.             BackPen    = FgPen;
  46.         else
  47.             BackPen = BgPen;
  48.  
  49.         Start    = MinY / TextFontHeight;
  50.         Stop    = MaxY / TextFontHeight;
  51.  
  52.         if(BackPen)
  53.         {
  54.             if(UseMasking)
  55.             {
  56.                 LONG Mask = BackPen,i;
  57.  
  58.                 for(i = Start ; i <= Stop ; i++)
  59.                 {
  60.                     if(ScrollLines[i] . Width)
  61.                         Mask |= ScrollLines[i] . ColourMask;
  62.  
  63.                     ScrollLines[i] . Left        = 0;
  64.                     ScrollLines[i] . Right        = LastColumn + 1;
  65.                     ScrollLines[i] . Width        = TextFontWidth;
  66.                     ScrollLines[i] . ColourMask    = BackPen;
  67.                 }
  68.  
  69.                 SetMask(RPort,Mask);
  70.             }
  71.             else
  72.             {
  73.                 LONG i;
  74.  
  75.                 for(i = Start ; i <= Stop ; i++)
  76.                 {
  77.                     ScrollLines[i] . Left        = 0;
  78.                     ScrollLines[i] . Right        = LastColumn + 1;
  79.                     ScrollLines[i] . Width        = TextFontWidth;
  80.                     ScrollLines[i] . ColourMask    = BackPen;
  81.                 }
  82.             }
  83.  
  84.             if(Start < ScrollLineFirst)
  85.                 ScrollLineFirst = Start;
  86.  
  87.             if(Stop > ScrollLineLast)
  88.                 ScrollLineLast = Stop;
  89.  
  90.             ScrollFrameUpdate();
  91.         }
  92.         else
  93.         {
  94.             LONG    ScrollLineLeft    = 32767,
  95.                 ScrollLineRight    = 0,
  96.                 ScrollLineWidth    = 0;
  97.  
  98.             if(UseMasking)
  99.             {
  100.                 LONG Mask = 0,i;
  101.  
  102.                 for(i = Start ; i <= Stop ; i++)
  103.                 {
  104.                     if(ScrollLines[i] . Width)
  105.                     {
  106.                         if(ScrollLines[i] . Width > ScrollLineWidth)
  107.                             ScrollLineWidth = ScrollLines[i] . Width;
  108.  
  109.                         if(ScrollLines[i] . Left < ScrollLineLeft)
  110.                             ScrollLineLeft = ScrollLines[i] . Left;
  111.  
  112.                         if(ScrollLines[i] . Right > ScrollLineRight)
  113.                             ScrollLineRight = ScrollLines[i] . Right;
  114.  
  115.                         Mask |= ScrollLines[i] . ColourMask;
  116.                     }
  117.  
  118.                     ScrollLines[i] . Left        = 32767;
  119.                     ScrollLines[i] . Right        = 0;
  120.                     ScrollLines[i] . Width        = 0;
  121.                     ScrollLines[i] . ColourMask    = 0;
  122.                 }
  123.  
  124.                 if(Mask)
  125.                     SetMask(RPort,Mask);
  126.                 else
  127.                 {
  128.                     ScrollFrameUpdate();
  129.  
  130.                     return;
  131.                 }
  132.             }
  133.             else
  134.             {
  135.                 LONG i;
  136.  
  137.                 for(i = Start ; i <= Stop ; i++)
  138.                 {
  139.                     if(ScrollLines[i] . Width)
  140.                     {
  141.                         if(ScrollLines[i] . Width > ScrollLineWidth)
  142.                             ScrollLineWidth = ScrollLines[i] . Width;
  143.  
  144.                         if(ScrollLines[i] . Left < ScrollLineLeft)
  145.                             ScrollLineLeft = ScrollLines[i] . Left;
  146.  
  147.                         if(ScrollLines[i] . Right > ScrollLineRight)
  148.                             ScrollLineRight = ScrollLines[i] . Right;
  149.                     }
  150.  
  151.                     ScrollLines[i] . Left        = 32767;
  152.                     ScrollLines[i] . Right        = 0;
  153.                     ScrollLines[i] . Width        = 0;
  154.                     ScrollLines[i] . ColourMask    = 0;
  155.                 }
  156.             }
  157.  
  158.             if(ScrollLineWidth)
  159.             {
  160.                 LONG Temp;
  161.  
  162.                 if((Temp = ScrollLineLeft * ScrollLineWidth) > MinX)
  163.                     MinX = Temp;
  164.  
  165.                 if((Temp = ScrollLineRight * ScrollLineWidth) < MaxX)
  166.                     MaxX = Temp;
  167.  
  168.                 if(MaxX == ScrollLineRight)
  169.                     MaxX += FontRightExtend;    // Add margin for italics or boldface.
  170.  
  171.                 if((Temp = MUL_Y(ScrollLineFirst)) > MinY)
  172.                     MinY = Temp;
  173.  
  174.                 if((Temp = MUL_Y(ScrollLineLast + 1) - 1) < MaxY)
  175.                     MaxY = Temp;
  176.             }
  177.  
  178.             if(Start < ScrollLineFirst)
  179.                 ScrollLineFirst = Start;
  180.  
  181.             if(Stop > ScrollLineLast)
  182.                 ScrollLineLast = Stop;
  183.  
  184.             ScrollFrameUpdate();
  185.  
  186.             if(!ScrollLineWidth)
  187.                 return;
  188.         }
  189.  
  190.             /* And clear the raster. */
  191.  
  192.         if(MinX < MaxX && MinY < MaxY)
  193.         {
  194.             MinX += WindowLeft;
  195.             MinY += WindowTop;
  196.             MaxX += WindowLeft;
  197.             MaxY += WindowTop;
  198.  
  199.             if(FgPen == BgPen || (Attributes & ATTR_INVERSE))
  200.                 RectFill(RPort,MinX,MinY,MaxX,MaxY);
  201.             else
  202.             {
  203.                 SetAPen(RPort,BgPen);
  204.                 RectFill(RPort,MinX,MinY,MaxX,MaxY);
  205.                 SetAPen(RPort,FgPen);
  206.             }
  207.         }
  208.     }
  209. }
  210.  
  211. VOID
  212. ScrollLineRectFillNoTabChange(struct RastPort *RPort,LONG MinX,LONG MinY,LONG MaxX,LONG MaxY)
  213. {
  214.     if(MinX < MaxX && MinY < MaxY)
  215.     {
  216.         LONG    Start,Stop;
  217.         LONG    BackPen;
  218.  
  219.         if(FgPen == BgPen || (Attributes & ATTR_INVERSE))
  220.             BackPen    = FgPen;
  221.         else
  222.             BackPen = BgPen;
  223.  
  224.         Start    = MinY / TextFontHeight;
  225.         Stop    = MaxY / TextFontHeight;
  226.  
  227.         if(BackPen)
  228.         {
  229.             if(UseMasking)
  230.             {
  231.                 LONG Mask = BackPen,i;
  232.  
  233.                 for(i = Start ; i <= Stop ; i++)
  234.                 {
  235.                     if(ScrollLines[i] . Width)
  236.                         Mask |= ScrollLines[i] . ColourMask;
  237.                 }
  238.  
  239.                 SetMask(RPort,Mask);
  240.             }
  241.  
  242.             if(Start < ScrollLineFirst)
  243.                 ScrollLineFirst = Start;
  244.  
  245.             if(Stop > ScrollLineLast)
  246.                 ScrollLineLast = Stop;
  247.  
  248.             ScrollFrameUpdate();
  249.         }
  250.         else
  251.         {
  252.             LONG    ScrollLineLeft    = 32767,
  253.                 ScrollLineRight    = 0,
  254.                 ScrollLineWidth    = 0;
  255.  
  256.             if(UseMasking)
  257.             {
  258.                 LONG Mask = 0,i;
  259.  
  260.                 for(i = Start ; i <= Stop ; i++)
  261.                 {
  262.                     if(ScrollLines[i] . Width)
  263.                     {
  264.                         if(ScrollLines[i] . Width > ScrollLineWidth)
  265.                             ScrollLineWidth = ScrollLines[i] . Width;
  266.  
  267.                         if(ScrollLines[i] . Left < ScrollLineLeft)
  268.                             ScrollLineLeft = ScrollLines[i] . Left;
  269.  
  270.                         if(ScrollLines[i] . Right > ScrollLineRight)
  271.                             ScrollLineRight = ScrollLines[i] . Right;
  272.  
  273.                         Mask |= ScrollLines[i] . ColourMask;
  274.                     }
  275.                 }
  276.  
  277.                 if(Mask)
  278.                     SetMask(RPort,Mask);
  279.                 else
  280.                 {
  281.                     ScrollFrameUpdate();
  282.  
  283.                     return;
  284.                 }
  285.             }
  286.             else
  287.             {
  288.                 LONG i;
  289.  
  290.                 for(i = Start ; i <= Stop ; i++)
  291.                 {
  292.                     if(ScrollLines[i] . Width)
  293.                     {
  294.                         if(ScrollLines[i] . Width > ScrollLineWidth)
  295.                             ScrollLineWidth = ScrollLines[i] . Width;
  296.  
  297.                         if(ScrollLines[i] . Left < ScrollLineLeft)
  298.                             ScrollLineLeft = ScrollLines[i] . Left;
  299.  
  300.                         if(ScrollLines[i] . Right > ScrollLineRight)
  301.                             ScrollLineRight = ScrollLines[i] . Right;
  302.                     }
  303.                 }
  304.             }
  305.  
  306.             if(ScrollLineWidth)
  307.             {
  308.                 LONG Temp;
  309.  
  310.                 if((Temp = ScrollLineLeft * ScrollLineWidth) > MinX)
  311.                     MinX = Temp;
  312.  
  313.                 if((Temp = ScrollLineRight * ScrollLineWidth) < MaxX)
  314.                     MaxX = Temp;
  315.  
  316.                 if(MaxX == ScrollLineRight)
  317.                     MaxX += FontRightExtend;    // Add margin for italics or boldface.
  318.  
  319.                 if((Temp = MUL_Y(ScrollLineFirst)) > MinY)
  320.                     MinY = Temp;
  321.  
  322.                 if((Temp = MUL_Y(ScrollLineLast + 1) - 1) < MaxY)
  323.                     MaxY = Temp;
  324.             }
  325.  
  326.             if(Start < ScrollLineFirst)
  327.                 ScrollLineFirst = Start;
  328.  
  329.             if(Stop > ScrollLineLast)
  330.                 ScrollLineLast = Stop;
  331.  
  332.             ScrollFrameUpdate();
  333.  
  334.             if(!ScrollLineWidth)
  335.                 return;
  336.         }
  337.  
  338.             /* And clear the raster. */
  339.  
  340.         if(MinX < MaxX && MinY < MaxY)
  341.         {
  342.             MinX += WindowLeft;
  343.             MinY += WindowTop;
  344.             MaxX += WindowLeft;
  345.             MaxY += WindowTop;
  346.  
  347.             if(FgPen == BgPen || (Attributes & ATTR_INVERSE))
  348.                 RectFill(RPort,MinX,MinY,MaxX,MaxY);
  349.             else
  350.             {
  351.                 SetAPen(RPort,BgPen);
  352.                 RectFill(RPort,MinX,MinY,MaxX,MaxY);
  353.                 SetAPen(RPort,FgPen);
  354.             }
  355.         }
  356.     }
  357. }
  358.  
  359.     /* ScrollLineRaster():
  360.      *
  361.      *    Scroll the window raster with the help
  362.      *    of the scrolling information.
  363.      */
  364.  
  365. VOID
  366. ScrollLineRaster(struct RastPort *RPort,LONG DeltaX,LONG DeltaY,LONG MinX,LONG MinY,LONG MaxX,LONG MaxY,BOOL Smooth)
  367. {
  368.     if((DeltaX || DeltaY) && MinX < MaxX && MinY < MaxY)
  369.     {
  370.         LONG    Start,Stop;
  371.         LONG    BackPen;
  372.         BOOL    ResetPen;
  373.  
  374.         if((Attributes & ATTR_INVERSE) && (FgPen != BgPen))
  375.         {
  376.             SetBPen(RPort,FgPen);
  377.  
  378.             ResetPen    = TRUE;
  379.             BackPen        = FgPen;
  380.         }
  381.         else
  382.         {
  383.             ResetPen    = FALSE;
  384.             BackPen        = BgPen;
  385.         }
  386.  
  387.         Start    = MinY / TextFontHeight;
  388.         Stop    = MaxY / TextFontHeight;
  389.  
  390.         if(BackPen)
  391.         {
  392.             if(UseMasking)
  393.             {
  394.                 LONG i,Mask = BackPen;
  395.  
  396.                 for(i = Start ; i <= Stop ; i++)
  397.                 {
  398.                     if(ScrollLines[i] . Width)
  399.                         Mask |= ScrollLines[i] . ColourMask;
  400.                 }
  401.  
  402.                 SetMask(RPort,Mask);
  403.             }
  404.  
  405.             if(DeltaX)
  406.             {
  407.                 if(!ScrollLines[CursorY] . Width)
  408.                 {
  409.                     if(ResetPen)
  410.                         SetBPen(RPort,BgPen);
  411.  
  412.                     return;
  413.                 }
  414.                 else
  415.                 {
  416.                     ScrollLines[CursorY] . Left    = 0;
  417.                     ScrollLines[CursorY] . Right    = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  418.  
  419.                     ScrollLines[CursorY] . ColourMask |= BackPen;
  420.                 }
  421.             }
  422.             else
  423.             {
  424.                 LONG i,Lines,Size;
  425.  
  426.                 Lines    = DeltaY / TextFontHeight;
  427.                 Size    = (MaxY - MinY + 1) / TextFontHeight;
  428.  
  429.                 if(Lines < 0)
  430.                 {
  431.                     Lines = -Lines;
  432.  
  433.                     if(Size <= Lines)
  434.                     {
  435.                         for(i = 0 ; i < Size ; i++)
  436.                         {
  437.                             ScrollLines[Start + i] . Left        = 0;
  438.                             ScrollLines[Start + i] . Right        = LastColumn + 1;
  439.                             ScrollLines[Start + i] . ColourMask    = BackPen;
  440.                             ScrollLines[Start + i] . Width        = TextFontWidth;
  441.                         }
  442.                     }
  443.                     else
  444.                     {
  445.                         LONG Offset = Size - Lines;
  446.  
  447.                         for(i = 1 ; i <= Offset ; i++)
  448.                             ScrollLines[Start + Size - i] = ScrollLines[Start + Size - (i + Lines)];
  449.  
  450.                         for(i = 0 ; i < Lines ; i++)
  451.                         {
  452.                             ScrollLines[Start + i] . Left        = 0;
  453.                             ScrollLines[Start + i] . Right        = LastColumn + 1;
  454.                             ScrollLines[Start + i] . ColourMask    = BackPen;
  455.                             ScrollLines[Start + i] . Width        = TextFontWidth;
  456.                         }
  457.                     }
  458.                 }
  459.                 else
  460.                 {
  461.                     if(Size <= Lines)
  462.                     {
  463.                         for(i = 0 ; i < Size ; i++)
  464.                         {
  465.                             ScrollLines[Start + i] . Left        = 0;
  466.                             ScrollLines[Start + i] . Right        = LastColumn + 1;
  467.                             ScrollLines[Start + i] . ColourMask    = BackPen;
  468.                             ScrollLines[Start + i] . Width        = TextFontWidth;
  469.                         }
  470.                     }
  471.                     else
  472.                     {
  473.                         LONG Offset = Size - Lines;
  474.  
  475.                         for(i = 0 ; i < Offset ; i++)
  476.                             ScrollLines[Start + i] = ScrollLines[Start + Lines + i];
  477.  
  478.                         for(i = Offset ; i < Size ; i++)
  479.                         {
  480.                             ScrollLines[Start + i] . Left        = 0;
  481.                             ScrollLines[Start + i] . Right        = LastColumn + 1;
  482.                             ScrollLines[Start + i] . ColourMask    = BackPen;
  483.                             ScrollLines[Start + i] . Width        = TextFontWidth;
  484.                         }
  485.                     }
  486.                 }
  487.             }
  488.         }
  489.         else
  490.         {
  491.             LONG    ScrollLineLeft    = 32767,
  492.                 ScrollLineRight    = 0,
  493.                 ScrollLineWidth    = 0;
  494.  
  495.             if(UseMasking)
  496.             {
  497.                 LONG i,Mask = 0;
  498.  
  499.                 for(i = Start ; i <= Stop ; i++)
  500.                 {
  501.                     if(ScrollLines[i] . Width)
  502.                     {
  503.                         if(ScrollLines[i] . Left < ScrollLineLeft)
  504.                             ScrollLineLeft = ScrollLines[i] . Left;
  505.  
  506.                         if(ScrollLines[i] . Right > ScrollLineRight)
  507.                             ScrollLineRight = ScrollLines[i] . Right;
  508.  
  509.                         if(ScrollLines[i] . Width > ScrollLineWidth)
  510.                             ScrollLineWidth = ScrollLines[i] . Width;
  511.  
  512.                         Mask |= ScrollLines[i] . ColourMask;
  513.                     }
  514.                 }
  515.  
  516.                 if(Mask)
  517.                     SetMask(RPort,Mask);
  518.                 else
  519.                 {
  520.                     if(ResetPen)
  521.                         SetBPen(RPort,BgPen);
  522.  
  523.                     return;
  524.                 }
  525.             }
  526.             else
  527.             {
  528.                 if(!DeltaX)
  529.                 {
  530.                     LONG i;
  531.  
  532.                     for(i = Start ; i <= Stop ; i++)
  533.                     {
  534.                         if(ScrollLines[i] . Width)
  535.                         {
  536.                             if(ScrollLines[i] . Left < ScrollLineLeft)
  537.                                 ScrollLineLeft = ScrollLines[i] . Left;
  538.  
  539.                             if(ScrollLines[i] . Right > ScrollLineRight)
  540.                                 ScrollLineRight = ScrollLines[i] . Right;
  541.  
  542.                             if(ScrollLines[i] . Width > ScrollLineWidth)
  543.                                 ScrollLineWidth = ScrollLines[i] . Width;
  544.                         }
  545.                     }
  546.                 }
  547.             }
  548.  
  549.             if(DeltaX)
  550.             {
  551.                 if(!ScrollLines[CursorY] . Width)
  552.                 {
  553.                     if(ResetPen)
  554.                         SetBPen(RPort,BgPen);
  555.  
  556.                     return;
  557.                 }
  558.                 else
  559.                 {
  560.                     LONG Last = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  561.  
  562.                     if(DeltaX > 0)
  563.                         ScrollLines[CursorY] . Left -= DeltaX / ScrollLines[CursorY] . Width;
  564.                     else
  565.                         ScrollLines[CursorY] . Right -= DeltaX / ScrollLines[CursorY] . Width;
  566.  
  567.                     if(ScrollLines[CursorY] . Right < 0)
  568.                         ScrollLines[CursorY] . Right = 0;
  569.                     else
  570.                     {
  571.                         if(ScrollLines[CursorY] . Right > Last)
  572.                             ScrollLines[CursorY] . Right = Last;
  573.                     }
  574.  
  575.                     if(ScrollLines[CursorY] . Left < 0)
  576.                         ScrollLines[CursorY] . Left = 0;
  577.                     else
  578.                     {
  579.                         if(ScrollLines[CursorY] . Left > Last)
  580.                             ScrollLines[CursorY] . Left = Last;
  581.                     }
  582.                 }
  583.             }
  584.             else
  585.             {
  586.                 LONG    i,Lines,Size;
  587.  
  588.                 Lines    = DeltaY / TextFontHeight;
  589.                 Size    = (MaxY - MinY + 1) / TextFontHeight;
  590.  
  591.                 if(Lines < 0)
  592.                 {
  593.                     Lines = -Lines;
  594.  
  595.                     if(Size <= Lines)
  596.                     {
  597.                         for(i = 0 ; i < Size ; i++)
  598.                         {
  599.                             ScrollLines[Start + i] . Left        = 32767;
  600.                             ScrollLines[Start + i] . Right        = 0;
  601.                             ScrollLines[Start + i] . ColourMask    = 0;
  602.                             ScrollLines[Start + i] . Width        = 0;
  603.                         }
  604.                     }
  605.                     else
  606.                     {
  607.                         LONG Offset = Size - Lines;
  608.  
  609.                         for(i = 1 ; i <= Offset ; i++)
  610.                             ScrollLines[Start + Size - i] = ScrollLines[Start + Size - (i + Lines)];
  611.  
  612.                         for(i = 0 ; i < Lines ; i++)
  613.                         {
  614.                             ScrollLines[Start + i] . Left        = 32767;
  615.                             ScrollLines[Start + i] . Right        = 0;
  616.                             ScrollLines[Start + i] . ColourMask    = 0;
  617.                             ScrollLines[Start + i] . Width        = 0;
  618.                         }
  619.                     }
  620.                 }
  621.                 else
  622.                 {
  623.                     if(Size <= Lines)
  624.                     {
  625.                         for(i = 0 ; i < Size ; i++)
  626.                         {
  627.                             ScrollLines[Start + i] . Left        = 32767;
  628.                             ScrollLines[Start + i] . Right        = 0;
  629.                             ScrollLines[Start + i] . ColourMask    = 0;
  630.                             ScrollLines[Start + i] . Width        = 0;
  631.                         }
  632.                     }
  633.                     else
  634.                     {
  635.                         LONG Offset = Size - Lines;
  636.  
  637.                         for(i = 0 ; i < Offset ; i++)
  638.                             ScrollLines[Start + i] = ScrollLines[Start + Lines + i];
  639.  
  640.                         for(i = Offset ; i < Size ; i++)
  641.                         {
  642.                             ScrollLines[Start + i] . Left        = 32767;
  643.                             ScrollLines[Start + i] . Right        = 0;
  644.                             ScrollLines[Start + i] . ColourMask    = 0;
  645.                             ScrollLines[Start + i] . Width        = 0;
  646.                         }
  647.                     }
  648.                 }
  649.  
  650.                 if(ScrollLineWidth)
  651.                 {
  652.                     LONG Temp;
  653.  
  654.                     if((Temp = ScrollLineLeft * ScrollLineWidth) > MinX)
  655.                         MinX = Temp;
  656.  
  657.                     if((Temp = ScrollLineRight * ScrollLineWidth) < MaxX)
  658.                         MaxX = Temp;
  659.  
  660.                     if(MaxX == ScrollLineRight)
  661.                         MaxX += FontRightExtend;    // Add margin for italics or boldface.
  662.  
  663.                     if(DeltaY < 0)
  664.                     {
  665.                         if((Temp = MUL_Y(ScrollLineFirst)) > MinY)
  666.                             MinY = Temp;
  667.  
  668.                         if((Temp = MUL_Y(ScrollLineLast + 1) - 1 - DeltaY) < MaxY)
  669.                             MaxY = Temp;
  670.                     }
  671.                     else
  672.                     {
  673.                         if(DeltaY > 0)
  674.                         {
  675.                             if((Temp = MUL_Y(ScrollLineFirst) - DeltaY) > MinY)
  676.                                 MinY = Temp;
  677.  
  678.                             if((Temp = MUL_Y(ScrollLineLast + 1) - 1) < MaxY)
  679.                                 MaxY = Temp;
  680.                         }
  681.                     }
  682.  
  683.                     if(MinX < 0)
  684.                         MinX = 0;
  685.  
  686.                     if(MaxX < 0)
  687.                         MaxX = 0;
  688.  
  689.                     if(MinY < 0)
  690.                         MinY = 0;
  691.  
  692.                     if(MaxY < 0)
  693.                         MaxY = 0;
  694.                 }
  695.                 else
  696.                 {
  697.                     ScrollFrameUpdate();
  698.  
  699.                     if(ResetPen)
  700.                         SetBPen(RPort,BgPen);
  701.  
  702.                     return;
  703.                 }
  704.             }
  705.         }
  706.  
  707.         if(Start < ScrollLineFirst)
  708.             ScrollLineFirst = Start;
  709.  
  710.         if(Stop > ScrollLineLast)
  711.             ScrollLineLast = Stop;
  712.  
  713.         ScrollFrameUpdate();
  714.  
  715.         if(MinX < MaxX && MinY < MaxY)
  716.         {
  717.             MinX += WindowLeft;
  718.             MaxX += WindowLeft;
  719.  
  720.             MinY += WindowTop;
  721.             MaxY += WindowTop;
  722.  
  723.                 /* Smooth scrolling requested? */
  724.  
  725.             if(Smooth && DeltaY)
  726.             {
  727.                 LONG Lines,Extra,Direction;
  728.  
  729.                 Lines = ABS(DeltaY);
  730.                 Extra = Lines & 1;
  731.                 Lines = Lines / 2;
  732.  
  733.                 if(DeltaY > 0)
  734.                     Direction = 2;
  735.                 else
  736.                     Direction = -2;
  737.  
  738.                 while(Lines-- > 0)
  739.                 {
  740.                     WaitBlit();
  741.                     WaitTOF();
  742.                     ScrollRaster(RPort,0,Direction,MinX,MinY,MaxX,MaxY);
  743.                 }
  744.  
  745.                 if(Extra)
  746.                 {
  747.                     WaitBlit();
  748.                     WaitTOF();
  749.                     ScrollRaster(RPort,0,Direction / 2,MinX,MinY,MaxX,MaxY);
  750.                 }
  751.             }
  752.             else
  753.                 ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  754.         }
  755.  
  756.         if(ResetPen)
  757.             SetBPen(RPort,BgPen);
  758.     }
  759. }
  760.  
  761. VOID
  762. ScrollLineRasterNoTabChange(struct RastPort *RPort,LONG DeltaX,LONG DeltaY,LONG MinX,LONG MinY,LONG MaxX,LONG MaxY,BOOL Smooth)
  763. {
  764.     if((DeltaX || DeltaY) && MinX < MaxX && MinY < MaxY)
  765.     {
  766.         LONG    Start,Stop;
  767.         LONG    BackPen;
  768.         BOOL    ResetPen;
  769.  
  770.         if((Attributes & ATTR_INVERSE) && (FgPen != BgPen))
  771.         {
  772.             SetBPen(RPort,FgPen);
  773.  
  774.             ResetPen    = TRUE;
  775.             BackPen        = FgPen;
  776.         }
  777.         else
  778.         {
  779.             ResetPen    = FALSE;
  780.             BackPen        = BgPen;
  781.         }
  782.  
  783.         Start    = MinY / TextFontHeight;
  784.         Stop    = MaxY / TextFontHeight;
  785.  
  786.         if(BackPen)
  787.         {
  788.             if(UseMasking)
  789.             {
  790.                 LONG i,Mask = BackPen;
  791.  
  792.                 for(i = Start ; i <= Stop ; i++)
  793.                 {
  794.                     if(ScrollLines[i] . Width)
  795.                         Mask |= ScrollLines[i] . ColourMask;
  796.                 }
  797.  
  798.                 SetMask(RPort,Mask);
  799.             }
  800.  
  801.             if(DeltaX)
  802.             {
  803.                 if(!ScrollLines[CursorY] . Width)
  804.                 {
  805.                     if(ResetPen)
  806.                         SetBPen(RPort,BgPen);
  807.  
  808.                     return;
  809.                 }
  810.             }
  811.         }
  812.         else
  813.         {
  814.             LONG    ScrollLineLeft    = 32767,
  815.                 ScrollLineRight    = 0,
  816.                 ScrollLineWidth    = 0;
  817.  
  818.             if(UseMasking)
  819.             {
  820.                 LONG i,Mask = 0;
  821.  
  822.                 for(i = Start ; i <= Stop ; i++)
  823.                 {
  824.                     if(ScrollLines[i] . Width)
  825.                     {
  826.                         if(ScrollLines[i] . Left < ScrollLineLeft)
  827.                             ScrollLineLeft = ScrollLines[i] . Left;
  828.  
  829.                         if(ScrollLines[i] . Right > ScrollLineRight)
  830.                             ScrollLineRight = ScrollLines[i] . Right;
  831.  
  832.                         if(ScrollLines[i] . Width > ScrollLineWidth)
  833.                             ScrollLineWidth = ScrollLines[i] . Width;
  834.  
  835.                         Mask |= ScrollLines[i] . ColourMask;
  836.                     }
  837.                 }
  838.  
  839.                 if(Mask)
  840.                     SetMask(RPort,Mask);
  841.                 else
  842.                 {
  843.                     if(ResetPen)
  844.                         SetBPen(RPort,BgPen);
  845.  
  846.                     return;
  847.                 }
  848.             }
  849.             else
  850.             {
  851.                 if(!DeltaX)
  852.                 {
  853.                     LONG i;
  854.  
  855.                     for(i = Start ; i <= Stop ; i++)
  856.                     {
  857.                         if(ScrollLines[i] . Width)
  858.                         {
  859.                             if(ScrollLines[i] . Left < ScrollLineLeft)
  860.                                 ScrollLineLeft = ScrollLines[i] . Left;
  861.  
  862.                             if(ScrollLines[i] . Right > ScrollLineRight)
  863.                                 ScrollLineRight = ScrollLines[i] . Right;
  864.  
  865.                             if(ScrollLines[i] . Width > ScrollLineWidth)
  866.                                 ScrollLineWidth = ScrollLines[i] . Width;
  867.                         }
  868.                     }
  869.                 }
  870.             }
  871.  
  872.             if(DeltaX)
  873.             {
  874.                 if(!ScrollLines[CursorY] . Width)
  875.                 {
  876.                     if(ResetPen)
  877.                         SetBPen(RPort,BgPen);
  878.  
  879.                     return;
  880.                 }
  881.             }
  882.             else
  883.             {
  884.                 if(ScrollLineWidth)
  885.                 {
  886.                     LONG Temp;
  887.  
  888.                     if((Temp = ScrollLineLeft * ScrollLineWidth) > MinX)
  889.                         MinX = Temp;
  890.  
  891.                     if((Temp = ScrollLineRight * ScrollLineWidth) < MaxX)
  892.                         MaxX = Temp;
  893.  
  894.                     if(MaxX == ScrollLineRight)
  895.                         MaxX += FontRightExtend;    // Add margin for italics or boldface.
  896.  
  897.                     if(DeltaY < 0)
  898.                     {
  899.                         if((Temp = MUL_Y(ScrollLineFirst)) > MinY)
  900.                             MinY = Temp;
  901.  
  902.                         if((Temp = MUL_Y(ScrollLineLast + 1) - 1 - DeltaY) < MaxY)
  903.                             MaxY = Temp;
  904.                     }
  905.                     else
  906.                     {
  907.                         if(DeltaY > 0)
  908.                         {
  909.                             if((Temp = MUL_Y(ScrollLineFirst) - DeltaY) > MinY)
  910.                                 MinY = Temp;
  911.  
  912.                             if((Temp = MUL_Y(ScrollLineLast + 1) - 1) < MaxY)
  913.                                 MaxY = Temp;
  914.                         }
  915.                     }
  916.  
  917.                     if(MinX < 0)
  918.                         MinX = 0;
  919.  
  920.                     if(MaxX < 0)
  921.                         MaxX = 0;
  922.  
  923.                     if(MinY < 0)
  924.                         MinY = 0;
  925.  
  926.                     if(MaxY < 0)
  927.                         MaxY = 0;
  928.                 }
  929.                 else
  930.                 {
  931.                     ScrollFrameUpdate();
  932.  
  933.                     if(ResetPen)
  934.                         SetBPen(RPort,BgPen);
  935.  
  936.                     return;
  937.                 }
  938.             }
  939.         }
  940.  
  941.         if(Start < ScrollLineFirst)
  942.             ScrollLineFirst = Start;
  943.  
  944.         if(Stop > ScrollLineLast)
  945.             ScrollLineLast = Stop;
  946.  
  947.         ScrollFrameUpdate();
  948.  
  949.         if(MinX < MaxX && MinY < MaxY)
  950.         {
  951.             MinX += WindowLeft;
  952.             MaxX += WindowLeft;
  953.  
  954.             MinY += WindowTop;
  955.             MaxY += WindowTop;
  956.  
  957.                 /* Smooth scrolling requested? */
  958.  
  959.             if(Smooth && DeltaY)
  960.             {
  961.                 LONG Lines,Extra,Direction;
  962.  
  963.                 Lines = ABS(DeltaY);
  964.                 Extra = Lines & 1;
  965.                 Lines = Lines / 2;
  966.  
  967.                 if(DeltaY > 0)
  968.                     Direction = 2;
  969.                 else
  970.                     Direction = -2;
  971.  
  972.                 while(Lines-- > 0)
  973.                 {
  974.                     WaitBlit();
  975.                     WaitTOF();
  976.                     ScrollRaster(RPort,0,Direction,MinX,MinY,MaxX,MaxY);
  977.                 }
  978.  
  979.                 if(Extra)
  980.                 {
  981.                     WaitBlit();
  982.                     WaitTOF();
  983.                     ScrollRaster(RPort,0,Direction / 2,MinX,MinY,MaxX,MaxY);
  984.                 }
  985.             }
  986.             else
  987.                 ScrollRaster(RPort,DeltaX,DeltaY,MinX,MinY,MaxX,MaxY);
  988.         }
  989.  
  990.         if(ResetPen)
  991.             SetBPen(RPort,BgPen);
  992.     }
  993. }
  994.  
  995.     /* ScrollLineEraseScreen(BYTE Mode):
  996.      *
  997.      *    Erase a part of the screen.
  998.      */
  999.  
  1000. VOID
  1001. ScrollLineEraseScreen(LONG Mode)
  1002. {
  1003.     LONG i;
  1004.  
  1005.     if(BgPen)
  1006.     {
  1007.         switch(Mode)
  1008.         {
  1009.                 /* Erase from first line to current cursor position (inclusive). */
  1010.  
  1011.             case 1:    ScrollLineFirst = CursorY;
  1012.  
  1013.                 if(ScrollLineLast < CursorY)
  1014.                     ScrollLineLast = CursorY;
  1015.  
  1016.                     /* Reset the lines. */
  1017.  
  1018.                 for(i = 0 ; i < CursorY ; i++)
  1019.                 {
  1020.                     ScrollLines[i] . Left        = 0;
  1021.                     ScrollLines[i] . Right        = LastColumn + 1;
  1022.                     ScrollLines[i] . ColourMask    = BgPen;
  1023.                     ScrollLines[i] . Width        = TextFontWidth;
  1024.                 }
  1025.  
  1026.                 if(CursorX)
  1027.                 {
  1028.                     if(!ScrollLines[CursorY] . Width)
  1029.                         ScrollLines[CursorY] . Width = GetFontWidth();
  1030.  
  1031.                     ScrollLines[CursorY] . Left        = 0;
  1032.                     ScrollLines[CursorY] . ColourMask    |= BgPen;
  1033.                 }
  1034.  
  1035.                 break;
  1036.  
  1037.                 /* Erase entire screen. */
  1038.  
  1039.             case 2:    for(i = 0 ; i < RasterHeight ; i++)
  1040.                 {
  1041.                     ScrollLines[i] . Left        = 0;
  1042.                     ScrollLines[i] . Right        = LastColumn + 1;
  1043.                     ScrollLines[i] . ColourMask    = BgPen;
  1044.                     ScrollLines[i] . Width        = TextFontWidth;
  1045.                 }
  1046.  
  1047.                 ScrollLineFirst    = 0;
  1048.                 ScrollLineLast    = RasterHeight - 1;
  1049.  
  1050.                 break;
  1051.  
  1052.                 /* Erase from current cursor position to end of screen. */
  1053.  
  1054.             default:for(i = CursorY + 1 ; i < RasterHeight ; i++)
  1055.                 {
  1056.                     ScrollLines[i] . Left        = 0;
  1057.                     ScrollLines[i] . Right        = LastColumn + 1;
  1058.                     ScrollLines[i] . ColourMask    = BgPen;
  1059.                     ScrollLines[i] . Width        = TextFontWidth;
  1060.                 }
  1061.  
  1062.                 if(!ScrollLines[CursorY] . Width)
  1063.                     ScrollLines[CursorY] . Width = GetFontWidth();
  1064.  
  1065.                 ScrollLines[CursorY] . Right = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  1066.  
  1067.                 if(CursorX)
  1068.                     ScrollLines[CursorY] . ColourMask |= BgPen;
  1069.                 else
  1070.                     ScrollLines[CursorY] . ColourMask = BgPen;
  1071.  
  1072.                 if(ScrollLineFirst > CursorY)
  1073.                     ScrollLineFirst = CursorY;
  1074.  
  1075.                 ScrollLineLast = RasterHeight - 1;
  1076.  
  1077.                 break;
  1078.         }
  1079.     }
  1080.     else
  1081.     {
  1082.         switch(Mode)
  1083.         {
  1084.                 /* Erase from first line to current cursor line (inclusive). */
  1085.  
  1086.             case 1:        /* Reset the lines. */
  1087.  
  1088.                 for(i = 0 ; i < CursorY ; i++)
  1089.                 {
  1090.                     ScrollLines[i] . Left        = 32767;
  1091.                     ScrollLines[i] . Right        = 0;
  1092.                     ScrollLines[i] . ColourMask    = 0;
  1093.                     ScrollLines[i] . Width        = 0;
  1094.                 }
  1095.  
  1096.                 ScrollLines[CursorY] . Left = CursorX;
  1097.  
  1098.                 if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  1099.                 {
  1100.                     ScrollLines[CursorY] . Left    = 32767;
  1101.                     ScrollLines[CursorY] . Right    = 0;
  1102.                     ScrollLines[CursorY] . Width    = 0;
  1103.  
  1104.                         /* Cleared the entire screen? */
  1105.  
  1106.                     if(CursorY == RasterHeight - 1)
  1107.                     {
  1108.                         ScrollLineFirst    = 32767;
  1109.                         ScrollLineLast    = 0;
  1110.                     }
  1111.                     else
  1112.                         ScrollLineFirst = CursorY;
  1113.                 }
  1114.                 else
  1115.                     ScrollLineFirst = CursorY;
  1116.  
  1117.                 if(ScrollLineLast < CursorY)
  1118.                     ScrollLineLast = CursorY;
  1119.  
  1120.                 break;
  1121.  
  1122.                 /* Erase entire screen. */
  1123.  
  1124.             case 2:    for(i = 0 ; i < RasterHeight ; i++)
  1125.                 {
  1126.                     ScrollLines[i] . Left        = 32767;
  1127.                     ScrollLines[i] . Right        = 0;
  1128.                     ScrollLines[i] . ColourMask    = 0;
  1129.                     ScrollLines[i] . Width        = 0;
  1130.                 }
  1131.  
  1132.                 ScrollLineFirst    = 32767;
  1133.                 ScrollLineLast    = 0;
  1134.  
  1135.                 break;
  1136.  
  1137.                 /* Erase from current cursor position to end of screen. */
  1138.  
  1139.             default:for(i = CursorY + 1 ; i < RasterHeight ; i++)
  1140.                 {
  1141.                     ScrollLines[i] . Left        = 32767;
  1142.                     ScrollLines[i] . Right        = 0;
  1143.                     ScrollLines[i] . ColourMask    = 0;
  1144.                     ScrollLines[i] . Width        = 0;
  1145.                 }
  1146.  
  1147.                 if(CursorX)
  1148.                 {
  1149.                     ScrollLines[CursorY] . Right = CursorX;
  1150.  
  1151.                     if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  1152.                     {
  1153.                         ScrollLines[CursorY] . Left    = 32767;
  1154.                         ScrollLines[CursorY] . Right    = 0;
  1155.                         ScrollLines[CursorY] . Width    = 0;
  1156.                     }
  1157.                 }
  1158.                 else
  1159.                 {
  1160.                     ScrollLines[CursorY] . Left    = 32767;
  1161.                     ScrollLines[CursorY] . Right    = 0;
  1162.                     ScrollLines[CursorY] . Width    = 0;
  1163.                 }
  1164.  
  1165.                 /* Cleared the entire screen? */
  1166.  
  1167.                 if(CursorY)
  1168.                     ScrollLineLast = CursorY;
  1169.                 else
  1170.                 {
  1171.                     if(ScrollLines[CursorY] . Right < ScrollLines[CursorY] . Left)
  1172.                     {
  1173.                         ScrollLineFirst    = 32767;
  1174.                         ScrollLineLast    = 0;
  1175.                     }
  1176.                     else
  1177.                     {
  1178.                         if(ScrollLineFirst > CursorY)
  1179.                             ScrollLineFirst = CursorY;
  1180.                     }
  1181.                 }
  1182.  
  1183.                 break;
  1184.         }
  1185.     }
  1186.  
  1187.     ScrollFrameUpdate();
  1188. }
  1189.  
  1190.     /* ScrollLineEraseLine(BYTE Mode):
  1191.      *
  1192.      *    Erase parts of the current cursor line.
  1193.      */
  1194.  
  1195. VOID
  1196. ScrollLineEraseLine(LONG Mode)
  1197. {
  1198.     if(BgPen)
  1199.     {
  1200.         switch(Mode)
  1201.         {
  1202.                 /* Erase from left margin to current cursor position (inclusive). */
  1203.  
  1204.             case 1:    ScrollLines[CursorY] . Left = 0;
  1205.  
  1206.                 ScrollLines[CursorY] . ColourMask |= BgPen;
  1207.  
  1208.                 if(!ScrollLines[CursorY] . Width)
  1209.                     ScrollLines[CursorY] . Width = GetFontWidth();
  1210.  
  1211.                 break;
  1212.  
  1213.                 /* Erase entire line. */
  1214.  
  1215.             case 2:    ScrollLines[CursorY] . Width        = GetFontWidth();
  1216.                 ScrollLines[CursorY] . Left        = 0;
  1217.                 ScrollLines[CursorY] . Right        = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  1218.                 ScrollLines[CursorY] . ColourMask    = BgPen;
  1219.  
  1220.                 break;
  1221.  
  1222.                 /* Erase from current cursor position towards end of line. */
  1223.  
  1224.             default:if(CursorX)
  1225.                 {
  1226.                     if(!ScrollLines[CursorY] . Width)
  1227.                         ScrollLines[CursorY] . Width = GetFontWidth();
  1228.  
  1229.                     ScrollLines[CursorY] . ColourMask |= BgPen;
  1230.                 }
  1231.                 else
  1232.                 {
  1233.                     ScrollLines[CursorY] . Width        = GetFontWidth();
  1234.                     ScrollLines[CursorY] . Left        = 0;
  1235.                     ScrollLines[CursorY] . ColourMask    = BgPen;
  1236.                 }
  1237.  
  1238.                 ScrollLines[CursorY] . Right = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  1239.                 break;
  1240.         }
  1241.     }
  1242.     else
  1243.     {
  1244.         switch(Mode)
  1245.         {
  1246.                 /* Erase from left margin to current cursor position (inclusive). */
  1247.  
  1248.             case 1:    ScrollLines[CursorY] . Left = CursorX;
  1249.  
  1250.                 if(ScrollLines[CursorY] . Left >= ScrollLines[CursorY] . Right)
  1251.                 {
  1252.                     ScrollLines[CursorY] . Left    = 32767;
  1253.                     ScrollLines[CursorY] . Right    = 0;
  1254.                     ScrollLines[CursorY] . Width    = 0;
  1255.                 }
  1256.  
  1257.                 break;
  1258.  
  1259.                 /* Erase entire line. */
  1260.  
  1261.             case 2:    ScrollLines[CursorY] . Left    = 32767;
  1262.                 ScrollLines[CursorY] . Right    = 0;
  1263.                 ScrollLines[CursorY] . Width    = 0;
  1264.  
  1265.                 break;
  1266.  
  1267.                 /* Erase from current cursor position towards end of line. */
  1268.  
  1269.             default:if(CursorX)
  1270.                     ScrollLines[CursorY] . Right = CursorX;
  1271.                 else
  1272.                 {
  1273.                     ScrollLines[CursorY] . Left    = 32767;
  1274.                     ScrollLines[CursorY] . Right    = 0;
  1275.                     ScrollLines[CursorY] . Width    = 0;
  1276.                 }
  1277.  
  1278.                 break;
  1279.         }
  1280.     }
  1281.  
  1282.     ScrollFrameUpdate();
  1283. }
  1284.  
  1285.     /* ScrollLineEraseCharacters(LONG Chars):
  1286.      *
  1287.      *    Erase a number of characters in the current cursor line.
  1288.      */
  1289.  
  1290. VOID
  1291. ScrollLineEraseCharacters(LONG Chars)
  1292. {
  1293.         /* Any characters to erase? */
  1294.  
  1295.     if(BgPen)
  1296.     {
  1297.         if(!ScrollLines[CursorY] . Width)
  1298.             ScrollLines[CursorY] . Width = GetFontWidth();
  1299.  
  1300.         ScrollLines[CursorY] . Left    = 0;
  1301.         ScrollLines[CursorY] . Right    = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  1302.  
  1303.         ScrollLines[CursorY] . ColourMask |= BgPen;
  1304.     }
  1305.     else
  1306.     {
  1307.         if(ScrollLines[CursorY] . Right > Chars)
  1308.             ScrollLines[CursorY] . Right -= Chars;
  1309.         else
  1310.             ScrollLines[CursorY] . Right = 0;
  1311.     }
  1312. }
  1313.  
  1314.     /* ScrollLineShiftChar(LONG Size):
  1315.      *
  1316.      *    Shift the characters following the current cursor position
  1317.      *    Size characters to the right.
  1318.      */
  1319.  
  1320. VOID
  1321. ScrollLineShiftChar(LONG Size)
  1322. {
  1323.         /* Any characters to scroll? */
  1324.  
  1325.     if(BgPen)
  1326.     {
  1327.         if(!ScrollLines[CursorY] . Width)
  1328.             ScrollLines[CursorY] . Width = GetFontWidth();
  1329.  
  1330.         ScrollLines[CursorY] . Left    = 0;
  1331.         ScrollLines[CursorY] . Right    = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  1332.  
  1333.         ScrollLines[CursorY] . ColourMask |= BgPen;
  1334.     }
  1335.     else
  1336.     {
  1337.         LONG Temp;
  1338.  
  1339.         ScrollLines[CursorY] . Right += Size;
  1340.  
  1341.         if((Temp = ScrollLines[CursorY] . Right * ScrollLines[CursorY] . Width) > LastPixel)
  1342.             ScrollLines[CursorY] . Right = (LastPixel + 1) / ScrollLines[CursorY] . Width;
  1343.         else
  1344.         {
  1345.             if(ScrollLines[CursorY] . Right < 0)
  1346.                 ScrollLines[CursorY] . Right = 0;
  1347.         }
  1348.     }
  1349. }
  1350.  
  1351.     /* ScrollLinePutString(LONG Length):
  1352.      *
  1353.      *    Update the line info according to the length of a string
  1354.      *    to be printed.
  1355.      */
  1356.  
  1357. VOID
  1358. ScrollLinePutString(LONG Length)
  1359. {
  1360.     if(Length)
  1361.     {
  1362.         LONG Width;
  1363.  
  1364.             /* Which scale is the font we are currently using? */
  1365.  
  1366.         if(RasterAttr[CursorY] >= SCALE_ATTR_TOP2X)
  1367.         {
  1368.                 /* Valid length? */
  1369.  
  1370.             if(CursorX + Length >= RasterWidth / 2)
  1371.                 Length = (RasterWidth / 2) - CursorX;
  1372.  
  1373.                 /* Double width. */
  1374.  
  1375.             Width = TextFontWidth * 2;
  1376.         }
  1377.         else
  1378.         {
  1379.             if(CurrentCharWidth == SCALE_HALF)
  1380.             {
  1381.                     /* Valid length? */
  1382.  
  1383.                 if(CursorX + Length >= RasterWidth * 2)
  1384.                     Length = (RasterWidth * 2) - CursorX;
  1385.  
  1386.                     /* Half width. */
  1387.  
  1388.                 Width = TextFontWidth / 2;
  1389.             }
  1390.             else
  1391.             {
  1392.                     /* Valid length? */
  1393.  
  1394.                 if(CursorX + Length >= RasterWidth)
  1395.                     Length = RasterWidth - CursorX;
  1396.  
  1397.                     /* Normal width. */
  1398.  
  1399.                 Width = TextFontWidth;
  1400.             }
  1401.         }
  1402.  
  1403.             /* Sensible value? */
  1404.  
  1405.         if(Length > 0)
  1406.         {
  1407.             struct ScrollLineInfo *Alias = &ScrollLines[CursorY];
  1408.  
  1409.                 /* Update font scale. */
  1410.  
  1411.             Alias -> Width = Width;
  1412.  
  1413.                 /* Update right margin. */
  1414.  
  1415.             if(CursorX < Alias -> Left)
  1416.                 Alias -> Left = CursorX;
  1417.  
  1418.                 /* Update left margin. */
  1419.  
  1420.             if(CursorX + Length > Alias -> Right)
  1421.                 Alias -> Right = CursorX + Length;
  1422.  
  1423.                 /* Update topmost line. */
  1424.  
  1425.             if(CursorY < ScrollLineFirst)
  1426.                 ScrollLineFirst = CursorY;
  1427.  
  1428.                 /* Update bottommost line. */
  1429.  
  1430.             if(CursorY > ScrollLineLast)
  1431.                 ScrollLineLast = CursorY;
  1432.  
  1433.             if(UseMasking)
  1434.             {
  1435.                     /* Update line colour mask. */
  1436.  
  1437.                 Alias -> ColourMask |= FgPen | BgPen;
  1438.  
  1439.                     /* Set write mask (will affect Text() since it is called
  1440.                      * after this routine has finished.
  1441.                      */
  1442.  
  1443.                 SetMask(RPort,Alias -> ColourMask);
  1444.             }
  1445.         }
  1446.     }
  1447. }
  1448.