|
|
/************************************************************/ /* Windows Write, Copyright 1985-1992 Microsoft Corporation */ /************************************************************/
/* Select2.c -- Less-frequently-used selection routines */
#define NOCLIPBOARD
#define NOGDICAPMASKS
#define NOCTLMGR
#define NOVIRTUALKEYCODES
#define NOWINMESSAGES
#define NOWINSTYLES
#define NOSYSMETRICS
#define NOMENUS
#define NOSOUND
#define NOCOMM
#define NOPEN
#define NOWNDCLASS
#define NOICON
#define NORASTEROPS
#define NOSHOWWINDOW
#define NOATOM
#define NOKEYSTATE
#define NOSYSCOMMANDS
#define NOBITMAP
#define NOBRUSH
#define NOCOLOR
#define NODRAWTEXT
#define NOMB
#define NOPOINT
#define NOMSG
#include <windows.h>
#include "mw.h"
#include "toolbox.h"
#include "docdefs.h"
#include "editdefs.h"
#include "dispdefs.h"
#include "cmddefs.h"
#include "wwdefs.h"
#include "ch.h"
#include "fmtdefs.h"
#include "propdefs.h"
#ifdef DBCS
#include "kanji.h"
#endif
extern int vfSeeSel; extern typeCP vcpFirstParaCache; extern typeCP vcpLimParaCache; extern typeCP vcpFetch; extern CHAR *vpchFetch; extern int vccpFetch; extern typeCP cpMinCur; extern typeCP cpMacCur; extern struct SEL selCur; extern int docCur; extern struct FLI vfli; extern struct WWD rgwwd[]; extern int vfSelHidden; extern int wwCur; extern struct CHP vchpFetch; extern struct PAP vpapAbs; extern struct WWD *pwwdCur; extern int vfInsEnd; extern typeCP CpBeginLine(); extern int vfPictSel; extern int vfSizeMode; extern struct CHP vchpNormal; extern int vfInsertOn; extern struct CHP vchpSel; /* Holds the props when the selection
is an insert point */ extern int vfMakeInsEnd; extern typeCP vcpSelect; extern int vfSelAtPara; /* true iff the last selection was made by an Up/Down cursor key */ extern int vfLastCursor;
#ifndef DBCS /* US version */
/* C P L I M S T Y S P E C I A L */ typeCP CpLimStySpecial(cp, sty) typeCP cp; int sty; { /* Return the first cp which is not part of the same sty unit */ int wb, ch, ich; struct EDL *pedl;
/* Other cases covered in CpLimSty, our only caller */
Assert( cp < cpMacCur ); Assert( cp >= cpMinCur ); Assert( sty == styWord || sty == stySent );
/* Special kludge for picture paragraphs */ CachePara(docCur, cp); if (vpapAbs.fGraphics) return vcpLimParaCache;
FetchCp(docCur, cp, 0, fcmChars + fcmNoExpand);
Assert(vccpFetch != 0);
/* Must be word or sentence */ wb = WbFromCh(ch = vpchFetch[ich = 0]); #ifdef CRLF
if (ch == chReturn) return vcpFetch + 2; #endif
if (ch == chEol || ch == chSect || ch == chNewLine || ch == chTab) /* EOL is its own unit */ return vcpFetch + 1;
if (wb == wbWhite && sty == stySent) { /* Might be between sentences; go back to text */ FetchCp(docCur, CpFirstSty(cp, styWord), 0, fcmChars + fcmNoExpand); wb = WbFromCh(ch = vpchFetch[ich = 0]); }
for (;;) { if (++ich >= vccpFetch) { /* Get next line and set up */ FetchCp(docNil, cpNil, 0, fcmChars); if (vcpFetch == cpMacCur) return cpMacCur; /* End of doc */ ich = 0; } if (sty == stySent) switch (ch) { case chDot: case chBang: case chQMark: sty = styWord; wb = wbPunct; } switch (ch = vpchFetch[ich]) { case chTab: case chEol: case chSect: case chNewLine: #ifdef CRLF
case chReturn: #endif
goto BreakFor; } if (sty == styWord) { /* Word ends after white space or on text/punct break */ int wbT = WbFromCh(ch); if (wb != wbT && (wb = wbT) != wbWhite) break; } } BreakFor: return vcpFetch + ich; }
/* C P F I R S T S T Y S P E C I A L */ typeCP CpFirstStySpecial(cp, sty) typeCP cp; int sty; { /* Return the first cp of this sty unit. */ typeCP cpBegin; int wb, ch, dcpChunk; typeCP cpSent; CHAR rgch[dcpAvgSent]; int ich; typeCP cpT;
/* Other cases were covered by CpFirstSty, our only caller */
Assert( cp > cpMinCur ); Assert( sty == stySent || sty == styWord );
if (cp >= cpMacCur) cpT = cp = cpMacCur; else cpT = cp++;
CachePara(docCur, cpT ); if ((vcpFirstParaCache == cpT) || vpapAbs.fGraphics) return vcpFirstParaCache;
dcpChunk = (sty == styWord) ? dcpAvgWord : dcpAvgSent; cpBegin = (cp > dcpChunk) ? cp - dcpChunk : cp0;
FetchRgch(&ich, rgch, docCur, cpBegin, cp, dcpChunk); wb = WbFromCh(ch = rgch[--ich]);
#ifdef CRLF
if(cpBegin + ich == 0) return cp0;
if (ch == chEol && rgch[ich-1] == chReturn) /* EOL is its own unit */ return cpBegin + ich - 1; if (ch == chEol || ch == chReturn || ch == chSect || ch == chNewLine || ch == chTab) return cpBegin + ich; #else /* not CRLF */
if (ch == chEol || ch == chSect || ch == chNewLine || ch == chTab) /* EOL is its own unit */ return cpBegin + ich; #endif /* CRLF */
if (wb == wbText) cpSent = cpBegin + ich; else cpSent = cpNil;
for (;;) { if (ich == 0) { if (cpBegin == cpMinCur) return cpMinCur; /* beginning of doc */ cpBegin = (cpBegin > dcpChunk) ? cpBegin - dcpChunk : cp0; FetchRgch(&ich, rgch, docCur, cpBegin, cp, dcpChunk); } ch = rgch[--ich]; CachePara( docCur, cpBegin + ich ); /* Needed for pictures */ if (ch == chEol || ch == chSect || ch == chNewLine || ch == chTab || vpapAbs.fGraphics ) break; /* EOL Always ends a unit */ if (sty == styWord) { if (wb != wbWhite) { if (WbFromCh(ch) != wb) break; } else wb = WbFromCh(ch); } else { /* Test for sentence. */ switch (ch) { case chDot: case chBang: case chQMark: if (cpSent != cpNil) return cpSent; } switch (WbFromCh(ch)) { case wbText: cpSent = cpBegin + ich; wb = wbText; break; case wbPunct: switch (wb) { case wbWhite: wb = wbPunct; break; case wbText: cpSent = cpBegin + ich; } break; case wbWhite: if (wb == wbPunct) cpSent = cpBegin + ich + 1; wb = wbWhite; break; } } } return cpBegin + ich + 1; }
#else /* DBCS version */
typeCP CpLimStySpecial(cp, sty) typeCP cp; int sty; { CHAR rgch[cchKanji]; int ch, ch2; int ich, wb; typeCP cpLim, cpT;
/* Other cases covered in CpLimSty, our only caller */ Assert(cp < cpMacCur); Assert(cp >= cpMinCur); Assert(sty == styWord || sty == stySent);
/* Picture paragraph? */ CachePara(docCur, cp); if (vpapAbs.fGraphics) { return vcpLimParaCache; }
cpLim = vcpLimParaCache; if (vcpLimParaCache > cpMacCur) { /* No EOL at end of doc */ cpLim = cpMacCur; }
FetchRgch(&ich, rgch, docCur, cp, ((cpT = cp + cchKanji) < cpLim) ? cpT : cpLim, cchKanji); ch = rgch[0]; #ifdef CRLF
if (ch == chReturn) { return (cp + 2); } #endif /* CRLF */
if (ch == chEol || ch == chSect || ch == chNewLine || ch == chTab) { /* EOL is its own unit. */ return (cp + 1); } #ifdef KOREA
wb=WbFromCh(ch); #else
if (FKanji1(ch)) { wb = WbFromKanjiChCh(ch, (int) rgch[1]); if (sty == styWord && wb == wbKanjiText) { return (CpLimSty(cp, styChar)); } else { if (wb == wbKanjiText) { wb = wbKanjiTextFirst; } } } else { if (sty == styWord && FKanaText(ch)) { return (CpLimSty(cp, styChar)); } wb = WbFromCh(ch); } #endif
for (; cp < cpLim;) { int wbT;
if (sty == stySent) { if (FKanji1(ch)) { CHAR ch2;
ch2 = rgch[1]; if (FKanjiKuten(ch, ch2) || FKanjiQMark(ch, ch2) || FKanjiBang(ch, ch2) || FKanjiPeriod(ch, ch2)) { sty = styWord; wb = wbPunct; goto lblNextFetch; } } else { switch (ch) { #ifndef KOREA
case bKanjiKuten: #endif
case chDot: case chBang: case chQMark: sty = styWord; wb = wbPunct; goto lblNextFetch; } } }
switch (ch) { case chTab: case chEol: case chSect: case chNewLine: #ifdef CRLF
case chReturn: #endif /* CRLF */
return cp; }
if (sty == styWord) { #ifdef KOREA
wbT = WbFromCh(ch); #else
if (FKanji1(ch)) { wbT = WbFromKanjiChCh(ch, (int) rgch[1]); } else { wbT = WbFromCh(ch); } #endif
if (wb != wbT && (wb = wbT) != wbWhite) { return (cp); } }
lblNextFetch: cp = CpLimSty(cp, styChar); if (cp < cpLim) { /* Save some time and an untimely demise.... */ FetchRgch(&ich, rgch, docCur, cp, ((cpT = cp + cchKanji) < cpLim) ? cpT : cpLim, cchKanji); ch = rgch[0]; } } return (cpLim); }
typeCP CpFirstStySpecial(cp, sty) typeCP cp; int sty; { /* Return the first cp of this sty unit. */ typeCP cpT, cpLim, cpFirstPara, cpFirstLastSent; /* cpFirst of the last possible sentence boundary */ CHAR rgch[cchKanji]; int ch; int wb; int ich;
/* Other cases were covered by CpFirstSty, our only caller */
Assert( cp > cpMinCur ); Assert(CpFirstSty(cp, styChar) == cp); /* cp is on a char boundary */ Assert( sty == stySent || sty == styWord );
cpT = cp; if (cp >= cpMacCur) { cpT = cp = cpMacCur; }
CachePara(docCur, cpT ); cpFirstPara = vcpFirstParaCache; if ((vcpFirstParaCache == cpT) || vpapAbs.fGraphics) { return vcpFirstParaCache; }
#ifdef CRLF
/* CR-LF is assumed. */ Assert(TRUE); #else
Assert(FALSE); #endif /* CRLF */
FetchRgch(&ich, rgch, docCur, cp, ((cpT = cp + cchKanji) < cpMacCur) ? cpT : cpMacCur, cchKanji); ch = rgch[0]; if (ich == cchKanji && ch == chReturn && rgch[1] == chEol) { /* EOL is its own unit */ return cp; } if (ch == chEol || ch == chReturn || ch == chSect || ch == chNewLine || ch == chTab) { return cp; }
cpFirstLastSent = cpNil;
#ifdef KOREA
wb = WbFromCh(ch); #else
if (FKanji1(ch)) { wb = WbFromKanjiChCh(ch, (int) rgch[1]); if (sty == styWord && wb == wbKanjiText) { return (CpFirstSty(cp, styChar)); } else { if (wb == wbKanjiText) { wb = wbKanjiTextFirst; } } } else { if (sty == styWord && FKanaText(ch)) { return (CpFirstSty(cp, styChar)); } wb = WbFromCh(ch); } #endif
for (; cpFirstPara < cp; ) { typeCP cpTemp; int wbT;
cpTemp = CpFirstSty(cp - 1, styChar); FetchRgch(&ich, rgch, docCur, cpTemp, ((cpT = cpTemp + cchKanji) < cpMacCur) ? cpT : cpMacCur, cchKanji); ch = rgch[0]; #ifdef KOREA
wbT = WbFromCh(ch); #else
if (FKanji1(ch)) { wbT = WbFromKanjiChCh(ch, (int) rgch[1]); } else { wbT = WbFromCh(ch); } #endif
if (wb == wbWhite) { #ifdef KOREA
wb=wbT; #else
wb = (wbT == wbKanjiText) ? wbKanjiTextFirst : wbT; #endif
} else if (wb != wbT) { if (sty == styWord) { return (cp); } else /* sty == stySent */ { /* wb != wbWhite */ /* wb != wbT */ if (wbT == wbWhite || wbT == wbPunct) { cpFirstLastSent = cp; wb = wbWhite; } } }
if (sty == stySent) { /* for the sentence */ if (FKanji1(ch)) { int ch2; ch2 = rgch[1]; if (FKanjiKuten(ch, ch2) || FKanjiQMark(ch, ch2) || FKanjiBang(ch, ch2) || FKanjiPeriod(ch, ch2)) { if (cpFirstLastSent != cpNil) { return (cpFirstLastSent); } else { cpFirstLastSent = cp; } } } else { switch(ch) { #ifndef KOREA
case bKanjiKuten: #endif
case chDot: case chBang: case chQMark: if (cpFirstLastSent != cpNil) { return (cpFirstLastSent); } else { cpFirstLastSent = cp; } } }
}
cp = cpTemp; } return (cpFirstPara); } #endif /* DBCS */
/* W B F R O M C H */ int WbFromCh(ch) int ch; { /* Return word-breakness of ch */
#if defined(DBCS) & !defined(KOREA) /* was in JAPAN; KenjiK '90-10-29 */
/* Brought from WIN2 source. */ if (FKanaPunct(ch)) { return wbPunct; } else if (FKanaText(ch)) { return wbKanjiText; } #endif
switch (ch) { case chSpace: case chEol: #ifdef CRLF
case chReturn: #endif
case chSect: case chTab: case chNewLine: case chNBSFile: return wbWhite; case chNRHFile: return wbText; default: /* we are using the ANSI char set that windows used */ #ifdef KOREA
return ((isalpha(ch) || isdigit(ch) || ((ch>0x81)&&(ch<0xfe)))? wbText : wbPunct); #else
return ((isalpha(ch) || isdigit(ch))? wbText : wbPunct); #endif
} }
#ifdef DBCS /* was in JAPAN; KenjiK '90-10-29 */
/* Brought from WIN2 source. */ int WbFromKanjiChCh(ch1, ch2) int ch1, ch2; { if (ch1 == chReturn && ch2 == chEol) { return wbWhite; } else if (FKanjiSpace(ch1, ch2)) { return wbWhite; } else
#ifdef JAPAN
{ switch (ch1) { case 0x81: if (0x57 <= ch2 && ch2 <= 0x59) { return wbKanjiText; } else { return wbPunct; } case 0x85: if ((0x40 <= ch2 && ch2 <= 0x4E) || (0x59 <= ch2 && ch2 <= 0x5F) || (0x7A <= ch2 && ch2 <= 0x7E) || (0x9B <= ch2 && ch2 <= 0xA3) || (0xDC <= ch2 && ch2 <= 0xDD)) { return wbPunct; } else { return wbKanjiText; } case 0x86: return wbPunct; case 0x87: return ((ch2 >= 0x90) ? wbPunct : wbKanjiText); default: return wbKanjiText; } } #endif
#ifdef KOREA
{ switch (ch1) { case 0xa2: if (0xde <= ch2 && ch2 <= 0xe5) { return wbText; // wbKanjiText; MSCH bklee 01/26/95
} else { return wbPunct; } case 0xa3: if ((0xa1 <= ch2 && ch2 <= 0xaf) || (0xba <= ch2 && ch2 <= 0xc0) || (0xdb <= ch2 && ch2 <= 0xe0) || (0xfb <= ch2 && ch2 <= 0xfe)) { return wbPunct; } else { return wbText; //wbKanjiText; MSCH bklee 01/26/95
} default: return wbText; //wbKanjiText; MSCH bklee 01/26/95
} } #endif
#ifdef PRC // brucere 11/16/95
{ switch (ch1) { case 0xA1: return wbPunct;
case 0xA3: if ((0xA1 <= ch2 && ch2 <= 0xAF) || (0xBA <= ch2 && ch2 <= 0xC0) || (0xDB <= ch2 && ch2 <= 0xE0) || (0xFB <= ch2 && ch2 <= 0xFE)) return wbPunct; else return wbKanjiText;
case 0xA4: if (ch2 == 0x92) return wbPunct; else return wbKanjiText;
default: return wbKanjiText; } } #elif TAIWAN
{ switch (ch1) { case 0xA1: if (0x41 <= ch2 && ch2 <= 0xAC) return wbPunct; else return wbKanjiText;
default: return wbKanjiText; } } #endif
} #endif
|