home *** CD-ROM | disk | FTP | other *** search
/ Languages Around the World / LanguageWorld.iso / language / japanese / win_prog / win_jwp / reformat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-31  |  18.8 KB  |  731 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4.  
  5. BOOL NullParaFormatProc(FILEOPTIONS *f, PARAGRAPH far *pp, int n);
  6.  
  7. static UNIT far *CurrentPosition, far *TopPosition;
  8. static POSITION StopPos;
  9. static long int OldBottom;
  10.  
  11. static BOOL TopChanged;
  12. static BOOL (* NewParaFormatProc)(FILEOPTIONS *, PARAGRAPH far *, int) = NullParaFormatProc;
  13. static int nr_para = 0;
  14.  
  15.  
  16.  
  17. static BOOL NullParaFormatProc(FILEOPTIONS *f, PARAGRAPH far *pp, int n)
  18. {
  19.     return (TRUE);
  20. }
  21.  
  22.  
  23.  
  24. void SetReformatProc (BOOL (*f_pf)(FILEOPTIONS *, PARAGRAPH far *, int))
  25. {
  26.     if (f_pf == NULL) NewParaFormatProc = NullParaFormatProc;
  27.     else NewParaFormatProc = f_pf;
  28. }
  29.  
  30.  
  31.  
  32. static void SplitLine (FILEOPTIONS *f, POSITION p, int Options)
  33. {
  34.     int i, j, len;
  35.     unsigned int n;
  36.     PARAGRAPH far *pp;
  37.     ONELINE far *lp;
  38.  
  39.  
  40.     /* How many blocks needed? */
  41.  
  42.     len = unitlen(&UNITOF(p, POSOF(p)+1)) + 1;
  43.     n = len / TEXTBLOCKSIZE;
  44.     n = (n + 1) * TEXTBLOCKSIZE;
  45.  
  46.     pp = StructAlloc(PARAGRAPH);
  47.  
  48.     pp->leftindent = PARAOF(p)->leftindent;
  49.     pp->rightindent = PARAOF(p)->rightindent;
  50.     pp->firstindent = PARAOF(p)->firstindent;
  51.     pp->spacing = PARAOF(p)->spacing;
  52.     pp->spacemulti = PARAOF(p)->spacemulti;
  53.  
  54.     pp->prev = PARAOF(p);
  55.     pp->next = PARAOF(p)->next;
  56.     PARAOF(p)->next = pp;
  57.  
  58.     if (pp->next != NULL) pp->next->prev = pp;
  59.     else f->eof = pp;
  60.  
  61.  
  62.     pp->textsize = n;
  63.  
  64.     lp = pp->lines = pp->lastline = StructAlloc(ONELINE);
  65.     f->nr_lines++;
  66.  
  67.     lp->prev = lp->next = NULL;
  68.  
  69.     lp->position = 0;
  70.     pp->text = (UNIT far *) BlockAlloc(n * sizeof(UNIT));
  71.  
  72.     lp->length = len;
  73.     lp->height = lp->width = 0;
  74.  
  75.  
  76.     /* Copy the text */
  77.  
  78.     for (i = 0, j = POSOF(p) + 1; ; i++, j++) {
  79.         if (Options & OP_MOVESEL) {
  80.             if (SELPARA1(f) == PARAOF(p) && &UNITOF(p, j) == &SELCHAR1(f)) {
  81.                 SELPARA1(f) = pp;
  82.                 SELPOS1(f) = i;
  83.             }
  84.             if (SELPARA2(f) == PARAOF(p) && &UNITOF(p, j) == &SELCHAR2(f)) {
  85.                 SELPARA2(f) = pp;
  86.                 SELPOS2(f) = i;
  87.             }
  88.         }
  89.  
  90.         if (&UNITOF(f->current,CURCHAR(f)) == &UNITOF(p, j)) {
  91.             CURPARA(f) = pp;
  92.             CURLINE(f) = lp;
  93.             CURCHAR(f) = i;
  94.         }
  95.         if (CurrentPosition == &UNITOF(p, j)) CurrentPosition = &(pp->text[i]);
  96.         if (TopPosition == &UNITOF(p, j)) {
  97.             TopPosition = &(pp->text[i]);
  98.             TopChanged = (j != 0);
  99.         }
  100.  
  101.         pp->text[i] = UNITOF(p,j);
  102.         if (!CHAROF(p, j)) break;
  103.     }
  104.  
  105.  
  106.     PARAOF(p)->lastline = LINEOF(p);
  107.     LINEOF(p)->length = POSOF(p);
  108.     CHAROF(p, POSOF(p)) = 0;
  109.  
  110.     f->nr_bytes--;
  111.  
  112.     ReallocateText(p, unitlen(PARAOF(p)->text));
  113.  
  114.     /* Special format? */
  115.  
  116.     NewParaFormatProc(f, pp, nr_para + 1);
  117. }
  118.  
  119.  
  120.  
  121. static void JoinLine (FILEOPTIONS *f, POSITION p, int Options)
  122. {
  123.     int i, j;
  124.     PARAGRAPH far *pp;
  125.     ONELINE far *tp1, far *tp2;
  126.  
  127.  
  128.     /* Join with the next paragraph */
  129.  
  130.     pp = PARAOF(p)->next;
  131.     if (pp->next == NULL && pp == f->eof) f->eof = PARAOF(p);
  132.  
  133.  
  134.     /* Do we need to shift the next paragraph's margins up? */
  135.  
  136.     if (POSOF(p) <= 0) {
  137.         PARAOF(p)->firstindent = pp->firstindent;
  138.         PARAOF(p)->leftindent = pp->leftindent;
  139.         PARAOF(p)->rightindent = pp->rightindent;
  140.     }
  141.  
  142.  
  143.     /* How many blocks needed? */
  144.  
  145.     ReallocateText (p, unitlen(pp->text) + unitlen(PARAOF(p)->text) + 1);
  146.  
  147.     CurrentPosition = &UNITOF(f->current,CURCHAR(f));
  148.     TopPosition = TOPPARA(f)->text + TOPLINE(f)->position;
  149.  
  150.  
  151.     /* Is the cursor on the remaining text? */
  152.  
  153.     for (i = POSOF(p) + 1; ; i++) {
  154.         if (CurrentPosition == &UNITOF(p,i)) {
  155.             CurrentPosition = &UNITOF(p,POSOF(p));
  156.             break;
  157.         } else if (!CHAROF(p,i)) break;
  158.     }
  159.  
  160.  
  161.     /* Copy the text */
  162.  
  163.     for (i = 0, j = POSOF(p); ; i++, j++) {
  164.         if (Options & OP_MOVESEL) {
  165.             if (SELPARA1(f) == pp && &(pp->text[i]) == &SELCHAR1(f)) {
  166.                 SELPARA1(f) = PARAOF(p);
  167.                 SELPOS1(f) = LINEOF(p)->position + j;
  168.             }
  169.             if (SELPARA2(f) == pp && &(pp->text[i]) == &SELCHAR2(f)) {
  170.                 SELPARA2(f) = PARAOF(p);
  171.                 SELPOS2(f) = LINEOF(p)->position + j;
  172.             }
  173.         }
  174.  
  175.         if (CurrentPosition == pp->text + i) CurrentPosition = &UNITOF(p, j);
  176.         if (TopPosition == pp->text + i) {
  177.             TopPosition = &UNITOF(p, j);
  178.             TopChanged = (j != 0);
  179.         }
  180.  
  181.         UNITOF(p,j) = pp->text[i];
  182.         if (!CHAROF(p, j)) break;
  183.     }
  184.  
  185.  
  186.     PARAOF(p)->lastline = LINEOF(p);
  187.     LINEOF(p)->length = j;
  188.  
  189.  
  190.     /* Re-link */
  191.  
  192.     PARAOF(p)->next = pp->next;
  193.     if (pp->next != NULL) pp->next->prev = PARAOF(p);
  194.  
  195.     PARAOF(StopPos) = pp->next;
  196.     LINEOF(StopPos) = (pp->next != NULL) ? pp->next->lines : NULL;
  197.     POSOF(StopPos) = 0;
  198.  
  199.  
  200.     /* Gets rid of the next paragraph */
  201.  
  202.     for (tp1 = pp->lines; tp1 != NULL; ) {
  203.         tp2 = tp1;
  204.         tp1 = tp1->next;
  205.         OldBottom += tp2->height + pp->spacing;
  206.         FreeStruct(tp2);
  207.         f->nr_lines--;
  208.     }
  209.  
  210.     if (pp->text != NULL) FreeBlock(pp->text);
  211.     FreeStruct(pp);
  212.  
  213.     f->nr_bytes--;
  214. }
  215.  
  216.  
  217.  
  218. static BOOL IsWhiteSpace (KANJI ch)
  219. {
  220.     if (ch <= ' ') return (TRUE);
  221.     return (FALSE);
  222. }
  223.  
  224.  
  225.  
  226. static BOOL IsWordWrap (POSITION *p)
  227. {
  228.     int i;
  229.     KANJI ch;
  230.     UNIT far *cp = &UNITOF(*p, POSOF(*p));
  231.  
  232.     ch = cp->kanji;
  233.  
  234.     if (ISKANJI(ch)) return (FALSE);
  235.     if (IsWhiteSpace(ch)) return (FALSE);
  236.  
  237.     /* Back-seek */
  238.  
  239.     for (i = POSOF(*p); i >= 0; i--, cp--) {
  240.         ch = cp->kanji;
  241.         if (ISKANJI(ch) || IsWhiteSpace(ch) || ch == '-') break;
  242.     }
  243.  
  244.     if (i < 0) return (FALSE);      /* Word longer than one line! */
  245.  
  246.     POSOF(*p) = i + 1;
  247.     return (TRUE);
  248. }
  249.  
  250.  
  251.  
  252. static BOOL PotentialWordWrap (POSITION p)
  253. {
  254.     int i;
  255.     KANJI ch;
  256.     UNIT far *cp = &UNITOF(p, POSOF(p));
  257.  
  258.     if (ISKANJI(cp->kanji)) {
  259.         if (POSOF(p) == 0) return (TRUE);
  260.         return (FALSE);
  261.     }
  262.  
  263.     /* Skip white spaces */
  264.  
  265.     for (i = POSOF(p); i > 0; i--, POSOF(p)--, cp--) {
  266.         ch = cp->kanji;
  267.         if (ISKANJI(ch)) return (FALSE);
  268.         if (!IsWhiteSpace(ch)) break;
  269.     }
  270.  
  271.     if (i < 0) return (FALSE);
  272.  
  273.     /* Now, is this word alone? */
  274.  
  275.     return (!IsWordWrap(&p));
  276. }
  277.  
  278.  
  279.  
  280. static BOOL OpenNewLine (FILEOPTIONS *f, POSITION p, int width, int height, int length)
  281. {
  282.     UNIT far *cp = &UNITOF(p,POSOF(p));
  283.     BOOL CanStop = FALSE;
  284.  
  285.     if (LINEOF(p)->next == NULL) {
  286.         LINEOF(p)->next = StructAlloc(ONELINE);
  287.         LINEOF(p)->next->prev = LINEOF(p);
  288.         LINEOF(p)->next->next = NULL;
  289.         LINEOF(p)->next->position = 0;
  290.         f->nr_lines++;
  291.     } else {
  292.         if (POS2ABS(p) == LINEOF(p)->next->position) CanStop = TRUE;
  293.     }
  294.  
  295.     LINEOF(p)->height = height;
  296.     LINEOF(p)->width = width;
  297.     LINEOF(p)->length = length;
  298.  
  299.     LINEOF(p) = LINEOF(p)->next;
  300.     LINEOF(p)->position = cp - PARAOF(p)->text;
  301.     if (!CanStop) LINEOF(p)->length = unitlen(cp);
  302.  
  303.     return (CanStop);
  304. }
  305.  
  306.  
  307.  
  308. void ReformatParagraph (FILEOPTIONS *f, POSITION start, PARAGRAPH far *stop, int options)
  309. {
  310.     int i, j, r, w;
  311.     long int OldTop, NewBottom;
  312.     int BlockHeight = LINEGAP(f);
  313.     int MaxHeight, LineLength;
  314.     long int dimension;
  315.     UNIT far *cp;
  316.     POSITION p;
  317.     RECT rect;
  318.     BOOL GoneBack = FALSE, CanStop;
  319.     BOOL relaxed, SoftReturn;
  320.     HDC hdc, hdcmem;
  321.     HBRUSH hbrush;
  322.     HBITMAP hbitmap;
  323.  
  324.  
  325.     TopChanged = FALSE;
  326.  
  327.     /* Word wrap situation? */
  328.  
  329.     if (PotentialWordWrap(start) && LINEOF(start)->prev != NULL) {
  330.         p = start;
  331.         LINEOF(start) = LINEOF(start)->prev;
  332.         POSOF(start) = LINEOF(start)->length - 1;
  333.  
  334.         GoneBack = TRUE;
  335.     }
  336.  
  337.  
  338.     /* Now take care of some accounting */
  339.  
  340.     CurrentPosition = &UNITOF(f->current,CURCHAR(f));
  341.     TopPosition = &(TOPPARA(f)->text[TOPLINE(f)->position]);
  342.  
  343.     if (stop != NULL) {
  344.         PARAOF(StopPos) = stop;
  345.         LINEOF(StopPos) = stop->lines;
  346.         POSOF(StopPos) = 0;
  347.     } else {
  348.         PARAOF(StopPos) = NULL;
  349.         LINEOF(StopPos) = NULL;
  350.         POSOF(StopPos) = 0;
  351.     }
  352.  
  353.  
  354.     /* Find the region top/bottom */
  355.  
  356.     if (options & OP_UPDATE) {
  357.         if (LINEOF(start) == TOPLINE(f)->prev) {
  358.             p = start;
  359.             j = -(LINEOF(p)->height + PARAOF(p)->spacing);
  360.         } else if (TOPLINE(f)->prev == NULL && TOPPARA(f)->prev != NULL &&
  361.                    LINEOF(start) == TOPPARA(f)->prev->lastline) {
  362.             p = start;
  363.             j = -(LINEOF(p)->height + PARAOF(p)->spacing);
  364.         } else {
  365.             p = f->top;
  366.             j = LINEGAP(f);
  367.         }
  368.  
  369.         do {
  370.             if (j >= f->height) {
  371.                 ErrorMessage(global.hwnd, "ReformatParagraph: Top of block not found!");
  372.                 break;
  373.             }
  374.             if (LINEOF(p) == LINEOF(start)) break;
  375.             j += LINEOF(p)->height + PARAOF(p)->spacing;
  376.         } while (NEXTLINE(p));
  377.  
  378.         NewBottom = j;
  379.         OldTop = j - LINEGAP(f);
  380.  
  381.         do {
  382.             if (LINEOF(p) == LINEOF(StopPos)) break;
  383.             j += LINEOF(p)->height + PARAOF(p)->spacing;
  384.         } while (NEXTLINE(p));
  385.  
  386.         OldBottom = j - LINEGAP(f);
  387.     } else {
  388.         NewBottom = OldBottom = OldTop = 0L;
  389.     }
  390.  
  391.  
  392.     /* Now reformat the paragraph! */
  393.  
  394.     p = start;
  395.     nr_para = 0;
  396.  
  397. Loop:
  398.  
  399.     NewParaFormatProc(f, PARAOF(p), nr_para);
  400.  
  401.  
  402.     MaxHeight = f->basefont->height;
  403.  
  404.     if (f->linelen > PARAOF(p)->rightindent) {
  405.         LineLength = (f->linelen - PARAOF(p)->rightindent) * BASEWIDTH(f);
  406.     } else {
  407.         LineLength = BASEWIDTH(f);
  408.     }
  409.  
  410.     relaxed = SoftReturn = FALSE;
  411.  
  412.  
  413.     i = POSOF(p);
  414.     j = CalcLength(f, &p);
  415.     cp = &UNITOF(p,POSOF(p));
  416.  
  417.     LINEOF(p)->length = unitlen(cp);
  418.  
  419.     for (; ; POSOF(p)++, i++, cp++) {
  420.         if (cp->kanji == '\r') {                  /* ^M = hard return */
  421.             //nr_para++;
  422.             SplitLine(f, p, options);
  423.             cp = &UNITOF(p,POSOF(p));
  424.         } else if (cp->kanji == '\b') {           /* ^H = join lines */
  425.             while (cp->kanji == '\b') {
  426.                 JoinLine(f, p, options);
  427.                 cp = &UNITOF(p,POSOF(p));
  428.                 LineLength = (f->linelen - PARAOF(p)->rightindent) * BASEWIDTH(f);
  429.             }
  430.         }
  431.  
  432.  
  433.         if (cp->kanji == '\n') {                  /* ^J = soft return */
  434.             SoftReturn = TRUE;
  435.             w = 0;
  436.         } else {
  437.             SoftReturn = FALSE;
  438.             if (cp->kanji) {
  439.                 dimension = GetDimension(f, p, j);
  440.                 w = LOWORD(dimension);
  441.                 if (POSOF(p) > 0 && cp[-1].kanji != '\t' && !ISKANJI(cp[-1].kanji) && ISKANJI(cp->kanji))
  442.                     w += f->leading;
  443.             } else {
  444.                 w = 0;
  445.             }
  446.         }
  447.  
  448.  
  449.         /* Line break? */
  450.  
  451.         if ((f->type & FN_NORMAL) && (j + w > LineLength || SoftReturn)) {
  452.             if (SoftReturn) {
  453.                 relaxed = FALSE;
  454.                 POSOF(p)++;
  455.             } else {
  456.                 relaxed = global.relaxmargin && IsSmallKana(cp->kanji);
  457.                 relaxed |= IsWhiteSpace(cp->kanji);
  458.             }
  459.  
  460.             if (!relaxed) {
  461.                 /* Word wrap? */
  462.  
  463.                 if (!SoftReturn && !ISKANJI(cp->kanji) && IsWordWrap(&p)) {
  464.                     i = POSOF(p);
  465.                     cp = &UNITOF(p, POSOF(p));
  466.  
  467.                     j = CalcLength(f, &p);
  468.                 }
  469.  
  470.                 /* Open new line */
  471.  
  472.                 NewBottom += MaxHeight + PARAOF(p)->spacing;
  473.                 BlockHeight += MaxHeight + PARAOF(p)->spacing;
  474.  
  475.                 r = OpenNewLine(f, p, j, MaxHeight, SoftReturn ? POSOF(p) - 1 : POSOF(p));
  476.  
  477.                 LINEOF(p) = LINEOF(p)->next;
  478.                 POSOF(p) = -1;
  479.                 if (!SoftReturn) cp--;
  480.  
  481.                 MaxHeight = f->basefont->height;
  482.                 j = PARAOF(p)->leftindent * BASEWIDTH(f);
  483.  
  484.                 /* Can we stop? */
  485.  
  486.                 if ((options & OP_MINIMAL) && r) {
  487.                     if (GoneBack && LINEOF(p) == LINEOF(start)->next) {
  488.                         CanStop = GoneBack = FALSE;
  489.                     } else {
  490.                         CanStop = TRUE;
  491.                     }
  492.                 } else {
  493.                     CanStop = FALSE;
  494.                 }
  495.  
  496.                 if (CanStop) {
  497.                     POSITION pp;
  498.  
  499.                     if (LINEOF(StopPos) == NULL) {      /* StopLine can be NULL */
  500.                         PARAOF(pp) = f->eof;
  501.                         LINEOF(pp) = f->eof->lastline;
  502.                         POSOF(pp) = 0;
  503.                     } else {
  504.                         pp = StopPos;
  505.                         PREVLINE(pp);
  506.                     }
  507.  
  508.                     do {
  509.                         OldBottom -= LINEOF(pp)->height + PARAOF(pp)->spacing;
  510.                         if (!PREVLINE(pp)) break;
  511.                     } while (LINEOF(pp) != LINEOF(p)->prev);
  512.  
  513.                     StopPos = p;
  514.  
  515.                     goto Update;
  516.                 }
  517.             } else {
  518.                 j += w;
  519.                 if (ISKANJI(cp->kanji)) j += f->leading;
  520.             }
  521.         } else {
  522.             //if (HIWORD(dimension) > MaxHeight) MaxHeight = HIWORD(dimension);
  523.             j += w;
  524.             if (ISKANJI(cp->kanji)) j += f->leading;
  525.         }
  526.  
  527.         if (POSOF(p) >= 0 && cp == CurrentPosition) f->current = p;
  528.         if (POSOF(p) >= 0 && cp == TopPosition) {
  529.             f->top = p;
  530.             TopChanged = (POSOF(p) != 0);
  531.         }
  532.  
  533.         if (!cp->kanji) break;
  534.     }
  535.  
  536.     NewBottom += MaxHeight + PARAOF(p)->spacing;
  537.     BlockHeight += MaxHeight + PARAOF(p)->spacing;
  538.  
  539.     LINEOF(p)->height = MaxHeight;
  540.     LINEOF(p)->length = unitlen(PARAOF(p)->text + LINEOF(p)->position);
  541.     LINEOF(p)->width = j;
  542.     PARAOF(p)->lastline = LINEOF(p);
  543.  
  544.  
  545.     /* Now, if it is at the beginning of a line, move it to the end */
  546.     /* of the previous line.                                        */
  547.  
  548.     if ((options & OP_MOVETOEND) && CURPARA(f) == PARAOF(p) &&
  549.         CURCHAR(f) <= 0 && CURLINE(f)->prev != NULL) {
  550.  
  551.         CURLINE(f) = CURLINE(f)->prev;
  552.         CURCHAR(f) = CURLINE(f)->length;
  553.     }
  554.  
  555.     /* If the last line is blank, get rid of it */
  556.  
  557.     if ((options & OP_MOVETOEND) &&
  558.         !CHAROF(p,0) && LINEOF(p)->prev != NULL &&
  559.         PARAOF(p)->text[LINEOF(p)->position - 1].kanji != '\n') {
  560.  
  561.             NewBottom -= LINEOF(p)->height + PARAOF(p)->spacing;
  562.             BlockHeight -= LINEOF(p)->height + PARAOF(p)->spacing;
  563.             PARAOF(p)->lastline = LINEOF(p) = LINEOF(p)->prev;
  564.     }
  565.  
  566.  
  567.     {
  568.         ONELINE far *tp1, far *tp2;
  569.  
  570.         for (tp1 = LINEOF(p)->next; tp1 != NULL; ) {
  571.             tp2 = tp1;
  572.             tp1 = tp1->next;
  573.             FreeStruct(tp2);
  574.             f->nr_lines--;
  575.         }
  576.  
  577.         LINEOF(p)->next = NULL;
  578.     }
  579.  
  580.     /* Reformat the next paragraph? */
  581.  
  582.     if (!NEXTLINE(p)) LINEOF(p) = NULL;
  583.  
  584.     if (LINEOF(p) != LINEOF(StopPos)) {
  585.         POSOF(p) = 0;
  586.         nr_para++;
  587.         goto Loop;
  588.     }
  589.  
  590.  
  591. Update:
  592.  
  593.     if (!(options & OP_UPDATE)) return;
  594.  
  595.     NewBottom -= LINEGAP(f);
  596.     BlockHeight -= LINEGAP(f);
  597.  
  598.     if (!FindCaret(f, TRUE) || TopChanged) {
  599.         if (TopChanged) {
  600.             /* Make sure MoveIntoWindow doesn't find the top */
  601.             /* Move it to the last line */
  602.             TOPPARA(f) = f->eof;
  603.             TOPLINE(f) = f->eof->lastline;
  604.         }
  605.  
  606.         MoveIntoWindow(f);
  607.         InvalidateRect(f->hwnd, NULL, TRUE);
  608.         UpdateWindow(f->hwnd);
  609.         return;
  610.     }
  611.  
  612.     /* Now redraw the update portion! */
  613.  
  614.     hdc = GetDC(f->hwnd);
  615.     hdcmem = CreateCompatibleDC(hdc);
  616.     SetTextColor(hdcmem, GetSysColor(COLOR_WINDOWTEXT));
  617.     SetBkColor(hdcmem, GetSysColor(COLOR_WINDOW));
  618.  
  619.     if (BlockHeight + OldTop >= f->height) BlockHeight = f->height - OldTop;
  620.  
  621.     hbitmap = CreateCompatibleBitmap (hdc, f->width, BlockHeight);
  622.     if (hbitmap != NULL) {
  623.         SelectObject(hdcmem, hbitmap);
  624.  
  625.         rect.left = 0;
  626.         rect.right = f->width;
  627.         rect.top = 0;
  628.         rect.bottom = NewBottom - OldTop;
  629.  
  630.         hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  631.         FillRect(hdcmem, &rect, hbrush);
  632.         DeleteObject(hbrush);
  633.  
  634.         rect.top = OldTop;
  635.         rect.bottom = NewBottom;
  636.  
  637.         RedrawFile(f, hdcmem, 0, OldTop, &rect, global.showspecial);     /* Draw on the hdc! */
  638.     } else {
  639.         w = f->basefont->height + f->spacing;
  640.  
  641.         hbitmap = CreateCompatibleBitmap (hdc, f->width, w);
  642.         if (hbitmap != NULL) {
  643.             SelectObject(hdcmem, hbitmap);
  644.  
  645.             rect.left = 0;
  646.             rect.right = f->width;
  647.             rect.top = 0;
  648.             rect.bottom = NewBottom - OldTop;
  649.  
  650.             hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  651.             FillRect(hdcmem, &rect, hbrush);
  652.             DeleteObject(hbrush);
  653.  
  654.             for (i = 0; i < BlockHeight; i += w) {
  655.                 rect.top = OldTop + i;
  656.                 rect.bottom = OldTop + i + w;
  657.  
  658.                 RedrawFile(f, hdcmem, 0, OldTop, &rect, global.showspecial);     /* Draw on the hdc! */
  659.             }
  660.         } else {
  661.             rect.left = OldTop;
  662.             rect.right = f->width;
  663.             rect.top = 0;
  664.             rect.bottom = NewBottom;
  665.             InvalidateRect(f->hwnd, &rect, TRUE);
  666.             UpdateWindow(f->hwnd);
  667.         }
  668.     }
  669.  
  670.  
  671.     /* Shift the under-part up/down */
  672.  
  673.     HideCaret(f->hwnd);
  674.  
  675.     rect.left = 0;
  676.     rect.right = f->width;
  677.  
  678.     if (NewBottom < OldBottom) {
  679.         if (OldBottom < f->height) {
  680.             rect.top = NewBottom;
  681.             rect.bottom = f->height;
  682.             ScrollWindow(f->hwnd, 0, NewBottom - OldBottom, NULL, &rect);
  683.         } else if (NewBottom < f->height) {
  684.             rect.top = NewBottom;
  685.             rect.bottom = f->height;
  686.             InvalidateRect(f->hwnd, &rect, TRUE);
  687.         }
  688.     } else if (NewBottom > OldBottom) {
  689.         if (NewBottom < f->height) {
  690.             rect.top = OldBottom;
  691.             rect.bottom = f->height;
  692.             ScrollWindow(f->hwnd, 0, NewBottom - OldBottom, NULL, &rect);
  693.         }
  694.     }
  695.  
  696.  
  697.     /* Redraw the screen */
  698.  
  699.     if (hbitmap != NULL) {
  700.         BitBlt(hdc, 0, OldTop, f->width, BlockHeight, hdcmem, 0, OldTop, SRCCOPY);
  701.     }
  702.     //ShowCaret(f->hwnd);
  703.  
  704.     ReleaseDC(f->hwnd, hdc);
  705.     DeleteDC(hdcmem);
  706.     if (hbitmap != NULL) DeleteObject(hbitmap);
  707.  
  708.     /*if (CURPARA(f) != global.cpospara)*/ FillCPos(f, CURPARA(f), 0, -1);
  709.  
  710.     //i = POS2ABS(f->current);
  711.     //CURX(f) = global.cpos[i].x;
  712.     //CURY(f) = global.cpos[i].y;
  713.     f->pseudo = f->cursor;
  714.     DoCaret(f, CURX(f), CURY(f) - CURLINE(f)->height, TRUE);
  715.     Triangles(f);
  716.     ShowCaret(f->hwnd);
  717. }
  718.  
  719.  
  720. void ReformatFile (FILEOPTIONS *f)
  721. {
  722.     POSITION p;
  723.  
  724.     for (PARAOF(p) = f->paragraph; PARAOF(p) != NULL; PARAOF(p) = PARAOF(p)->next) {
  725.         LINEOF(p) = PARAOF(p)->lines;
  726.         POSOF(p) = 0;
  727.  
  728.         ReformatParagraph(f, p, NULL, 0);
  729.     }
  730. }
  731.