/* Copyright (c) Microsoft Corporation. Licensed under the MIT License. */ /* Copyright (c) Microsoft Corporation. Licensed under the MIT License. */ /*************************************************************************** Author: ShonK Project: Kauai Reviewed: Copyright (c) Microsoft Corporation Rich text document and supporting views. ***************************************************************************/ #ifndef RTXT_H #define RTXT_H /*************************************************************************** Character properties - if you change this, make sure to update FetchChp and _TGetLwFromChp. ***************************************************************************/ struct CHP { ulong grfont; // bold, italic, etc long onn; // which font long dypFont; // size of the font long dypOffset; // sub/superscript (-128 to 127) ACR acrFore; // text color ACR acrBack; // background color void Clear(void) { ClearPb(this, offset(CHP, acrFore)); acrFore = kacrBlack; acrBack = kacrBlack; } }; typedef CHP *PCHP; /*************************************************************************** Paragraph properties - if you change these, make sure to update FetchPap and _TGetLwFromPap. The dypExtraLine and numLine fields are used to change the height of lines from their default. The line height used is calculated as (numLine / 256) * dyp + dypExtraLine, where dyp is the natural height of the line. ***************************************************************************/ enum { jcMin, jcLeft = jcMin, jcRight, jcCenter, jcLim }; enum { ndMin, ndNone = ndMin, ndFirst, //just on the left ndRest, //just on the left ndAll, //on both sides ndLim }; struct PAP { byte jc; byte nd; short dxpTab; short numLine; short dypExtraLine; short numAfter; short dypExtraAfter; }; typedef PAP *PPAP; const short kdenLine = 256; const short kdenAfter = 256; const short kdxpTabDef = (kdzpInch / 4); const short kdxpDocDef = (kdzpInch * 6); const achar kchObject = 1; /*************************************************************************** Generic text document base class ***************************************************************************/ const long kcchMaxTxtbCache = 512; typedef class TXTB *PTXTB; #define TXTB_PAR DOCB #define kclsTXTB 'TXTB' class TXTB : public TXTB_PAR { RTCLASS_DEC ASSERT MARKMEM protected: PFIL _pfil; PBSF _pbsf; ACR _acrBack; long _dxpDef; //default width of the document long _cpMinCache; long _cpLimCache; achar _rgchCache[kcchMaxTxtbCache]; long _cactSuspendUndo; // > 0 means don't set up undo records. long _cactCombineUndo; // determines whether we can combine undo records. TXTB(PDOCB pdocb = pvNil, ulong grfdoc = fdocNil); ~TXTB(void); virtual bool _FInit(PFNI pfni = pvNil, PBSF pbsf = pvNil, short osk = koskCur); virtual bool _FLoad(short osk = koskCur); virtual achar _ChFetch(long cp); virtual void _CacheRange(long cpMin, long cpLim); virtual void _InvalCache(long cp, long ccpIns, long ccpDel); public: virtual void InvalAllDdg(long cp, long ccpIns, long ccpDel, ulong grfdoc = fdocUpdate); // REVIEW shonk: this is needed for using a text document as input to a lexer. // The bsf returned is read-only!!!! PBSF Pbsf(void) { AssertThis(0); return _pbsf; } long CpMac(void); bool FMinPara(long cp); long CpMinPara(long cp); long CpLimPara(long cp); long CpPrev(long cp, bool fWord = fFalse); long CpNext(long cp, bool fWord = fFalse); ACR AcrBack(void) { return _acrBack; } void SetAcrBack(ACR acr, ulong grfdoc = fdocUpdate); long DxpDef(void) { return _dxpDef; } virtual void SetDxpDef(long dxp); virtual void FetchRgch(long cp, long ccp, achar *prgch); virtual bool FReplaceRgch(void *prgch, long ccpIns, long cp, long ccpDel, ulong grfdoc = fdocUpdate); virtual bool FReplaceFlo(PFLO pflo, bool fCopy, long cp, long ccpDel, short osk = koskCur, ulong grfdoc = fdocUpdate); virtual bool FReplaceBsf(PBSF pbsfSrc, long cpSrc, long ccpSrc, long cpDst, long ccpDel, ulong grfdoc = fdocUpdate); virtual bool FReplaceTxtb(PTXTB ptxtbSrc, long cpSrc, long ccpSrc, long cpDst, long ccpDel, ulong grfdoc = fdocUpdate); virtual bool FGetObjectRc(long cp, PGNV pgnv, PCHP pchp, RC *prc); virtual bool FDrawObject(long cp, PGNV pgnv, long *pxp, long yp, PCHP pchp, RC *prcClip); virtual bool FGetFni(FNI *pfni); virtual void HideSel(void); virtual void SetSel(long cp1, long cp2, long gin = kginDraw); virtual void ShowSel(void); virtual void SuspendUndo(void); virtual void ResumeUndo(void); virtual bool FSetUndo(long cp1, long cp2, long ccpIns); virtual void CancelUndo(void); virtual void CommitUndo(void); virtual void BumpCombineUndo(void); virtual bool FFind(achar *prgch, long cch, long cpStart, long *pcpMin, long *pcpLim, bool fCaseSensitive = fFalse); virtual void ExportFormats(PCLIP pclip); }; /*************************************************************************** Plain text document class ***************************************************************************/ typedef class TXPD *PTXPD; #define TXPD_PAR TXTB #define kclsTXPD 'TXPD' class TXPD : public TXPD_PAR { RTCLASS_DEC protected: TXPD(PDOCB pdocb = pvNil, ulong grfdoc = fdocNil); public: static PTXPD PtxpdNew(PFNI pfni = pvNil, PBSF pbsf = pvNil, short osk = koskCur, PDOCB pdocb = pvNil, ulong grfdoc = fdocNil); virtual PDDG PddgNew(PGCB pgcb); virtual bool FSaveToFni(FNI *pfni, bool fSetFni); }; /*************************************************************************** Rich text document class. ***************************************************************************/ const long kcpMaxTxrd = 0x00800000; // 8MB typedef class RTUN *PRTUN; typedef class TXRD *PTXRD; #define TXRD_PAR TXTB #define kclsTXRD 'TXRD' class TXRD : public TXRD_PAR { RTCLASS_DEC ASSERT MARKMEM protected: // WARNING: changing these values affects the file format // NOTE: Originally, _FSprmInAg was a virtual TXRD method called to // determine if a sprm stored its value in the AG. This didn't work // well when a subclass had a sprm in an AG (it broke undo for that // sprm). To fix this I (shonk) made _FSprmInAg static and made it // know exactly which sprms use the AG. For sprms in the client range // or above sprmMinObj, odd ones are _not_ in the AG and even ones _are_ // in the AG. I couldn't just use the odd/even rule throughout the // range, because that would have required changing values of old // sprms, which would have broken existing rich text documents. enum { sprmNil = 0, // character properties sprmMinChp = 1, sprmStyle = 1, //bold, italic, etc, font size, dypOffset sprmFont = 2, //font - in the AG sprmForeColor = 3, //foreground color sprmBackColor = 4, //background color sprmLimChp, // client character properties start at 64 sprmMinChpClient = 64, //for subclassed character properties // paragraph properties sprmMinPap = 128, sprmHorz = 128, //justification, indenting and dxpTab sprmVert = 129, //numLine and dypExtraLine sprmAfter = 130, //numAfter and dypExtraAfter sprmLimPap, // client paragraph properties sprmMinPapClient = 160, //for subclassed paragraph properties // objects - these apply to a single character, not a range sprmMinObj = 192, sprmObject = 192, }; //map property entry struct MPE { ulong spcp; //sprm in the high byte and cp in the low 3 bytes long lw; //the associated value - meaning depends on the sprm, //but 0 is _always_ the default }; //sprm, value, mask triple struct SPVM { byte sprm; long lw; long lwMask; }; //rich text document properties struct RDOP { short bo; short oskFont; long dxpDef; long dypFont; long lwAcrBack; // byte rgbStnFont[]; font name }; #define kbomRdop 0x5FC00000 PCFL _pcfl; PGL _pglmpe; PAG _pagcact; //for sprm's that have more than a long's worth of data long _onnDef; //default font and font size long _dypFontDef; short _oskFont; //osk for the default font STN _stnFontDef; //name of default font //cached CHP and PAP (from FetchChp and FetchPap) CHP _chp; long _cpMinChp, _cpLimChp; PAP _pap; long _cpMinPap, _cpLimPap; // current undo record PRTUN _prtun; TXRD(PDOCB pdocb = pvNil, ulong grfdoc = fdocNil); ~TXRD(void); bool _FInit(PFNI pfni = pvNil, CTG ctg = kctgRichText); virtual bool _FReadChunk(PCFL pcfl, CTG ctg, CNO cno, bool fCopyText); virtual bool _FOpenArg(long icact, byte sprm, short bo, short osk); ulong _SpcpFromSprmCp(byte sprm, long cp) { return ((ulong)sprm << 24) | (cp & 0x00FFFFFF); } byte _SprmFromSpcp(ulong spcp) { return B3Lw(spcp); } long _CpFromSpcp(ulong spcp) { return (long)(spcp & 0x00FFFFFF); } bool _FFindMpe(ulong spcp, MPE *pmpe, long *pcpLim = pvNil, long *pimpe = pvNil); bool _FFetchProp(long impe, byte *psprm, long *plw = pvNil, long *pcpMin = pvNil, long *pcpLim = pvNil); bool _FEnsureInAg(byte sprm, void *pv, long cb, long *pjv); void _ReleaseInAg(long jv); void _AddRefInAg(long jv); void _ReleaseSprmLw(byte sprm, long lw); void _AddRefSprmLw(byte sprm, long lw); bool _TGetLwFromChp(byte sprm, PCHP pchpNew, PCHP pchpOld, long *plw, long *plwMask); bool _TGetLwFromPap(byte sprm, PPAP ppapNew, PPAP ppapOld, long *plw, long *plwMask); bool _FGetRgspvmFromChp(PCHP pchp, PCHP pchpDiff, SPVM *prgspvm, long *pcspvm); bool _FGetRgspvmFromPap(PPAP ppap, PPAP ppapDiff, SPVM *prgspvm, long *pcspvm); void _ReleaseRgspvm(SPVM *prgspvm, long cspvm); void _ApplyRgspvm(long cp, long ccp, SPVM *prgspvm, long cspvm); void _GetParaBounds(long *pcpMin, long *pccp, bool fExpand); void _AdjustMpe(long cp, long ccpIns, long ccpDel); void _CopyProps(PTXRD ptxrd, long cpSrc, long cpDst, long ccpSrc, long ccpDst, byte sprmMin, byte sprmLim); virtual bool _FGetObjectRc(long icact, byte sprm, PGNV pgnv, PCHP pchp, RC *prc); virtual bool _FDrawObject(long icact, byte sprm, PGNV pgnv, long *pxp, long yp, PCHP pchp, RC *prcClip); bool _FReplaceCore(void *prgch, PFLO pflo, bool fCopy, PBSF pbsf, long cpSrc, long ccpIns, long cp, long ccpDel, PCHP pchp, PPAP ppap, ulong grfdoc); static bool _FSprmInAg(byte sprm); public: static PTXRD PtxrdNew(PFNI pfni = pvNil); static PTXRD PtxrdReadChunk(PCFL pcfl, CTG ctg, CNO cno, bool fCopyText = fTrue); virtual PDDG PddgNew(PGCB pgcb); void FetchChp(long cp, PCHP pchp, long *pcpMin = pvNil, long *pcpLim = pvNil); void FetchPap(long cp, PPAP ppap, long *pcpMin = pvNil, long *pcpLim = pvNil); bool FApplyChp(long cp, long ccp, PCHP pchp, PCHP pchpDiff = pvNil, ulong grfdoc = fdocUpdate); bool FApplyPap(long cp, long ccp, PPAP ppap, PPAP ppapDiff, long *pcpMin = pvNil, long *pcpLim = pvNil, bool fExpand = fTrue, ulong grfdoc = fdocUpdate); virtual bool FReplaceRgch(void *prgch, long ccpIns, long cp, long ccpDel, ulong grfdoc = fdocUpdate); virtual bool FReplaceFlo(PFLO pflo, bool fCopy, long cp, long ccpDel, short osk = koskCur, ulong grfdoc = fdocUpdate); virtual bool FReplaceBsf(PBSF pbsfSrc, long cpSrc, long ccpSrc, long cpDst, long ccpDel, ulong grfdoc = fdocUpdate); virtual bool FReplaceTxtb(PTXTB ptxtbSrc, long cpSrc, long ccpSrc, long cpDst, long ccpDel, ulong grfdoc = fdocUpdate); bool FReplaceRgch(void *prgch, long ccpIns, long cp, long ccpDel, PCHP pchp, PPAP ppap = pvNil, ulong grfdoc = fdocUpdate); bool FReplaceFlo(PFLO pflo, bool fCopy, long cp, long ccpDel, PCHP pchp, PPAP ppap = pvNil, short osk = koskCur, ulong grfdoc = fdocUpdate); bool FReplaceBsf(PBSF pbsfSrc, long cpSrc, long ccpSrc, long cpDst, long ccpDel, PCHP pchp, PPAP ppap = pvNil, ulong grfdoc = fdocUpdate); bool FReplaceTxtb(PTXTB ptxtbSrc, long cpSrc, long ccpSrc, long cpDst, long ccpDel, PCHP pchp, PPAP ppap = pvNil, ulong grfdoc = fdocUpdate); bool FReplaceTxrd(PTXRD ptxrd, long cpSrc, long ccpSrc, long cpDst, long ccpDel, ulong grfdoc = fdocUpdate); bool FFetchObject(long cpMin, long *pcp, void **ppv = pvNil, long *pcb = pvNil); virtual bool FInsertObject(void *pv, long cb, long cp, long ccpDel, PCHP pchp = pvNil, ulong grfdoc = fdocUpdate); virtual bool FApplyObjectProps(void *pv, long cb, long cp, ulong grfdoc = fdocUpdate); virtual bool FGetObjectRc(long cp, PGNV pgnv, PCHP pchp, RC *prc); virtual bool FDrawObject(long cp, PGNV pgnv, long *pxp, long yp, PCHP pchp, RC *prcClip); virtual bool FGetFni(FNI *pfni); virtual bool FGetFniSave(FNI *pfni); virtual bool FSaveToFni(FNI *pfni, bool fSetFni); virtual bool FSaveToChunk(PCFL pcfl, CKI *pcki, bool fRedirectText = fFalse); virtual bool FSetUndo(long cp1, long cp2, long ccpIns); virtual void CancelUndo(void); virtual void CommitUndo(void); }; /*************************************************************************** Rich text undo object. ***************************************************************************/ typedef class RTUN *PRTUN; #define RTUN_PAR UNDB #define kclsRTUN 'RTUN' class RTUN : public RTUN_PAR { RTCLASS_DEC ASSERT MARKMEM protected: long _cactCombine; // RTUNs with different values can't be combined PTXRD _ptxrd; // copy of replaced text long _cpMin; // where the text came from in the original RTXD long _ccpIns; // how many characters the original text was replaced with public: static PRTUN PrtunNew(long cactCombine, PTXRD ptxrd, long cp1, long cp2, long ccpIns); ~RTUN(void); virtual bool FUndo(PDOCB pdocb); virtual bool FDo(PDOCB pdocb); bool FCombine(PRTUN prtun); }; /*************************************************************************** Text document display GOB - DDG for a TXTB. ***************************************************************************/ const long kdxpIndentTxtg = (kdzpInch / 8); const long kcchMaxLineTxtg = 512; typedef class TRUL *PTRUL; enum { ftxtgNil = 0, ftxtgNoColor = 1, }; typedef class TXTG *PTXTG; #define TXTG_PAR DDG #define kclsTXTG 'TXTG' class TXTG : public TXTG_PAR { RTCLASS_DEC ASSERT MARKMEM protected: //line information struct LIN { long cpMin; // the cp of the first character in this line long dypTot; // the total height of lines up to this line short ccp; short xpLeft; short dyp; short dypAscent; }; PTXTB _ptxtb; PGL _pgllin; long _ilinDisp; long _cpDisp; long _dypDisp; long _ilinInval; // LINs from here on have wrong cpMin and dypTot values PGNV _pgnv; //the selection long _cpAnchor; long _cpOther; ulong _tsSel; long _xpSel; bool _fSelOn: 1; bool _fXpValid: 1; bool _fMark: 1; bool _fClear: 1; bool _fSelByWord: 1; //the ruler PTRUL _ptrul; TXTG(PTXTB ptxtb, PGCB pgcb); ~TXTG(void); virtual bool _FInit(void); virtual void _Activate(bool fActive); virtual long _DxpDoc(void); virtual void _FetchChp(long cp, PCHP pchp, long *pcpMin = pvNil, long *pcpLim = pvNil) = 0; virtual void _FetchPap(long cp, PPAP ppap, long *pcpMin = pvNil, long *pcpLim = pvNil) = 0; void _CalcLine(long cpMin, long dyp, LIN *plin); void _Reformat(long cp, long ccpIns, long ccpDel, long *pyp = pvNil, long *pdypIns = pvNil, long *pdypDel = pvNil); void _ReformatAndDraw(long cp, long ccpIns, long ccpDel); void _FetchLin(long ilin, LIN *plin, long *pilinActual = pvNil); void _FindCp(long cpFind, LIN *plin, long *pilin = pvNil, bool fCalcLines = fTrue); void _FindDyp(long dypFind, LIN *plin, long *pilin = pvNil, bool fCalcLines = fTrue); bool _FGetCpFromPt(long xp, long yp, long *pcp, bool fClosest = fTrue); bool _FGetCpFromXp(long xp, LIN *plin, long *pcp, bool fClosest = fTrue); void _GetXpYpFromCp(long cp, long *pypMin, long *pypLim, long *pxp, long *pdypBaseLine = pvNil, bool fView = fTrue); long _DxpFromCp(long cpLine, long cp); void _SwitchSel(bool fOn, long gin = kginDraw); void _InvertSel(PGNV pgnv, long gin = kginDraw); void _InvertCpRange(PGNV pgnv, long cp1, long cp2, long gin = kginDraw); virtual long _ScvMax(bool fVert); virtual void _Scroll(long scaHorz, long scaVert, long scvHorz = 0, long scvVert = 0); virtual void _ScrollDxpDyp(long dxp, long dyp); virtual long _DypTrul(void); virtual PTRUL _PtrulNew(PGCB pgcb); virtual void _DrawLinExtra(PGNV pgnv, RC *prcClip, LIN *plin, long dxp, long yp, ulong grftxtg); public: virtual void DrawLines(PGNV pgnv, RC *prcClip, long dxp, long dyp, long ilinMin, long ilinLim = klwMax, ulong grftxtg = ftxtgNil); virtual void Draw(PGNV pgnv, RC *prcClip); virtual bool FCmdTrackMouse(PCMD_MOUSE pcmd); virtual bool FCmdKey(PCMD_KEY pcmd); virtual bool FCmdSelIdle(PCMD pcmd); virtual void InvalCp(long cp, long ccpIns, long ccpDel); virtual void HideSel(void); virtual void GetSel(long *pcpAnchor, long *pcpOther); virtual void SetSel(long cpAnchor, long cpOther, long gin = kginDraw); virtual bool FReplace(achar *prgch, long cch, long cp1, long cp2); void ShowSel(void); PTXTB Ptxtb(void) { return _ptxtb; } virtual void ShowRuler(bool fShow = fTrue); virtual void SetDxpTab(long dxp); virtual void SetDxpDoc(long dxp); virtual void GetNaturalSize(long *pdxp, long *pdyp); }; /*************************************************************************** Line text document display gob ***************************************************************************/ typedef class TXLG *PTXLG; #define TXLG_PAR TXTG #define kclsTXLG 'TXLG' class TXLG : public TXLG_PAR { RTCLASS_DEC protected: //the font long _onn; ulong _grfont; long _dypFont; long _dxpChar; long _cchTab; TXLG(PTXTB ptxtb, PGCB pgcb, long onn, ulong grfont, long dypFont, long cchTab); virtual long _DxpDoc(void); virtual void _FetchChp(long cp, PCHP pchp, long *pcpMin = pvNil, long *pcpLim = pvNil); virtual void _FetchPap(long cp, PPAP ppap, long *pcpMin = pvNil, long *pcpLim = pvNil); //clipboard support virtual bool _FCopySel(PDOCB *ppdocb = pvNil); virtual void _ClearSel(void); virtual bool _FPaste(PCLIP pclip, bool fDoIt, long cid); public: static PTXLG PtxlgNew(PTXTB ptxtb, PGCB pgcb, long onn, ulong grfont, long dypFont, long cchTab); virtual void SetDxpTab(long dxp); virtual void SetDxpDoc(long dxp); }; /*************************************************************************** Rich text document display gob ***************************************************************************/ typedef class TXRG *PTXRG; #define TXRG_PAR TXTG #define kclsTXRG 'TXRG' class TXRG : public TXRG_PAR { RTCLASS_DEC CMD_MAP_DEC(TXRG) ASSERT protected: TXRG(PTXRD ptxrd, PGCB pgcb); CHP _chpIns; bool _fValidChp; virtual void _FetchChp(long cp, PCHP pchp, long *pcpMin = pvNil, long *pcpLim = pvNil); virtual void _FetchPap(long cp, PPAP ppap, long *pcpMin = pvNil, long *pcpLim = pvNil); virtual bool _FGetOtherSize(long *pdypFont); virtual bool _FGetOtherSubSuper(long *pdypOffset); //clipboard support virtual bool _FCopySel(PDOCB *ppdocb = pvNil); virtual void _ClearSel(void); virtual bool _FPaste(PCLIP pclip, bool fDoIt, long cid); void _FetchChpSel(long cp1, long cp2, PCHP pchp); void _EnsureChpIns(void); public: static PTXRG PtxrgNew(PTXRD ptxrd, PGCB pgcb); virtual void SetSel(long cpAnchor, long cpOther, long gin = kginDraw); virtual bool FReplace(achar *prgch, long cch, long cp1, long cp2); virtual bool FApplyChp(PCHP pchp, PCHP pchpDiff = pvNil); virtual bool FApplyPap(PPAP ppap, PPAP ppapDiff = pvNil, bool fExpand = fTrue); virtual bool FCmdApplyProperty(PCMD pcmd); virtual bool FEnablePropCmd(PCMD pcmd, ulong *pgrfeds); bool FSetColor(ACR *pacrFore, ACR *pacrBack); virtual void SetDxpTab(long dxp); }; /*************************************************************************** The ruler for a rich text document. ***************************************************************************/ typedef class TRUL *PTRUL; #define TRUL_PAR GOB #define kclsTRUL 'TRUL' class TRUL : public TRUL_PAR { RTCLASS_DEC protected: TRUL(GCB *pgcb) : TRUL_PAR(pgcb) {} public: virtual void SetDxpTab(long dxpTab) = 0; virtual void SetDxpDoc(long dxpDoc) = 0; virtual void SetXpLeft(long xpLeft) = 0; }; #endif //!RTXT_H