home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / tvision / wrdwrp / wrap.asm < prev   
Encoding:
Assembly Source File  |  1992-01-03  |  21.8 KB  |  792 lines

  1. ;/**************************************************************************/
  2. ;/*                                                                        */
  3. ;/*                   Copyright (c) 1991 Primatech Inc.                    */
  4. ;/*                                                                        */
  5. ;/*                          All Rights Reserved                           */
  6. ;/*                                                                        */
  7. ;/**************************************************************************/
  8.  
  9. ;/*------------------------------------------------------------*/
  10. ;/* filename -       wrap.asm                                  */
  11. ;/*                                                            */
  12. ;/* function(s)                                                */
  13. ;/*                  TEditor::doWordWrapBuffer                 */
  14. ;/*------------------------------------------------------------*/
  15.  
  16. ;Created:       12 November 1991 by Jeffrey A. Hottle
  17.  
  18.  
  19.     IDEAL
  20.     JUMPS
  21.     MODEL LARGE, PROLOG
  22.  
  23.     INCLUDE "TVWRITE.INC"
  24.  
  25.     PUBLIC @TEditor@doWordWrapBuffer$qususns
  26.  
  27.     EXTRN @TEditor@changeBufSize$qs:PROC
  28.  
  29.     CR = 0Dh
  30.     LF = 0Ah
  31.  
  32. CODESEG
  33.  
  34. MACRO AdvancePtr
  35. LOCAL @@OK
  36.     inc  BX
  37.     cmp  BX,[ES:DI+TEditorCurPtr]
  38.     jne  @@OK
  39.     add  BX,[ES:DI+TEditorGapLen]
  40. @@OK:
  41. ENDM
  42.  
  43.  
  44.  
  45. ;ushort TEditor::doWordWrapBuffer( ushort start_ofs,
  46. ;                                  ushort min_chars,
  47. ;                                  int* line_delta )
  48. ;assume:
  49. ;   line_delta is initialized
  50. ;   start_ofs is beginning of a line
  51. ;   at least 2 lines or min_chars will be processed
  52. ;
  53. PROC @TEditor@doWordWrapBuffer$qususns
  54.  
  55.     ARG   thisPtr:FAR PTR, StartOfs:WORD, MinChars:WORD, LineDelta:PTR WORD
  56.     USES  DS,SI,DI
  57.     LOCAL Delta:WORD, CharCt:WORD, LineCt:WORD, RealDS:WORD
  58.     LOCAL BufChg:BYTE, LineChg:BYTE, LineStart:WORD, DelLastCR:BYTE
  59.     LOCAL WrapPos:WORD, WrapDX:WORD, WrapCharCt:WORD
  60.  
  61.     ASSUME DS:nothing, ES:nothing
  62.  
  63.     xor  AX,AX
  64.     mov  [Delta],AX
  65.     mov  [CharCt],AX
  66.     mov  [LineCt],AX
  67.     mov  [BufChg],AL
  68.  
  69.     mov  [RealDS],DS              ;save original DATASEG
  70.  
  71.     les  DI,[thisPtr]
  72.     lds  SI,[ES:DI+TEditorBuffer] ;DS:SI = buffer
  73.     mov  BX,[StartOfs]
  74.  
  75.     ; update BX if it is sitting at the start of the gap
  76.     cmp  BX,[ES:DI+TEditorCurPtr]
  77.     jne  ScanLine
  78.     add  BX,[ES:DI+TEditorGapLen]
  79.  
  80. ScanLine:
  81.     ;----------------------------------
  82.     ; scan to find line break position
  83.     ;----------------------------------
  84.     xor  DX,DX                    ;DH = CR count, DL = previous buffer char
  85.     xor  CX,CX                    ;CX = current x position
  86.     cld
  87.     xor  AX,AX
  88.     mov  [LineChg],AL
  89.     mov  [DelLastCR],AL
  90.     mov  [WrapPos],AX
  91.     mov  [LineStart],BX
  92.     jmp  short ScanSkip
  93. ScanNext:
  94.     mov  AH,AL                    ;save previous line character
  95.     AdvancePtr                    ;advance pointer
  96. ScanSkip:
  97.     mov  DL,AL                    ;save previous buffer character
  98.     cmp  BX,[ES:DI+TEditorBufSize];check for end of buffer
  99.     jae  BufEnd
  100.     inc  CX                       ;advance column number
  101.     inc  [CharCt]
  102.     mov  AL,[SI+BX]               ;get character from buffer
  103.     cmp  AL,CR                    ;is this character a CR?
  104.     jne  NotCR
  105.     AdvancePtr
  106.     cmp  [BYTE PTR SI+BX],LF      ;yes, is it CR+LF? (hard return)
  107.     jne  JustCR
  108.     AdvancePtr                    ;hard return, skip LF
  109.     inc  [CharCt]
  110.     jmp  DelAllCR                 ;remove all soft returns from this line
  111. JustCR:
  112.     inc  DH                       ;bump soft-return count
  113.     dec  CX                       ;don't count this as a column
  114.     jmp  ScanSkip
  115. NotCR:
  116.     cmp  AL,' '                   ;check for space
  117.     je   ScanNext
  118.  
  119.     cmp  AH,' '                   ;non-space, check prev for space or hyphen
  120.     je   SetBreak
  121.     cmp  AH,'-'
  122.     je   SetBreak
  123.  
  124.     cmp  CX,[ES:DI+TEditorRMargin];no break here, check if past end of line
  125.     jbe  ScanNext                 ;not past end
  126.  
  127.     cmp  [WrapPos],0              ;past end, have we found a break yet?
  128.     jnz  BreakPos                 ;yes
  129.     jmp  BreakPosGo               ;no, use this position
  130.  
  131. SetBreak:
  132.     mov  [WrapPos],BX
  133.     mov  [WrapDX],DX
  134.     push AX
  135.     mov  AX,[CharCt]
  136.     mov  [WrapCharCt],AX
  137.     pop  AX
  138.     cmp  CX,[ES:DI+TEditorRMargin];is this the end of the line?
  139.     jbe  ScanNext                 ;no
  140.  
  141.     ;---------------------------------------------------------
  142.     ; break position found, check if line already breaks here
  143.     ;---------------------------------------------------------
  144. BreakPos:
  145.     mov  BX,[WrapPos]             ;set current pointer back to wrap position
  146.     mov  DX,[WrapDX]              ;get previous buffer char & CR count
  147.     mov  AX,[WrapCharCt]          ;set proper character count
  148.     mov  [CharCt],AX
  149. BreakPosGo:
  150.     dec  [CharCt]                 ;adjust count for character after the break
  151.     cmp  DH,1                     ;check for 1 CR found
  152.     jne  FixBuffer
  153.     cmp  DL,CR                    ;check if CR is previous char in buffer
  154.     je   NextLine                 ;it is, no change to buffer needed
  155.     jmp  FixBuffer
  156.  
  157.     ;----------------------------------------
  158.     ; end of buffer, remove all soft returns
  159.     ;----------------------------------------
  160. BufEnd:
  161.     or   DH,DH                    ;any soft-returns in this line?
  162.     jz   Success                  ;no, we're done
  163.  
  164.     ;--------------------------------------
  165.     ; remove all soft returns in this line
  166.     ;--------------------------------------
  167. DelAllCR:
  168.     mov  [DelLastCR],1
  169.  
  170.     ;----------------------------------------------------------------
  171.     ; update buffer removing soft returns, setting new one if needed
  172.     ;----------------------------------------------------------------
  173. FixBuffer:
  174.     mov  CX,BX                    ;save ending position
  175.     or   DH,DH                    ;are there any CRs?
  176.     jz   NoCR
  177.     mov  BX,[LineStart]           ;get start-of-line position
  178. FindCR:
  179.     cmp  [BYTE PTR SI+BX],CR      ;is this character a CR?
  180.     je   FoundCR
  181.     AdvancePtr                    ;no, try next character
  182.     jmp  FindCR
  183. FoundCR:
  184.     dec  DH                       ;adjust CR count
  185.     jnz  DeleteIt                 ;not last one yet
  186.     cmp  [DelLastCR],0            ;delete last CR?
  187.     jz   LastCR
  188. DeleteIt:
  189.     dec  [Delta]                  ;adjust line delta value
  190.     mov  [LineChg],1
  191.     mov  [BufChg],1
  192.  
  193.     ; compress text at BX, updating ptr in CX and other object pointers
  194.     call CompressBuf
  195.     or   DH,DH
  196.     jnz  FindCR
  197.  
  198. LastCR:
  199.     ; shift text (if needed) to put CR at end of line
  200.     cmp  [DelLastCR],0            ;do we want a CR on this line?
  201.     jnz  RightPlace               ;no
  202.     cmp  DL,CR                    ;check if we have a CR in the right place
  203.     je   RightPlace
  204.  
  205.     ; shift text at BX thru CX and put CR in the hole
  206.     mov  [LineChg],1
  207.     mov  [BufChg],1
  208.     call ShiftBuf
  209.     mov  BX,CX                    ;put CR in the hole
  210.     mov  [BYTE PTR SI+BX],CR
  211.     AdvancePtr                    ;skip over that location
  212.     jmp  NextLine
  213.  
  214. NoCR:
  215.     cmp  [DelLastCR],0            ;do we want a CR on this line?
  216.     jnz  RightPlace               ;no
  217.  
  218.     ; expand buffer at end and insert CR in hole
  219.     mov  BX,CX
  220.     mov  AX,[RealDS]
  221.     call ExpandBuf
  222.     or   AX,AX                    ;check for expand failure
  223.     jz   Failure
  224.     mov  [LineChg],1
  225.     mov  [BufChg],1
  226.     inc  [Delta]                  ;adjust line delta value
  227.     mov  [BYTE PTR SI+BX],CR
  228.  
  229. RightPlace:
  230.     mov  BX,CX                    ;recover end-of-line pointer
  231.  
  232.     ;-----------------------------
  233.     ; process next line if needed
  234.     ;-----------------------------
  235. NextLine:
  236.     inc  [LineCt]
  237.     cmp  [LineCt],2               ;must do at least 2 lines
  238.     jb   ScanLine
  239.     mov  AX,[CharCt]              ;must process at least MinChars characters
  240.     cmp  AX,[MinChars]
  241.     jb   ScanLine
  242.     cmp  [LineChg],0              ;trickle down if needed
  243.     jz   Success
  244.     jmp  ScanLine
  245.  
  246. Failure:
  247.     mov  AX,wwsError              ;failure return value
  248.     jmp  short Exit
  249. Success:
  250.     mov  AX,wwsNoWrap             ;assume nothing happened
  251.     cmp  [BufChg],0
  252.     jz   Exit
  253.     mov  AX,wwsDidWrap            ;something happened
  254. Exit:
  255.     lds  BX,[LineDelta]           ;adjust line count
  256.     mov  CX,[Delta]
  257.     add  [BX],CX
  258.  
  259.     ret
  260.  
  261. ENDP
  262.  
  263.  
  264. PROC NOLANGUAGE DecreasePtr NEAR
  265.     push AX
  266.     mov  AX,[ES:DI+TEditorCurPtr]
  267.     add  AX,[ES:DI+TEditorGapLen]
  268.     cmp  BX,AX
  269.     jne  DecreaseOK
  270.     sub  BX,[ES:DI+TEditorGapLen]
  271. DecreaseOK:
  272.     dec  BX
  273.     pop  AX
  274.     ret
  275. ENDP
  276.  
  277.  
  278. ;-----------------------------------------------------
  279. ; compress buffer (DS:SI) by removing character at BX
  280. ; updates pointer CX and various object data elements
  281. ; in:  ES:DI = thisPtr
  282. ;      DS:SI = buffer
  283. ;      BX = pointer to character to remove
  284. ;      CX = pointer to update
  285. ; out: BX points to character after deleted character
  286. ;      CX updated if needed
  287. ;      all others unchanged
  288. ;-----------------------------------------------------
  289. PROC NOLANGUAGE CompressBuf NEAR
  290.  
  291.     push AX
  292.     push DX
  293.  
  294.     cmp  BX,[ES:DI+TEditorCurPtr]
  295.     jae  CompressAfter
  296.  
  297.     ;-------------------------
  298.     ; compress before the gap
  299.     ;-------------------------
  300.     push SI
  301.     push DI
  302.     push ES
  303.     push CX
  304.     mov  CX,[ES:DI+TEditorCurPtr] ;compute length to move
  305.     dec  CX
  306.     sub  CX,BX
  307.     add  SI,BX                    ;set source and destination
  308.     mov  DI,SI
  309.     inc  SI
  310.     push DS
  311.     pop  ES
  312.     rep  movsb                    ;shift the data
  313.     pop  CX
  314.     pop  ES
  315.     pop  DI
  316.     pop  SI
  317.  
  318.     ; convert BX and CX to data offsets
  319.     call DataOfs
  320.     xchg BX,CX
  321.     call DataOfs
  322.     xchg BX,CX
  323.     mov  DX,[ES:DI+TEditorBufLen]
  324.  
  325.     ; update object data elements
  326.     inc  [WORD PTR ES:DI+TEditorGapLen]
  327.     dec  [WORD PTR ES:DI+TEditorBufLen]
  328.     dec  [WORD PTR ES:DI+TEditorCurPtr]
  329.  
  330.     ; adjust insCount if needed
  331.     mov  AX,[ES:DI+TEditorCurPtr]
  332.     sub  AX,[ES:DI+TEditorInsCount]
  333.     cmp  AX,BX
  334.     sbb  [WORD PTR ES:DI+TEditorInsCount],0   ;dec InsCount if it does
  335.  
  336.     ; adjust pointers
  337.     mov  AX,-1                    ;adjustment amount
  338.     inc  BX                       ;low end to adjust (DX is high end)
  339.     call AdjustPointers           ;adjust pointers CX, SelStart, SelEnd
  340.     dec  BX
  341.  
  342.     ; convert BX & CX back into buffer offsets
  343.     call BufferOfs
  344.     xchg BX,CX
  345.     call BufferOfs
  346.     xchg BX,CX
  347.     jmp  CompressDone
  348.  
  349.     ;------------------------
  350.     ; compress after the gap
  351.     ;------------------------
  352. CompressAfter:
  353.     push SI
  354.     push DI
  355.     push ES
  356.     push CX
  357.     mov  AX,[ES:DI+TEditorCurPtr] ;get pointer to first deleted character
  358.     add  AX,[ES:DI+TEditorGapLen]
  359.     sub  AX,[ES:DI+TEditorDelCount]
  360.     mov  CX,BX                    ;compute length to move
  361.     sub  CX,AX
  362.     add  SI,BX                    ;set source and destination
  363.     mov  DI,SI
  364.     dec  SI
  365.     push DS
  366.     pop  ES
  367.     std                           ;move backward for this
  368.     rep  movsb                    ;shift the data
  369.     cld
  370.     pop  CX
  371.     pop  ES
  372.     pop  DI
  373.     pop  SI
  374.  
  375.     ; set data offsets of BX and CX pointers
  376.     call DataOfs
  377.     xchg BX,CX
  378.     call DataOfs
  379.     xchg BX,CX
  380.  
  381.     ; update object data elements
  382.     mov  AX,-1                    ;adjustment amount
  383.     mov  DX,[ES:DI+TEditorBufLen] ;high end to adjust
  384.     inc  BX                       ;low end to adjust
  385.     call AdjustPointers           ;adjust pointers CX, SelStart, SelEnd
  386.     dec  BX
  387.  
  388.     inc  [WORD PTR ES:DI+TEditorGapLen]
  389.     dec  [WORD PTR ES:DI+TEditorBufLen]
  390.  
  391.     ; change BX & CX back to buffer offsets
  392.     call BufferOfs
  393.     xchg BX,CX
  394.     call BufferOfs
  395.     xchg BX,CX
  396.  
  397. CompressDone:
  398.     pop  DX
  399.     pop  AX
  400.     ret
  401.  
  402. ENDP
  403.  
  404.  
  405. ;--------------------------------------------------------
  406. ; expand buffer (DS:SI) before character at pointer BX
  407. ; updates pointer CX and various object data elements
  408. ; in:  ES:DI = thisPtr
  409. ;      DS:SI = buffer
  410. ;      AX = original DS
  411. ;      BX = pointer to expand location
  412. ;      CX = pointer to update
  413. ; out: AX = 0 on failure
  414. ;      DS:SI = new buffer location
  415. ;      BX points to new character, but updated if needed
  416. ;      CX updated if needed
  417. ;      all others unchanged
  418. ;--------------------------------------------------------
  419. PROC NOLANGUAGE ExpandBuf NEAR
  420.  
  421.     push DX
  422.  
  423.     ;-------------------------------
  424.     ; check if buffer is big enough
  425.     ;-------------------------------
  426.     mov  DX,[ES:DI+TEditorGapLen]
  427.     cmp  DX,[ES:DI+TEditorDelCount]
  428.     ja   BufSizeOK
  429.     mov  DS,AX                    ;restore real DS for this function
  430.     call GrowBuffer               ;returns new buffer location in DS:SI
  431.     or   AX,AX                    ;check for failure
  432.     jz   ExpandDone               ;failure
  433.  
  434.     ;-----------------------------------------------
  435.     ; check if expansion is before or after the gap
  436.     ;-----------------------------------------------
  437. BufSizeOK:
  438.     cmp  BX,[ES:DI+TEditorCurPtr]
  439.     jae  ExpandAfter
  440.  
  441.     ;-----------------------
  442.     ; expand before the gap
  443.     ;-----------------------
  444.     push SI
  445.     push DI
  446.     push ES
  447.     push CX
  448.     mov  CX,[ES:DI+TEditorCurPtr]
  449.     add  SI,CX                    ;set source and destination
  450.     mov  DI,SI
  451.     dec  SI
  452.     push DS
  453.     pop  ES
  454.     sub  CX,BX                    ;compute length to move
  455.     std                           ;move backward for this
  456.     rep  movsb                    ;shift the data
  457.     cld
  458.     pop  CX
  459.     pop  ES
  460.     pop  DI
  461.     pop  SI
  462.  
  463.     ; convert BX and CX to data offsets
  464.     call DataOfs
  465.     xchg BX,CX
  466.     call DataOfs
  467.     xchg BX,CX
  468.     mov  DX,[ES:DI+TEditorBufLen]
  469.  
  470.     ; adjust insCount if needed
  471.     mov  AX,[ES:DI+TEditorCurPtr]
  472.     sub  AX,[ES:DI+TEditorInsCount]
  473.     cmp  AX,BX
  474.     adc  [WORD PTR ES:DI+TEditorInsCount],0   ;inc InsCount if it does
  475.  
  476.     dec  [WORD PTR ES:DI+TEditorGapLen]
  477.     inc  [WORD PTR ES:DI+TEditorBufLen]
  478.     inc  [WORD PTR ES:DI+TEditorCurPtr]
  479.  
  480.     ; adjust pointers
  481.     mov  AX,1                     ;adjustment amount
  482.     call AdjustPointers           ;adjust pointers CX, SelStart, SelEnd
  483.  
  484.     ; change BX & CX back to buffer offsets
  485.     call BufferOfs
  486.     xchg BX,CX
  487.     call BufferOfs
  488.     xchg BX,CX
  489.     jmp  ExpandDone               ;NOTE: AX still non-0 from above
  490.  
  491.     ;----------------------
  492.     ; expand after the gap
  493.     ;----------------------
  494. ExpandAfter:
  495.     push SI
  496.     push DI
  497.     push ES
  498.     push CX
  499.     mov  AX,[ES:DI+TEditorCurPtr] ;get ptr to char before 1st deleted char
  500.     add  AX,[ES:DI+TEditorGapLen]
  501.     sub  AX,[ES:DI+TEditorDelCount]
  502.     dec  AX
  503.     mov  CX,BX                    ;compute length to move
  504.     sub  CX,AX
  505.     add  SI,AX                    ;set source and destination
  506.     mov  DI,SI
  507.     inc  SI
  508.     push DS
  509.     pop  ES
  510.     rep  movsb                    ;shift the data
  511.     pop  CX
  512.     pop  ES
  513.     pop  DI
  514.     pop  SI
  515.  
  516.     ; convert BX and CX to data offsets
  517.     call DataOfs
  518.     xchg BX,CX
  519.     call DataOfs
  520.     xchg BX,CX
  521.     mov  DX,[ES:DI+TEditorBufLen]
  522.  
  523.     ; update object data elements
  524.     dec  [WORD PTR ES:DI+TEditorGapLen]
  525.     inc  [WORD PTR ES:DI+TEditorBufLen]
  526.  
  527.     ; adjust pointers
  528.     mov  AX,1                     ;adjustment amount
  529.     call AdjustPointers           ;adjust pointers CX, SelStart, SelEnd
  530.  
  531.     ; change BX & CX back to buffer offsets
  532.     call BufferOfs
  533.     xchg BX,CX
  534.     call BufferOfs
  535.     xchg BX,CX
  536.  
  537.     ;NOTE: AX still non-0 from above (success return value)
  538.  
  539. ExpandDone:
  540.     pop  DX
  541.     ret
  542.  
  543. ENDP
  544.  
  545.  
  546. ;----------------------------------------------------------------
  547. ; shift text in buffer (from BX+1 thru CX)
  548. ; in:  ES:DI = thisPtr
  549. ;      DS:SI = buffer
  550. ;      BX = pointer to location to overwrite
  551. ;      CX = pointer to ending location
  552. ; out: BX = updated but still points to start of affected area
  553. ;      CX = pointer to the hole
  554. ;      various object data members changed
  555. ;----------------------------------------------------------------
  556. PROC NOLANGUAGE ShiftBuf NEAR
  557.  
  558.     push AX
  559.     push DX
  560.  
  561.     mov  AX,[ES:DI+TEditorCurPtr]
  562.     cmp  BX,AX
  563.     jae  ShiftAfter               ;all shifting occurs after gap
  564.  
  565. ShiftBefore:
  566.     ;---------------------------
  567.     ; adjust InsCount if needed
  568.     ;---------------------------
  569.     mov  DX,AX                    ;compute start of inserted area
  570.     sub  DX,[ES:DI+TEditorInsCount]
  571.     cmp  BX,DX                    ;check if BX in inserted area
  572.     jb   @@NotBX
  573.     dec  [WORD PTR ES:DI+TEditorInsCount]
  574. @@NotBX:
  575.     cmp  CX,AX                    ;check if CX in inserted area
  576.     jae  @@NotCX
  577.     cmp  CX,DX
  578.     jb   @@NotCX
  579.     inc  [WORD PTR ES:DI+TEditorInsCount]
  580. @@NotCX:
  581.  
  582.     ;--------------------------
  583.     ; shift portion before gap
  584.     ;--------------------------
  585.     push CX                       ;save ending offset
  586.     cmp  CX,AX
  587.     jb   AllBefore
  588.     dec  AX
  589.     mov  [ES:DI+TEditorCurPtr],AX
  590.     mov  CX,AX                    ;fake ending offset for this part
  591.     inc  AX                       ;leave old value in AX
  592. AllBefore:
  593.     push ES
  594.     push SI
  595.     push DI
  596.     push CX
  597.     sub  CX,BX                    ;set move length
  598.     add  SI,BX                    ;set source and destination
  599.     mov  DI,SI
  600.     inc  SI
  601.     push DS
  602.     pop  ES
  603.     rep  movsb                    ;move the data
  604.     pop  CX
  605.     pop  DI
  606.     pop  SI
  607.     pop  ES
  608.  
  609.     pop  DX                       ;recover real ending pointer
  610.     cmp  CX,DX                    ;check if entire shift was before gap
  611.     je   ShiftAdj                 ;it was
  612.     mov  CX,DX                    ;was not, set real ending pointer
  613.  
  614.     ;-----------------------------
  615.     ; shift portion after the gap
  616.     ;-----------------------------
  617. ShiftAfter:
  618.     push BX                       ;save real starting offset
  619.     cmp  BX,AX                    ;AX still old value of CurPtr from above
  620.     jae  AllAfter
  621.     mov  BX,AX                    ;fake starting offset for this part
  622.     add  BX,[ES:DI+TEditorGapLen]
  623.     sub  BX,[ES:DI+TEditorDelCount]
  624.     dec  BX
  625. AllAfter:
  626.     push ES
  627.     push SI
  628.     push DI
  629.     push CX
  630.     sub  CX,BX                    ;set move length
  631.     add  SI,BX                    ;set source and destination
  632.     mov  DI,SI
  633.     inc  SI
  634.     push DS
  635.     pop  ES
  636.     rep  movsb                    ;move the data
  637.     pop  CX
  638.     pop  DI
  639.     pop  SI
  640.     pop  ES
  641.  
  642.     pop  BX                       ;recover real starting offset
  643.  
  644.     ;----------------------------------
  645.     ; adjust pointers to affected text
  646.     ;----------------------------------
  647. ShiftAdj:
  648.  
  649.     ; convert BX and CX to data offsets
  650.     call DataOfs
  651.     xchg BX,CX
  652.     call DataOfs
  653.     xchg BX,CX
  654.  
  655.     ; adjust pointers
  656.     mov  AX,-1                    ;adjustment amount
  657.     mov  DX,CX                    ;high end to adjust
  658.     inc  BX                       ;low end to adjust
  659.     call AdjustPointers
  660.     dec  BX
  661.  
  662.     ; change BX & CX back to buffer offsets
  663.     call BufferOfs
  664.     xchg BX,CX
  665.     call BufferOfs
  666.     xchg BX,CX
  667.  
  668.     pop  DX
  669.     pop  AX
  670.     ret
  671.  
  672. ENDP
  673.  
  674.  
  675. ;=========================================
  676. ; increase buffer size by at least 1 byte
  677. ; in:  DS = original DS (DATASEG)
  678. ;      BX,CX = buffer pointers
  679. ; out: AX = 0 on failure
  680. ;      BX,CX = updated
  681. ;      DS:SI = new buffer location
  682. ;=========================================
  683. PROC NOLANGUAGE GrowBuffer NEAR
  684.  
  685.     call DataOfs
  686.     xchg BX,CX
  687.     call DataOfs
  688.     xchg BX,CX
  689.  
  690.     push BX                       ;save our registers
  691.     push CX
  692.     push DX
  693.     push ES
  694.  
  695.     mov  AX,1                     ; changeBufSize(1)
  696.     push AX
  697.     push ES
  698.     push DI
  699.     call @TEditor@changeBufSize$qs
  700.     add  SP,6
  701.     cbw
  702.  
  703.     pop  ES                       ;restore our registers
  704.     pop  DX
  705.     pop  CX
  706.     pop  BX
  707.  
  708.     lds  SI,[ES:DI+TEditorBuffer] ;get new buffer pointer
  709.  
  710.     call BufferOfs
  711.     xchg BX,CX
  712.     call BufferOfs
  713.     xchg BX,CX
  714.  
  715.     ret                           ;AX = return value from changeBufSize()
  716. ENDP
  717.  
  718.  
  719. ;======================================
  720. ; convert buffer offset to data offset
  721. ; in:  BX = buffer offset
  722. ;      ES:DI = thisPtr
  723. ; out: BX = data offset
  724. ;======================================
  725. PROC NOLANGUAGE DataOfs NEAR
  726.     cmp  BX,[ES:DI+TEditorCurPtr]
  727.     jb   @@Exit
  728.     sub  BX,[ES:DI+TEditorGapLen]
  729. @@Exit:
  730.     ret
  731. ENDP
  732.  
  733.  
  734. ;======================================
  735. ; convert data offset to buffer offset
  736. ; in:  BX = data offset
  737. ;      ES:DI = thisPtr
  738. ; out: BX = buffer offset
  739. ;======================================
  740. PROC NOLANGUAGE BufferOfs NEAR
  741.     cmp  BX,[ES:DI+TEditorCurPtr]
  742.     jb   @@Exit
  743.     add  BX,[ES:DI+TEditorGapLen]
  744. @@Exit:
  745.     ret
  746. ENDP
  747.  
  748.  
  749. ;-----------------------------------------------------------------
  750. ; adjust pointers into edit buffer after text shift
  751. ; in:  ES:DI = thisPtr
  752. ;      AX = adjustment amount
  753. ;      BX, DX = endpoints of affected data (data offsets)
  754. ;      CX = pointer to adjust (in addition to SelStart & SelEnd)
  755. ; out: CX, SelStart & SelEnd updated
  756. ;      other regs unchanged
  757. ;-----------------------------------------------------------------
  758. PROC NOLANGUAGE AdjustPointers NEAR
  759.  
  760.     call AdjPtr                   ;fix pointer CX
  761.     push CX                       ;save it
  762.  
  763.     mov  CX,[ES:DI+TEditorSelStart]
  764.     call AdjPtr
  765.     mov  [ES:DI+TEditorSelStart],CX
  766.  
  767.     mov  CX,[ES:DI+TEditorSelEnd]
  768.     call AdjPtr
  769.     mov  [ES:DI+TEditorSelEnd],CX
  770.  
  771.     pop  CX                       ;recover pointer CX
  772.     ret
  773.  
  774. ; called to adjust pointer CX
  775. AdjPtr:
  776.     cmp  CX,BX
  777.     jb   AdjOk
  778.     cmp  CX,DX
  779.     ja   AdjOk
  780.     add  CX,AX                    ;in range, adjust it
  781. AdjOk:
  782.     ret
  783.  
  784. ENDP
  785.  
  786.  
  787. ENDP     ;doWordWrapBuffer
  788.  
  789.  
  790. END
  791.  
  792.