Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3743 lines
93 KiB

  1. /*
  2. * @doc TOM
  3. *
  4. * @module tomfmt.cpp - Implement the CTxtFont and CTxtPara Classes |
  5. *
  6. * This module contains the implementation of the TOM ITextFont and
  7. * ITextPara interfaces
  8. *
  9. * History: <nl>
  10. * 11/8/95 - MurrayS: created
  11. * 5/96 - MurrayS: added zombie protection
  12. *
  13. * Copyright (c) 1995-2000, Microsoft Corporation. All rights reserved.
  14. */
  15. #include "_common.h"
  16. #include "_tomfmt.h"
  17. #include "_font.h"
  18. ASSERTDATA
  19. #define tomFloatUndefined ((float)(int)tomUndefined)
  20. // Alignment translation vectors
  21. const BYTE g_rgREtoTOMAlign[] = // RichEdit to TOM
  22. {
  23. // TODO: generalize TOM to handle new LineServices options
  24. tomAlignLeft, tomAlignLeft, tomAlignRight, tomAlignCenter, tomAlignJustify,
  25. tomAlignInterLetter, tomAlignScaled, tomAlignGlyphs, tomAlignSnapGrid
  26. };
  27. const BYTE g_rgTOMtoREAlign[] = // TOM to RichEdit
  28. {
  29. PFA_LEFT, PFA_CENTER, PFA_RIGHT, PFA_FULL_INTERWORD,
  30. PFA_FULL_INTERLETTER, PFA_FULL_SCALED, PFA_FULL_GLYPHS,
  31. PFA_SNAP_GRID
  32. };
  33. /*
  34. * QueryInterface(riid, riid1, punk, ppv, fZombie)
  35. *
  36. * @func
  37. * QueryInterface punk for the ref IDs riid1, IID_IDispatch, and
  38. * IID_IUnknown
  39. *
  40. * @rdesc
  41. * HRESULT = (!ppv) ? E_INVALIDARG :
  42. * (interface found) ? NOERROR : E_NOINTERFACE
  43. */
  44. HRESULT QueryInterface (
  45. REFIID riid, //@parm Reference to requested interface ID
  46. REFIID riid1, //@parm Query for this, IDispatch, IUnknown
  47. IUnknown *punk, //@parm Interface to query
  48. void ** ppv, //@parm Out parm to receive interface ptr
  49. BOOL fZombie) //@parm If true, return CO_E_RELEASED
  50. {
  51. if(!ppv)
  52. return E_INVALIDARG;
  53. *ppv = NULL;
  54. if(fZombie) // Check for range zombie
  55. return CO_E_RELEASED;
  56. Assert(punk);
  57. if( IsEqualIID(riid, IID_IUnknown) ||
  58. IsEqualIID(riid, IID_IDispatch) ||
  59. IsEqualIID(riid, riid1) )
  60. {
  61. *ppv = punk;
  62. punk->AddRef();
  63. return NOERROR;
  64. }
  65. return E_NOINTERFACE;
  66. }
  67. //------------------------------- CTxtFont -------------------------------------
  68. /*
  69. * CTxtFont::CTxtFont(prg)
  70. *
  71. * @mfunc
  72. * Constructor
  73. */
  74. CTxtFont::CTxtFont(CTxtRange *prg) : CTxtFormat(prg)
  75. {
  76. Assert(!_dwMask); // We assume that object is zeroed (new'd)
  77. }
  78. //------------------------- CTxtFont IUnknown Methods -------------------------------------
  79. /* CTxtFont::IUnknown methods
  80. *
  81. * See tomDoc.cpp for comments
  82. */
  83. STDMETHODIMP CTxtFont::QueryInterface (REFIID riid, void **ppv)
  84. {
  85. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::QueryInterface");
  86. return ::QueryInterface(riid, IID_ITextFont, this, ppv, IsZombie());
  87. }
  88. STDMETHODIMP_(ULONG) CTxtFont::AddRef()
  89. {
  90. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::AddRef");
  91. return ++_cRefs;
  92. }
  93. STDMETHODIMP_(ULONG) CTxtFont::Release()
  94. {
  95. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::Release");
  96. _cRefs--;
  97. if(!_cRefs)
  98. {
  99. delete this;
  100. return 0;
  101. }
  102. return _cRefs;
  103. }
  104. //------------------------- CTxtFont IDispatch Methods -------------------------------------
  105. /*
  106. * CTxtFont::GetTypeInfoCount(pcTypeInfo)
  107. *
  108. * @mfunc
  109. * Get the number of TYPEINFO elements (1)
  110. *
  111. * @rdesc
  112. * HRESULT = (pcTypeInfo) ? NOERROR : E_INVALIDARG;
  113. */
  114. STDMETHODIMP CTxtFont::GetTypeInfoCount (
  115. UINT * pcTypeInfo) //@parm Out parm to receive type-info count
  116. {
  117. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetTypeInfoCount");
  118. if(!pcTypeInfo)
  119. return E_INVALIDARG;
  120. *pcTypeInfo = 1;
  121. return NOERROR;
  122. }
  123. /*
  124. * CTxtFont::GetTypeInfo(iTypeInfo, lcid, ppTypeInfo)
  125. *
  126. * @mfunc
  127. * Return ptr to type information object for ITextFont interface
  128. *
  129. * @rdesc
  130. * HRESULT
  131. */
  132. STDMETHODIMP CTxtFont::GetTypeInfo (
  133. UINT iTypeInfo, //@parm Index of type info to return
  134. LCID lcid, //@parm Local ID of type info
  135. ITypeInfo **ppTypeInfo) //@parm Out parm to receive type info
  136. {
  137. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetTypeInfo");
  138. return ::GetTypeInfo(iTypeInfo, g_pTypeInfoFont, ppTypeInfo);
  139. }
  140. /*
  141. * CTxtFont::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid)
  142. *
  143. * @mfunc
  144. * Get DISPIDs for ITextFont methods and properties
  145. *
  146. * @rdesc
  147. * HRESULT
  148. */
  149. STDMETHODIMP CTxtFont::GetIDsOfNames (
  150. REFIID riid, //@parm Interface ID to interpret names for
  151. OLECHAR ** rgszNames, //@parm Array of names to be mapped
  152. UINT cNames, //@parm Count of names to be mapped
  153. LCID lcid, //@parm Local ID to use for interpretation
  154. DISPID * rgdispid) //@parm Out parm to receive name mappings
  155. {
  156. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetIDsOfNames");
  157. HRESULT hr = GetTypeInfoPtrs(); // Ensure TypeInfo ptrs are OK
  158. if(hr != NOERROR)
  159. return hr;
  160. return g_pTypeInfoFont->GetIDsOfNames(rgszNames, cNames, rgdispid);
  161. }
  162. /*
  163. * CTxtFont::Invoke(dispidMember, riid, lcid, wFlags, pdispparams,
  164. * pvarResult, pexcepinfo, puArgError)
  165. * @mfunc
  166. * Invoke methods for the ITextFont interface
  167. *
  168. * @rdesc
  169. * HRESULT
  170. */
  171. STDMETHODIMP CTxtFont::Invoke (
  172. DISPID dispidMember, //@parm Identifies member function
  173. REFIID riid, //@parm Pointer to interface ID
  174. LCID lcid, //@parm Locale ID for interpretation
  175. USHORT wFlags, //@parm Flags describing context of call
  176. DISPPARAMS *pdispparams, //@parm Ptr to method arguments
  177. VARIANT * pvarResult, //@parm Out parm for result (if not NULL)
  178. EXCEPINFO * pexcepinfo, //@parm Out parm for exception info
  179. UINT * puArgError) //@parm Out parm for error
  180. {
  181. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::Invoke");
  182. HRESULT hr = GetTypeInfoPtrs(); // Ensure TypeInfo ptrs are OK
  183. if(hr != NOERROR)
  184. return hr;
  185. if(IsZombie())
  186. return CO_E_RELEASED;
  187. return g_pTypeInfoFont->Invoke(this, dispidMember, wFlags,
  188. pdispparams, pvarResult, pexcepinfo, puArgError);
  189. }
  190. //--------------------------- ITextFont Methods -------------------------------------
  191. /*
  192. * ITextFont::CanChange(long * pbCanChange)
  193. *
  194. * @mfunc
  195. * Method that sets *pbCanChange = tomTrue if and only if the
  196. * font can be changed.
  197. *
  198. * @rdesc
  199. * HRESULT = (can change char format) ? NOERROR : S_FALSE
  200. */
  201. STDMETHODIMP CTxtFont::CanChange (
  202. long *pbCanChange) //@parm Out parm to receive boolean value
  203. {
  204. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::CanChange");
  205. return CTxtFormat::CanChange(pbCanChange, CharFormat);
  206. }
  207. /*
  208. * ITextFont::GetAllCaps(long * pValue)
  209. *
  210. * @mfunc
  211. * Property get method that gets the AllCaps state.
  212. *
  213. * @rdesc
  214. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  215. */
  216. STDMETHODIMP CTxtFont::GetAllCaps (
  217. long *pValue) //@parm Out parm to receive tomBool
  218. {
  219. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetAllCaps");
  220. return EffectGetter(pValue, CFM_ALLCAPS);
  221. }
  222. /*
  223. * ITextFont::GetAnimation(long * pValue)
  224. *
  225. * @mfunc
  226. * Property get method that gets the animation type as defined
  227. * in the table below.
  228. *
  229. * @rdesc
  230. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  231. */
  232. STDMETHODIMP CTxtFont::GetAnimation (
  233. long *pValue) //@parm Out parm to receive animation type
  234. {
  235. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetAnimation");
  236. return GetParameter((long *)&_CF._bAnimation, CFM_ANIMATION, 1, pValue);
  237. }
  238. /*
  239. * ITextFont::GetBackColor(long * pValue)
  240. *
  241. * @mfunc
  242. * Property get method that gets the background color. The
  243. * value is a Win32 COLORREF.
  244. *
  245. * @rdesc
  246. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  247. */
  248. STDMETHODIMP CTxtFont::GetBackColor (
  249. long *pValue) //@parm Out parm to receive COLORREF value
  250. {
  251. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetBackColor");
  252. HRESULT hr = EffectGetter(pValue, CFE_AUTOBACKCOLOR);
  253. if(hr != NOERROR || *pValue == tomUndefined)
  254. return hr;
  255. *pValue = (*pValue == tomFalse) ? _CF._crBackColor : tomAutoColor;
  256. return NOERROR;
  257. }
  258. /*
  259. * ITextFont::GetBold(long * pValue)
  260. *
  261. * @mfunc
  262. * Property get method that gets the bold state.
  263. *
  264. * @rdesc
  265. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  266. */
  267. STDMETHODIMP CTxtFont::GetBold (
  268. long *pValue) //@parm Out parm to receive tomBool
  269. {
  270. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetBold");
  271. return EffectGetter(pValue, CFM_BOLD);
  272. }
  273. /*
  274. * ITextFont::GetDuplicate(ITextFont **ppFont)
  275. *
  276. * @mfunc
  277. * Property get method that gets a clone of this character
  278. * format object.
  279. *
  280. * @rdesc
  281. * HRESULT = (!ppFont) ? E_INVALIDARG :
  282. * (if success) ? NOERROR : S_FALSE
  283. */
  284. STDMETHODIMP CTxtFont::GetDuplicate (
  285. ITextFont **ppFont) //@parm Out parm to receive font clone
  286. {
  287. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetDuplicate");
  288. if(!ppFont)
  289. return E_INVALIDARG;
  290. *ppFont = NULL;
  291. if(IsZombie())
  292. return CO_E_RELEASED;
  293. CTxtFont *pFont = new CTxtFont(NULL);
  294. if(!pFont)
  295. return E_OUTOFMEMORY;
  296. if(_prg)
  297. UpdateFormat();
  298. pFont->_CF = _CF;
  299. pFont->_dwMask = _dwMask;
  300. *ppFont = pFont;
  301. return NOERROR;
  302. }
  303. /*
  304. * ITextFont::GetEmboss(long * pValue)
  305. *
  306. * @mfunc
  307. * Property get method that gets the embossed state.
  308. *
  309. * @rdesc
  310. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  311. */
  312. STDMETHODIMP CTxtFont::GetEmboss (
  313. long *pValue) //@parm Out parm to receive tomBool
  314. {
  315. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetEmboss");
  316. return EffectGetter(pValue, CFM_EMBOSS);
  317. }
  318. /*
  319. * ITextFont::GetForeColor(long * pValue)
  320. *
  321. * @mfunc
  322. * Property get method that gets the foreground color.
  323. *
  324. * @rdesc
  325. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  326. */
  327. STDMETHODIMP CTxtFont::GetForeColor (
  328. long *pValue) //@parm Out parm to receive COLORREF value
  329. {
  330. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetForeColor");
  331. HRESULT hr = EffectGetter(pValue, CFE_AUTOCOLOR);
  332. if(hr != NOERROR || *pValue == tomUndefined)
  333. return hr;
  334. *pValue = (*pValue == tomFalse) ? _CF._crTextColor : tomAutoColor;
  335. return NOERROR;
  336. }
  337. /*
  338. * ITextFont::GetHidden(long * pValue)
  339. *
  340. * @mfunc
  341. * Property get method that gets the hidden state.
  342. *
  343. * @rdesc
  344. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  345. */
  346. STDMETHODIMP CTxtFont::GetHidden (
  347. long *pValue) //@parm Out parm to receive tomBool
  348. {
  349. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetHidden");
  350. return EffectGetter(pValue, CFM_HIDDEN);
  351. }
  352. /*
  353. * ITextFont::GetEngrave(long * pValue)
  354. *
  355. * @mfunc
  356. * Property get method that gets the imprint state.
  357. *
  358. * @rdesc
  359. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  360. */
  361. STDMETHODIMP CTxtFont::GetEngrave (
  362. long *pValue) //@parm Out parm to receive tomBool
  363. {
  364. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetEngrave");
  365. return EffectGetter(pValue, CFM_IMPRINT);
  366. }
  367. /*
  368. * ITextFont::GetItalic(long * pValue)
  369. *
  370. * @mfunc
  371. * Property get method that gets the italic state.
  372. *
  373. * @rdesc
  374. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  375. */
  376. STDMETHODIMP CTxtFont::GetItalic (
  377. long *pValue) //@parm Out parm to receive tomBool
  378. {
  379. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetItalic");
  380. return EffectGetter(pValue, CFM_ITALIC);
  381. }
  382. /*
  383. * ITextFont::GetKerning(float * pValue)
  384. *
  385. * @mfunc
  386. * Property get method that gets the minimum kerning size,
  387. * which is given in floating-point points.
  388. *
  389. * @rdesc
  390. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  391. *
  392. * @comm
  393. * A kerning size of 0 turns off kerning, but an arbitrarily small
  394. * value turns it on, e.g., 1.0, which is too small to see, let alone
  395. * kern!
  396. */
  397. STDMETHODIMP CTxtFont::GetKerning (
  398. float *pValue) //@parm Out parm to receive minimum kerning size
  399. {
  400. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetKerning");
  401. return GetParameter((long *)&_CF._wKerning, CFM_KERNING, -2, (long *)pValue);
  402. }
  403. /*
  404. * ITextFont::GetLanguageID(long * pValue)
  405. *
  406. * @mfunc
  407. * Property get method that gets the language ID (more
  408. * generally LCID).
  409. *
  410. * @rdesc
  411. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  412. */
  413. STDMETHODIMP CTxtFont::GetLanguageID (
  414. long *pValue) //@parm Out parm to receive LCID value
  415. {
  416. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetLanguageID");
  417. if (!pValue)
  418. return E_INVALIDARG;
  419. if ((*pValue & 0xF0000000) == tomCharset)
  420. {
  421. UpdateFormat();
  422. // Special case to get CharSet and PitchAndFamily
  423. *pValue = (_CF._bPitchAndFamily << 8) + CharSetFromCharRep(_CF._iCharRep);
  424. return NOERROR;
  425. }
  426. return GetParameter((long *)&_CF._lcid, CFM_LCID, 4, pValue);
  427. }
  428. /*
  429. * ITextFont::GetName(BSTR *pbstr)
  430. *
  431. * @mfunc
  432. * Property get method that gets the font name.
  433. *
  434. * @rdesc
  435. * HRESULT = (!pValue) ? E_INVALIDARG :
  436. * (can allocate bstr) ? NOERROR : E_OUTOFMEMORY
  437. */
  438. STDMETHODIMP CTxtFont::GetName (
  439. BSTR *pbstr) //@parm Out parm to receive font name bstr
  440. {
  441. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetName");
  442. if(!pbstr)
  443. return E_INVALIDARG;
  444. *pbstr = NULL;
  445. HRESULT hr = UpdateFormat(); // If live Font object, update
  446. // _CF to current _prg values
  447. if(hr != NOERROR) // Attached to zombied range
  448. return hr;
  449. *pbstr = SysAllocString(GetFontName(_CF._iFont));
  450. return *pbstr ? NOERROR : E_OUTOFMEMORY;
  451. }
  452. /*
  453. * ITextFont::GetOutline(long * pValue)
  454. *
  455. * @mfunc
  456. * Property get method that gets the outline state.
  457. *
  458. * @rdesc
  459. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  460. */
  461. STDMETHODIMP CTxtFont::GetOutline (
  462. long *pValue) //@parm Out parm to receive tomBool
  463. {
  464. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetOutline");
  465. return EffectGetter(pValue, CFM_OUTLINE);
  466. }
  467. /*
  468. * ITextFont::GetPosition(float *pValue)
  469. *
  470. * @mfunc
  471. * Property get method that gets the character position
  472. * relative to the baseline. The value is given in floating-point
  473. * points.
  474. *
  475. * @rdesc
  476. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  477. */
  478. STDMETHODIMP CTxtFont::GetPosition (
  479. float *pValue) //@parm Out parm to receive relative vertical position
  480. {
  481. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetPosition");
  482. return GetParameter((long *)&_CF._yOffset, CFM_OFFSET, -2, (long *)pValue);
  483. }
  484. /*
  485. * ITextFont::GetProtected(long * pValue)
  486. *
  487. * @mfunc
  488. * Property get method that gets the protected state.
  489. *
  490. * @rdesc
  491. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  492. */
  493. STDMETHODIMP CTxtFont::GetProtected (
  494. long *pValue) //@parm Out parm to receive tomBool
  495. {
  496. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetProtected");
  497. return EffectGetter(pValue, CFM_PROTECTED);
  498. }
  499. /*
  500. * ITextFont::GetShadow(long * pValue)
  501. *
  502. * @mfunc
  503. * Property get method that gets the shadow state.
  504. *
  505. * @rdesc
  506. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  507. */
  508. STDMETHODIMP CTxtFont::GetShadow (
  509. long *pValue) //@parm Out parm to receive tomBool
  510. {
  511. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetShadow");
  512. return EffectGetter(pValue, CFM_SHADOW);
  513. }
  514. /*
  515. * ITextFont::GetSize(float * pValue)
  516. *
  517. * @mfunc
  518. * Property get method that gets the font size, which is given
  519. * in floating-point points.
  520. *
  521. * @rdesc
  522. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  523. */
  524. STDMETHODIMP CTxtFont::GetSize (
  525. float *pValue) //@parm Out parm to receive font size
  526. {
  527. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetSize");
  528. return GetParameter((long *)&_CF._yHeight, CFM_SIZE, -2, (long *)pValue);
  529. }
  530. /*
  531. * ITextFont::GetSmallCaps(long * pValue)
  532. *
  533. * @mfunc
  534. * Property get method that gets the SmallCaps state.
  535. *
  536. * @rdesc
  537. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  538. */
  539. STDMETHODIMP CTxtFont::GetSmallCaps (
  540. long *pValue) //@parm Out parm to receive tomBool
  541. {
  542. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetSmallCaps");
  543. return EffectGetter(pValue, CFM_SMALLCAPS);
  544. }
  545. /*
  546. * ITextFont::GetSpacing(float * pValue)
  547. *
  548. * @mfunc
  549. * Property get method that gets the intercharacter spacing,
  550. * which is given in floating-point points.
  551. *
  552. * @rdesc
  553. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  554. */
  555. STDMETHODIMP CTxtFont::GetSpacing (
  556. float *pValue) //@parm Out parm to receive intercharacter spacing
  557. {
  558. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetSpacing");
  559. return GetParameter((long *)&_CF._sSpacing, CFM_SPACING, -2, (long *)pValue);
  560. }
  561. /*
  562. * ITextFont::GetStrikeThrough(long * pValue)
  563. *
  564. * @mfunc
  565. * Property get method that gets the strikeout state.
  566. *
  567. * @rdesc
  568. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  569. */
  570. STDMETHODIMP CTxtFont::GetStrikeThrough (
  571. long *pValue) //@parm Out parm to receive tomBool
  572. {
  573. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetStrikeThrough");
  574. return EffectGetter(pValue, CFM_STRIKEOUT);
  575. }
  576. /*
  577. * ITextFont::GetStyle(long * pValue)
  578. *
  579. * @mfunc
  580. * Property get method that gets the character style handle for
  581. * the characters in a range.
  582. *
  583. * @rdesc
  584. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  585. */
  586. STDMETHODIMP CTxtFont::GetStyle (
  587. long *pValue) //@parm Out parm to receive character style handle
  588. {
  589. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetStyle");
  590. return GetParameter((long *)&_CF._sStyle, CFM_STYLE, 2, pValue);
  591. }
  592. /*
  593. * ITextFont::GetSubscript(long * pValue)
  594. *
  595. * @mfunc
  596. * Property get method that gets the subscript state.
  597. *
  598. * @rdesc
  599. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  600. */
  601. STDMETHODIMP CTxtFont::GetSubscript (
  602. long *pValue) //@parm Out parm to receive tomBool
  603. {
  604. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetSubscript");
  605. return EffectGetter(pValue, CFE_SUBSCRIPT);
  606. }
  607. /*
  608. * ITextFont::GetSuperscript(long * pValue)
  609. *
  610. * @mfunc
  611. * Property get method that gets the superscript state.
  612. *
  613. * @rdesc
  614. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  615. */
  616. STDMETHODIMP CTxtFont::GetSuperscript (
  617. long *pValue) //@parm Out parm to receive tomBool
  618. {
  619. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetSuperscript");
  620. return EffectGetter(pValue, CFE_SUPERSCRIPT);
  621. }
  622. /*
  623. * ITextFont::GetUnderline(long * pValue)
  624. *
  625. * @mfunc
  626. * Property get method that gets the underline style.
  627. *
  628. * @rdesc
  629. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
  630. */
  631. STDMETHODIMP CTxtFont::GetUnderline (
  632. long *pValue) //@parm Out parm to receive underline style
  633. {
  634. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetUnderline");
  635. if(!pValue)
  636. return E_INVALIDARG;
  637. HRESULT hr = UpdateFormat(); // If live Font object, update
  638. // _CF to current _prg values
  639. *pValue = 0; // Default no underline
  640. if(!(_dwMask & CFM_UNDERLINE)) // It's a NINCH
  641. *pValue = tomUndefined;
  642. else if(_CF._dwEffects & CFM_UNDERLINE)
  643. *pValue = (LONG)_CF._bUnderlineType ? (LONG)_CF._bUnderlineType : tomTrue;
  644. return hr;
  645. }
  646. /*
  647. * ITextFont::GetWeight(long * pValue)
  648. *
  649. * @mfunc
  650. * Property get method that gets the font weight for
  651. * the characters in a range.
  652. *
  653. * @rdesc
  654. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  655. */
  656. STDMETHODIMP CTxtFont::GetWeight (
  657. long *pValue) //@parm Out parm to receive character style handle
  658. {
  659. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::GetWeight");
  660. return GetParameter((long *)&_CF._wWeight, CFM_WEIGHT, 2, pValue);
  661. }
  662. /*
  663. * ITextFont::IsEqual(ITextFont * pFont, long * pB)
  664. *
  665. * @mfunc
  666. * Method that sets *<p pB> = tomTrue if this text font has the
  667. * same properties as *<p pFont>. For this to be true, *<p pFont> has to
  668. * belong to the same TOM engine as the present one. The IsEqual()
  669. * method should ignore entries for which either font object has a
  670. * tomUndefined value.
  671. *
  672. * @rdesc
  673. * HRESULT = (equal objects) ? NOERROR : S_FALSE
  674. *
  675. * @devnote
  676. * This implementation assumes that all properties are defined and that
  677. * pFont belongs to RichEdit. It would be nice to generalize this so
  678. * that undefined properties are ignored in the comparison and so that
  679. * pFont could belong to a different TOM engine. This would help in
  680. * using RichEdit Find dialogs to search for rich text in Word using
  681. * TOM.
  682. */
  683. STDMETHODIMP CTxtFont::IsEqual (
  684. ITextFont * pFont, //@parm ITextFont to compare to
  685. long * pB) //@parm Out parm to receive comparison result
  686. {
  687. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::IsEqual");
  688. if(pB)
  689. *pB = tomFalse;
  690. if(!IsSameVtables(this, pFont))
  691. return S_FALSE;
  692. HRESULT hr = UpdateFormat(); // Update _CFs in case they are
  693. if(hr != NOERROR) // attached to ranges
  694. return hr;
  695. CTxtFont *pF = (CTxtFont *)pFont;
  696. hr = pF->UpdateFormat();
  697. if(hr != NOERROR)
  698. return hr;
  699. // Ignore differences in CharSet, since TOM thinks all CharSets are Unicode!
  700. DWORD dwIgnore = (DWORD)(~CFM_CHARSET);
  701. if(!(_CF._dwEffects & CFE_UNDERLINE)) // If not underlining, ignore
  702. dwIgnore &= ~CFM_UNDERLINETYPE; // differences in underline type
  703. DWORD dwMask = pF->_dwMask & dwIgnore;
  704. if((_dwMask ^ dwMask) & dwIgnore) // The masks have to be the same
  705. return S_FALSE; // for equality
  706. if(dwMask & _CF.Delta(&(pF->_CF),FALSE))// Any difference?
  707. return S_FALSE; // Yes. *pB set equal to tomFalse above
  708. if(pB)
  709. *pB = tomTrue;
  710. return NOERROR;
  711. }
  712. /*
  713. * ITextFont::Reset(long Value)
  714. *
  715. * @mfunc
  716. * Method that resets the character formatting to the default
  717. * values to 1) those defined by the RTF \plain control word (Value =
  718. * tomDefault), and 2) all undefined values (Value = tomUndefined).
  719. *
  720. * @rdesc
  721. * HRESULT = (if success) ? NOERROR :
  722. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  723. */
  724. STDMETHODIMP CTxtFont::Reset (
  725. long Value) //@parm Kind of reset (tomDefault or tomUndefined)
  726. {
  727. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::Reset");
  728. HRESULT hr = CanChange(NULL);
  729. if(hr != NOERROR) // Takes care of zombie
  730. return hr; // and protection
  731. if(Value == tomDefault)
  732. {
  733. if(_prg)
  734. {
  735. _CF = *_prg->GetPed()->GetCharFormat(-1);
  736. FormatSetter(CFM_ALL2);
  737. }
  738. else
  739. _CF.InitDefault(0);
  740. _dwMask = CFM_ALL2;
  741. }
  742. else if(Value == tomApplyTmp)
  743. {
  744. _fApplyLater = 1;
  745. _fApplyToTmp = 1;
  746. // Reset all temp. display attribute
  747. _tmpDisplayAttr.wMask = 0;
  748. _tmpDisplayAttr.bUnderlineType = 0;
  749. _tmpDisplayAttr.crTextColor = (DWORD)tomUndefined;
  750. _tmpDisplayAttr.crBackColor = (DWORD)tomUndefined;
  751. _tmpDisplayAttr.crUnderlineColor = (DWORD)tomUndefined;
  752. }
  753. else if(Value == tomUndefined && !_prg) // Only applicable
  754. _dwMask = 0; // for clones
  755. else if((Value | 1) == tomApplyLater) // Set-method optimization
  756. {
  757. _fApplyLater = Value & 1;
  758. if(!_fApplyLater) // Apply now
  759. {
  760. FormatSetter(_dwMask);
  761. _fApplyToTmp = 0;
  762. }
  763. }
  764. else if((Value | 1) == tomCacheParms) // Get-method optimization
  765. {
  766. _fCacheParms = FALSE;
  767. if(Value & 1) // Cache parms now, but
  768. { // don't update on gets
  769. UpdateFormat();
  770. _fCacheParms = TRUE;
  771. }
  772. }
  773. else
  774. return E_INVALIDARG;
  775. return NOERROR;
  776. }
  777. /*
  778. * ITextFont::SetAllCaps(long Value)
  779. *
  780. * @mfunc
  781. * Property put method that sets the AllCaps state according to
  782. * the value given by Value.
  783. *
  784. * @rdesc
  785. * HRESULT = (if success) ? NOERROR :
  786. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  787. */
  788. STDMETHODIMP CTxtFont::SetAllCaps (
  789. long Value) //@parm New value. Default value: tomToggle
  790. {
  791. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetAllCaps");
  792. return EffectSetter(Value, CFM_ALLCAPS | CFM_SMALLCAPS, CFE_ALLCAPS);
  793. }
  794. /*
  795. * ITextFont::SetAnimation(long Value)
  796. *
  797. * @mfunc
  798. * Property put method that sets the animation type
  799. *
  800. * @rdesc
  801. * HRESULT = (Value defined) ? NOERROR : E_INVALIDARG
  802. */
  803. STDMETHODIMP CTxtFont::SetAnimation (
  804. long Value) //@parm New animation type
  805. {
  806. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetAnimation");
  807. if(Value == tomUndefined)
  808. return NOERROR;
  809. if((unsigned)Value > tomAnimationMax)
  810. return E_INVALIDARG;
  811. return SetParameter((long *)&_CF._bAnimation, CFM_ANIMATION, 1, Value);
  812. }
  813. /*
  814. * ITextFont::SetBackColor(long Value)
  815. *
  816. * @mfunc
  817. * Property put method that sets the background color according
  818. * to the value given by Value.
  819. *
  820. * @rdesc
  821. * HRESULT = (if success) ? NOERROR :
  822. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  823. * @devnote
  824. * Legal values are tomUndefined, tomAutoColor (both negative) and
  825. * in principle any positive values. Currently wingdi.h only defines
  826. * high bytes = 0, 1, 2, 4. But more values might happen, so we only
  827. * rule out negative values other than tomUndefined and tomAutoColor.
  828. */
  829. STDMETHODIMP CTxtFont::SetBackColor (
  830. long Value ) //@parm New COLORREF value to use
  831. {
  832. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetBackColor");
  833. if(Value == tomUndefined) // NINCH
  834. return NOERROR;
  835. if (_fApplyToTmp)
  836. {
  837. _tmpDisplayAttr.wMask |= APPLY_TMP_BACKCOLOR;
  838. _tmpDisplayAttr.crBackColor = (COLORREF)Value;
  839. return NOERROR;
  840. }
  841. _CF._dwEffects |= CFE_AUTOBACKCOLOR; // Default AutoBackColor
  842. if(Value != tomAutoColor)
  843. {
  844. if(Value < 0)
  845. return E_INVALIDARG;
  846. _CF._dwEffects &= ~CFE_AUTOBACKCOLOR; // Turn off AutoBackColor
  847. _CF._crBackColor = (COLORREF)Value; // Use new BackColor
  848. }
  849. return FormatSetter(CFM_BACKCOLOR);
  850. }
  851. /*
  852. * ITextFont::SetBold(long Value)
  853. *
  854. * @mfunc
  855. * Property put method that sets the bold state according to
  856. * the value given by Value.
  857. *
  858. * @rdesc
  859. * HRESULT = (if success) ? NOERROR :
  860. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  861. */
  862. STDMETHODIMP CTxtFont::SetBold (
  863. long Value) //@parm New value. Default value: tomToggle
  864. {
  865. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetBold");
  866. return EffectSetter(Value, CFM_BOLD, CFE_BOLD);
  867. }
  868. /*
  869. * ITextFont::SetDuplicate(ITextFont *pFont)
  870. *
  871. * @mfunc
  872. * Property put method that sets this text font character
  873. * formatting to that given by pFont.
  874. *
  875. * @rdesc
  876. * HRESULT = (if success) ? NOERROR :
  877. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  878. */
  879. STDMETHODIMP CTxtFont::SetDuplicate(
  880. ITextFont *pFont) //@parm Font object to apply to this font object
  881. {
  882. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetDuplicate");
  883. DWORD dwMask = 0;
  884. BSTR bstr;
  885. CTxtRange * prg;
  886. long Value;
  887. float x;
  888. if(IsZombie()) // Check for range zombie
  889. return CO_E_RELEASED;
  890. if(IsSameVtables(this, pFont)) // If pFont belongs to this TOM
  891. { // engine, can cast and copy
  892. ((CTxtFont *)pFont)->UpdateFormat();
  893. _CF = ((CTxtFont *)pFont)->_CF;
  894. dwMask = ((CTxtFont *)pFont)->_dwMask;// Use this mask in case this
  895. } // font is active
  896. else
  897. { // Need to call pFont for all font
  898. prg = _prg; // properties
  899. _prg = NULL; // Be sure it's a clone during
  900. // transfer
  901. pFont->GetStyle(&Value);
  902. SetStyle(Value);
  903. pFont->GetAllCaps(&Value);
  904. SetAllCaps(Value);
  905. pFont->GetAnimation(&Value);
  906. SetAnimation(Value);
  907. pFont->GetBackColor(&Value);
  908. SetBackColor(Value);
  909. pFont->GetBold(&Value);
  910. SetBold(Value);
  911. pFont->GetEmboss(&Value);
  912. SetEmboss(Value);
  913. pFont->GetForeColor(&Value);
  914. SetForeColor(Value);
  915. pFont->GetHidden(&Value);
  916. SetHidden(Value);
  917. pFont->GetEngrave(&Value);
  918. SetEngrave(Value);
  919. pFont->GetItalic(&Value);
  920. SetItalic(Value);
  921. pFont->GetKerning(&x);
  922. SetKerning(x);
  923. pFont->GetLanguageID(&Value);
  924. SetLanguageID(Value);
  925. pFont->GetName(&bstr);
  926. SetName(bstr);
  927. SysFreeString(bstr);
  928. pFont->GetOutline(&Value);
  929. SetOutline(Value);
  930. pFont->GetPosition(&x);
  931. SetPosition(x);
  932. pFont->GetProtected(&Value);
  933. SetProtected(Value);
  934. pFont->GetShadow(&Value);
  935. SetShadow(Value);
  936. pFont->GetSize(&x);
  937. SetSize(x);
  938. pFont->GetSmallCaps(&Value);
  939. SetSmallCaps(Value);
  940. pFont->GetSpacing(&x);
  941. SetSpacing(x);
  942. pFont->GetStrikeThrough(&Value);
  943. SetStrikeThrough(Value);
  944. pFont->GetSubscript(&Value);
  945. SetSubscript(Value);
  946. pFont->GetSuperscript(&Value);
  947. SetSuperscript(Value);
  948. pFont->GetUnderline(&Value);
  949. SetUnderline(Value);
  950. _prg = prg; // Restore original value
  951. }
  952. return FormatSetter(dwMask); // Apply it unless !_prg
  953. }
  954. /*
  955. * ITextFont::SetEmboss(long Value)
  956. *
  957. * @mfunc
  958. * Property put method that sets the embossed state according
  959. * to the value given by Value
  960. *
  961. * @rdesc
  962. * HRESULT = (if success) ? NOERROR :
  963. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  964. */
  965. STDMETHODIMP CTxtFont::SetEmboss (
  966. long Value) //@parm New value. Default value: tomToggle
  967. {
  968. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetEmboss");
  969. return EffectSetter(Value, CFM_EMBOSS, CFE_EMBOSS);
  970. }
  971. /*
  972. * ITextFont::SetForeColor(long Value)
  973. *
  974. * @mfunc
  975. * Property put method that sets the foreground color according
  976. * to the value given by Value.
  977. *
  978. * @rdesc
  979. * HRESULT = (if success) ? NOERROR :
  980. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  981. */
  982. STDMETHODIMP CTxtFont::SetForeColor (
  983. long Value ) //@parm New COLORREF value to use
  984. {
  985. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetForeColor");
  986. if(Value == tomUndefined) // NINCH
  987. return NOERROR;
  988. if (_fApplyToTmp)
  989. {
  990. _tmpDisplayAttr.wMask |= APPLY_TMP_FORECOLOR;
  991. _tmpDisplayAttr.crTextColor = (COLORREF)Value;
  992. return NOERROR;
  993. }
  994. _CF._dwEffects |= CFE_AUTOCOLOR; // Default AutoColor
  995. if(Value != tomAutoColor)
  996. {
  997. if(Value < 0)
  998. return E_INVALIDARG;
  999. _CF._dwEffects &= ~CFE_AUTOCOLOR; // Turn off AutoColor
  1000. _CF._crTextColor = (COLORREF)Value; // Use new TextColor
  1001. }
  1002. return FormatSetter(CFM_COLOR);
  1003. }
  1004. /*
  1005. * ITextFont::SetHidden(long Value)
  1006. *
  1007. * @mfunc
  1008. * Property put method that sets the hidden state according to
  1009. * the value given by Value.
  1010. *
  1011. * @rdesc
  1012. * HRESULT = (if success) ? NOERROR :
  1013. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1014. */
  1015. STDMETHODIMP CTxtFont::SetHidden (
  1016. long Value) //@parm New value. Default value: tomToggle
  1017. {
  1018. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetHidden");
  1019. return EffectSetter(Value, CFM_HIDDEN, CFE_HIDDEN);
  1020. }
  1021. /*
  1022. * ITextFont::SetEngrave(long Value)
  1023. *
  1024. * @mfunc
  1025. * Property put method that sets the imprint state according to
  1026. * the value given by Value.
  1027. *
  1028. * @rdesc
  1029. * HRESULT = (if success) ? NOERROR :
  1030. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1031. */
  1032. STDMETHODIMP CTxtFont::SetEngrave (
  1033. long Value) //@parm New value. Default value: tomToggle
  1034. {
  1035. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetEngrave");
  1036. return EffectSetter(Value, CFM_IMPRINT, CFE_IMPRINT);
  1037. }
  1038. /*
  1039. * ITextFont::SetItalic(long Value)
  1040. *
  1041. * @mfunc
  1042. * Property put method that sets the italic state according to
  1043. * the value given by Value.
  1044. *
  1045. * @rdesc
  1046. * HRESULT = (if success) ? NOERROR :
  1047. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1048. */
  1049. STDMETHODIMP CTxtFont::SetItalic (
  1050. long Value) //@parm New value. Default value: tomToggle
  1051. {
  1052. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetItalic");
  1053. return EffectSetter(Value, CFM_ITALIC, CFE_ITALIC);
  1054. }
  1055. /*
  1056. * ITextFont::SetKerning(float Value)
  1057. *
  1058. * @mfunc
  1059. * Property set method that sets the minimum kerning size,
  1060. * which is given in floating-point points.
  1061. *
  1062. * @rdesc
  1063. * HRESULT = (Value < 0) ? E_INVALIDARG :
  1064. * (if success) ? NOERROR :
  1065. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1066. */
  1067. STDMETHODIMP CTxtFont::SetKerning (
  1068. float Value) //@parm New value of minimum kerning size
  1069. {
  1070. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetKerning");
  1071. return SetParameter((long *)&_CF._wKerning, CFM_KERNING, -2, *(long *)&Value);
  1072. }
  1073. /*
  1074. * ITextFont::SetLanguageID(long Value)
  1075. *
  1076. * @mfunc
  1077. * Property put method that sets the language ID (more
  1078. * generally LCID) according to the value given by Value. See
  1079. * GetLanguageID() for more information.
  1080. *
  1081. * @rdesc
  1082. * HRESULT = (if success) ? NOERROR :
  1083. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1084. */
  1085. STDMETHODIMP CTxtFont::SetLanguageID (
  1086. long Value) //@parm New LCID to use
  1087. {
  1088. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetLanguageID");
  1089. if ((Value & 0xF0000000) == tomCharset)
  1090. {
  1091. // Sepcial case to set charset and pitchandfamily
  1092. _CF._iCharRep = CharRepFromCharSet(Value);
  1093. _CF._bPitchAndFamily = (BYTE)(Value >> 8);
  1094. return FormatSetter(CFM_CHARSET);
  1095. }
  1096. return SetParameter((long *)&_CF._lcid, CFM_LCID, 4, Value);
  1097. }
  1098. /*
  1099. * ITextFont::SetName(BSTR Name)
  1100. *
  1101. * @mfunc
  1102. * Property put method that sets the font name to Name.
  1103. *
  1104. * @rdesc
  1105. * HRESULT = (Name too long) ? E_INVALIDARG :
  1106. * (if success) ? NOERROR :
  1107. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1108. */
  1109. STDMETHODIMP CTxtFont::SetName(
  1110. BSTR Name) //@parm New font name
  1111. {
  1112. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetName");
  1113. LONG cch = SysStringLen(Name);
  1114. if(cch > LF_FACESIZE)
  1115. return E_INVALIDARG;
  1116. if(!cch) // NINCH
  1117. return NOERROR;
  1118. _CF._iFont = GetFontNameIndex(Name);
  1119. _CF._iCharRep = GetFirstAvailCharRep(GetFontSignatureFromFace(_CF._iFont));
  1120. return FormatSetter(CFM_FACE + CFM_CHARSET);
  1121. }
  1122. /*
  1123. * ITextFont::SetOutline(long Value)
  1124. *
  1125. * @mfunc
  1126. * Property put method that sets the outline state according to
  1127. * the value given by Value.
  1128. *
  1129. * @rdesc
  1130. * HRESULT = (if success) ? NOERROR :
  1131. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1132. */
  1133. STDMETHODIMP CTxtFont::SetOutline (
  1134. long Value) //@parm New value. Default value: tomToggle
  1135. {
  1136. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetOutline");
  1137. return EffectSetter(Value, CFM_OUTLINE, CFE_OUTLINE);
  1138. }
  1139. /*
  1140. * ITextFont::SetPosition(float Value)
  1141. *
  1142. * @mfunc
  1143. * Property set method that sets the character position
  1144. * relative to the baseline. The value is given in floating-point
  1145. * points.
  1146. *
  1147. * @rdesc
  1148. * HRESULT = (if success) ? NOERROR :
  1149. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1150. */
  1151. STDMETHODIMP CTxtFont::SetPosition (
  1152. float Value) //@parm New value of relative vertical position
  1153. {
  1154. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetPosition");
  1155. return SetParameter((long *)&_CF._yOffset, CFM_OFFSET, -2, *(long *)&Value);
  1156. }
  1157. /*
  1158. * ITextFont::SetProtected(long Value)
  1159. *
  1160. * @mfunc
  1161. * Property put method that sets the protected state according
  1162. * to the value given by Value.
  1163. *
  1164. * @rdesc
  1165. * HRESULT = (if success) ? NOERROR : S_FALSE
  1166. */
  1167. STDMETHODIMP CTxtFont::SetProtected (
  1168. long Value) //@parm New value. Default value: tomToggle
  1169. {
  1170. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetProtected");
  1171. return EffectSetter(Value, CFM_PROTECTED, CFE_PROTECTED);
  1172. }
  1173. /*
  1174. * ITextFont::SetShadow(long Value)
  1175. *
  1176. * @mfunc
  1177. * Property put method that sets the shadow state according to
  1178. * the value given by Value.
  1179. *
  1180. * @rdesc
  1181. * HRESULT = (if success) ? NOERROR :
  1182. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1183. */
  1184. STDMETHODIMP CTxtFont::SetShadow (
  1185. long Value) //@parm New value. Default value: tomToggle
  1186. {
  1187. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetShadow");
  1188. return EffectSetter(Value, CFM_SHADOW, CFE_SHADOW);
  1189. }
  1190. /*
  1191. * ITextFont::SetSize(float Value)
  1192. *
  1193. * @mfunc
  1194. * Property put method that sets the font size = Value (in
  1195. * floating-point points).
  1196. *
  1197. * @rdesc
  1198. * HRESULT = (if success) ? NOERROR :
  1199. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1200. */
  1201. STDMETHODIMP CTxtFont::SetSize (
  1202. float Value) //@parm New font size to use
  1203. {
  1204. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetSize");
  1205. return SetParameter((long *)&_CF._yHeight, CFM_SIZE, -2, *(long *)&Value);
  1206. }
  1207. /*
  1208. * ITextFont::SetSmallCaps(long Value)
  1209. *
  1210. * @mfunc
  1211. * Property put method that sets the SmallCaps state according
  1212. * to the value given by Value.
  1213. *
  1214. * @rdesc
  1215. * HRESULT = (if success) ? NOERROR :
  1216. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1217. */
  1218. STDMETHODIMP CTxtFont::SetSmallCaps (
  1219. long Value) //@parm New value. Default value: tomToggle
  1220. {
  1221. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetSmallCaps");
  1222. return EffectSetter(Value, CFM_ALLCAPS | CFM_SMALLCAPS, CFE_SMALLCAPS);
  1223. }
  1224. /*
  1225. * ITextFont::SetSpacing(float Value)
  1226. *
  1227. * @mfunc
  1228. * Property set method that sets the intercharacter spacing,
  1229. * which is given in floating-point points.
  1230. *
  1231. * @rdesc
  1232. * HRESULT = (if success) ? NOERROR :
  1233. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1234. */
  1235. STDMETHODIMP CTxtFont::SetSpacing (
  1236. float Value) //@parm New value of intercharacter spacing
  1237. {
  1238. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetSpacing");
  1239. return SetParameter((long *)&_CF._sSpacing, CFM_SPACING, -2, *(long *)&Value);
  1240. }
  1241. /*
  1242. * ITextFont::SetStrikeThrough(long Value)
  1243. *
  1244. * @mfunc
  1245. * Property put method that sets the StrikeThrough state
  1246. * according to the value given by Value.
  1247. *
  1248. * @rdesc
  1249. * HRESULT = (if success) ? NOERROR :
  1250. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1251. */
  1252. STDMETHODIMP CTxtFont::SetStrikeThrough (
  1253. long Value) //@parm New value. Default value: tomToggle
  1254. {
  1255. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetStrikeThrough");
  1256. return EffectSetter(Value, CFM_STRIKEOUT, CFE_STRIKEOUT);
  1257. }
  1258. /*
  1259. * ITextFont::SetStyle(long Value)
  1260. *
  1261. * @mfunc
  1262. * Property put method that sets the character style handle for
  1263. * the characters in a range. See GetStyle() for further discussion.
  1264. *
  1265. * @rdesc
  1266. * HRESULT = (if success) ? NOERROR :
  1267. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1268. */
  1269. STDMETHODIMP CTxtFont::SetStyle (
  1270. long Value) //@parm New character style handle
  1271. {
  1272. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetStyle");
  1273. if(Value == tomUndefined)
  1274. return NOERROR;
  1275. if(Value < -32768 || Value > 32767)
  1276. return E_INVALIDARG;
  1277. return SetParameter((long *)&_CF._sStyle, CFM_STYLE, 2, Value);
  1278. }
  1279. /*
  1280. * ITextFont::SetSubscript(long Value)
  1281. *
  1282. * @mfunc
  1283. * Property put method that sets the subscript state according
  1284. * to the value given by Value.
  1285. *
  1286. * @rdesc
  1287. * HRESULT = (if success) ? NOERROR :
  1288. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1289. */
  1290. STDMETHODIMP CTxtFont::SetSubscript (
  1291. long Value) //@parm New value. Default value: tomToggle
  1292. {
  1293. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetSubscript");
  1294. return EffectSetter(Value, CFM_SUBSCRIPT | CFM_SUPERSCRIPT, CFE_SUBSCRIPT);
  1295. }
  1296. /*
  1297. * ITextFont::SetSuperscript(long Value)
  1298. *
  1299. * @mfunc
  1300. * Property put method that sets the superscript state
  1301. * according to the value given by Value
  1302. *
  1303. * @rdesc
  1304. * HRESULT = (if success) ? NOERROR :
  1305. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1306. */
  1307. STDMETHODIMP CTxtFont::SetSuperscript (
  1308. long Value) //@parm New value. Default value: tomToggle
  1309. {
  1310. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetSuperscript");
  1311. return EffectSetter(Value, CFM_SUBSCRIPT | CFM_SUPERSCRIPT, CFE_SUPERSCRIPT);
  1312. }
  1313. /*
  1314. * ITextFont::SetUnderline(long Value)
  1315. *
  1316. * @mfunc
  1317. * Property put method that sets the underline style according
  1318. * to the value given by Value.
  1319. *
  1320. * @rdesc
  1321. * HRESULT = (if success) ? NOERROR :
  1322. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1323. */
  1324. STDMETHODIMP CTxtFont::SetUnderline (
  1325. long Value) //@parm New value of underline type
  1326. {
  1327. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetUnderline");
  1328. if (_fApplyToTmp)
  1329. {
  1330. if (Value == tomAutoColor)
  1331. _tmpDisplayAttr.crUnderlineColor = (DWORD)tomAutoColor;
  1332. else if ((((DWORD)Value) & 0x0FF000000) == 0x0FF000000)
  1333. _tmpDisplayAttr.crUnderlineColor = ((DWORD)Value) & 0x000FFFFFF; // Set UL color
  1334. else
  1335. _tmpDisplayAttr.bUnderlineType = (BYTE)(Value & 0x1F); // Set UL style
  1336. return NOERROR;
  1337. }
  1338. _CF._bUnderlineType = 0; // Default no underline type
  1339. if(Value < 0) // tomTrue, tomUndefined, or
  1340. return EffectSetter(Value, CFM_UNDERLINETYPE | CFM_UNDERLINE, CFE_UNDERLINE);
  1341. if(Value > 0x0FFFF) // Illegal underline type
  1342. return E_INVALIDARG;
  1343. _CF._bUnderlineType = (BYTE)(Value & 0x1F);
  1344. _CF._bUnderlineColor = (BYTE)(Value/256);
  1345. _CF._dwEffects &= ~CFM_UNDERLINE; // Default underlining is off
  1346. if(Value)
  1347. _CF._dwEffects |= CFM_UNDERLINE; // It's on
  1348. return FormatSetter(CFM_UNDERLINETYPE + CFM_UNDERLINE);
  1349. }
  1350. /*
  1351. * ITextFont::SetWeight(long Value)
  1352. *
  1353. * @mfunc
  1354. * Property put method that sets the font weight for
  1355. * the characters in a range.
  1356. *
  1357. * @rdesc
  1358. * HRESULT = (if success) ? NOERROR :
  1359. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1360. */
  1361. STDMETHODIMP CTxtFont::SetWeight (
  1362. long Value) //@parm New character style handle
  1363. {
  1364. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFont::SetWeight");
  1365. if(Value == tomUndefined) // NINCH
  1366. return NOERROR;
  1367. if((unsigned)Value > 900) // Valid values satisfy:
  1368. return E_INVALIDARG; // 0 <= Value <= 900
  1369. return SetParameter((long *)&_CF._wWeight, CFM_WEIGHT, 2, Value);
  1370. }
  1371. //------------------------------- CTxtPara ------------------------------------
  1372. /*
  1373. * CTxtPara::CTxtPara(prg)
  1374. *
  1375. * @mfunc
  1376. * Constructor
  1377. */
  1378. CTxtPara::CTxtPara(CTxtRange *prg) : CTxtFormat(prg)
  1379. {
  1380. Assert(!_dwMask && !_PF._dwBorderColor); // We assume that object is zeroed (new'd)
  1381. _PF._iTabs = -1;
  1382. }
  1383. /*
  1384. * CTxtPara::~CTxtPara()
  1385. *
  1386. * @mfunc
  1387. * Destructor
  1388. */
  1389. CTxtPara::~CTxtPara()
  1390. {
  1391. Assert(_PF._iTabs == -1);
  1392. }
  1393. //------------------------- CTxtPara IUnknown Methods -------------------------------------
  1394. /* CTxtPara::IUnknown methods
  1395. *
  1396. * See tomdoc.cpp for comments
  1397. */
  1398. STDMETHODIMP CTxtPara::QueryInterface (REFIID riid, void **ppv)
  1399. {
  1400. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::QueryInterface");
  1401. return ::QueryInterface(riid, IID_ITextPara, this, ppv, IsZombie());
  1402. }
  1403. STDMETHODIMP_(ULONG) CTxtPara::AddRef()
  1404. {
  1405. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::AddRef");
  1406. return ++_cRefs;
  1407. }
  1408. STDMETHODIMP_(ULONG) CTxtPara::Release()
  1409. {
  1410. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::Release");
  1411. _cRefs--;
  1412. if(!_cRefs)
  1413. {
  1414. delete this;
  1415. return 0;
  1416. }
  1417. return _cRefs;
  1418. }
  1419. //------------------------- CTxtPara IDispatch Methods -------------------------------------
  1420. /*
  1421. * CTxtPara::GetTypeInfoCount(pcTypeInfo)
  1422. *
  1423. * @mfunc
  1424. * Get the number of TYPEINFO elements (1)
  1425. *
  1426. * @rdesc
  1427. * HRESULT = (pcTypeInfo) ? NOERROR : E_INVALIDARG;
  1428. */
  1429. STDMETHODIMP CTxtPara::GetTypeInfoCount (
  1430. UINT * pcTypeInfo) //@parm Out parm to receive type-info count
  1431. {
  1432. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetTypeInfoCount");
  1433. if(!pcTypeInfo)
  1434. return E_INVALIDARG;
  1435. *pcTypeInfo = 1;
  1436. return NOERROR;
  1437. }
  1438. /*
  1439. * CTxtPara::GetTypeInfo(iTypeInfo, lcid, ppTypeInfo)
  1440. *
  1441. * @mfunc
  1442. * Return ptr to type information object for ITextPara interface
  1443. *
  1444. * @rdesc
  1445. * HRESULT
  1446. */
  1447. STDMETHODIMP CTxtPara::GetTypeInfo (
  1448. UINT iTypeInfo, //@parm Index of type info to return
  1449. LCID lcid, //@parm Local ID of type info
  1450. ITypeInfo **ppTypeInfo) //@parm Out parm to receive type info
  1451. {
  1452. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetTypeInfo");
  1453. return ::GetTypeInfo(iTypeInfo, g_pTypeInfoPara, ppTypeInfo);
  1454. }
  1455. /*
  1456. * CTxtPara::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid)
  1457. *
  1458. * @mfunc
  1459. * Get DISPIDs for ITextPara methods and properties
  1460. *
  1461. * @rdesc
  1462. * HRESULT
  1463. */
  1464. STDMETHODIMP CTxtPara::GetIDsOfNames (
  1465. REFIID riid, //@parm Interface ID to interpret names for
  1466. OLECHAR ** rgszNames, //@parm Array of names to be mapped
  1467. UINT cNames, //@parm Count of names to be mapped
  1468. LCID lcid, //@parm Local ID to use for interpretation
  1469. DISPID * rgdispid) //@parm Out parm to receive name mappings
  1470. {
  1471. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetIDsOfNames");
  1472. HRESULT hr = GetTypeInfoPtrs(); // Ensure TypeInfo ptrs are OK
  1473. if(hr != NOERROR)
  1474. return hr;
  1475. return g_pTypeInfoPara->GetIDsOfNames(rgszNames, cNames, rgdispid);
  1476. }
  1477. /*
  1478. * CTxtPara::Invoke(dispidMember, riid, lcid, wFlags, pdispparams,
  1479. * pvarResult, pexcepinfo, puArgError)
  1480. * @mfunc
  1481. * Invoke methods for the ITextPara interface
  1482. *
  1483. * @rdesc
  1484. * HRESULT
  1485. */
  1486. STDMETHODIMP CTxtPara::Invoke (
  1487. DISPID dispidMember, //@parm Identifies member function
  1488. REFIID riid, //@parm Pointer to interface ID
  1489. LCID lcid, //@parm Locale ID for interpretation
  1490. USHORT wFlags, //@parm Flags describing context of call
  1491. DISPPARAMS *pdispparams, //@parm Ptr to method arguments
  1492. VARIANT * pvarResult, //@parm Out parm for result (if not NULL)
  1493. EXCEPINFO * pexcepinfo, //@parm Out parm for exception info
  1494. UINT * puArgError) //@parm Out parm for error
  1495. {
  1496. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::Invoke");
  1497. HRESULT hr = GetTypeInfoPtrs(); // Ensure TypeInfo ptrs are OK
  1498. if(hr != NOERROR)
  1499. return hr;
  1500. if(IsZombie())
  1501. return CO_E_RELEASED;
  1502. return g_pTypeInfoPara->Invoke(this, dispidMember, wFlags,
  1503. pdispparams, pvarResult, pexcepinfo, puArgError);
  1504. }
  1505. //------------------------ CTxtPara ITextPara Methods -------------------------------------
  1506. /*
  1507. * ITextPara::AddTab(float tbPos, long tbAlign, long tbLeader)
  1508. *
  1509. * @mfunc
  1510. * Method that adds a tab at the displacement tbPos, with type
  1511. * tbAlign, and leader style tbLeader. The displacement is given in
  1512. * floating-point points.
  1513. *
  1514. * @rdesc
  1515. * HRESULT = (if success) ? NOERROR :
  1516. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1517. */
  1518. STDMETHODIMP CTxtPara::AddTab (
  1519. float tbPos, //@parm New tab displacement
  1520. long tbAlign, //@parm New tab type
  1521. long tbLeader) //@parm New tab style
  1522. {
  1523. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::AddTab");
  1524. HRESULT hr = UpdateFormat(); // If live Para object, update
  1525. // _PF to current _prg values
  1526. if(hr != NOERROR)
  1527. return hr; // Must be a zombie
  1528. //This doesn't seem correct because it doesn't ever look at whether or not
  1529. //we are in a table.
  1530. hr = _PF.AddTab(FPPTS_TO_TWIPS(tbPos), tbAlign, tbLeader, &_rgxTabs[0]);
  1531. if(hr != NOERROR)
  1532. return hr;
  1533. return FormatSetter(PFM_TABSTOPS);
  1534. }
  1535. /*
  1536. * ITextPara::CanChange(long * pbCanChange)
  1537. *
  1538. * @mfunc
  1539. * Method that sets *pbCanChange = tomTrue if and only if the
  1540. * paragraph formatting can be changed.
  1541. *
  1542. * @rdesc
  1543. * HRESULT = (can change char format) ? NOERROR : S_FALSE
  1544. */
  1545. STDMETHODIMP CTxtPara::CanChange (
  1546. long *pbCanChange) //@parm Out parm to receive boolean value
  1547. {
  1548. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::CanChange");
  1549. return CTxtFormat::CanChange(pbCanChange, ParaFormat);
  1550. }
  1551. /*
  1552. * ITextPara::ClearAllTabs()
  1553. *
  1554. * @mfunc
  1555. * Method that clears all tabs, reverting to equally spaced
  1556. * tabs with the default tab spacing.
  1557. *
  1558. * @rdesc
  1559. * HRESULT = (if success) ? NOERROR :
  1560. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1561. */
  1562. STDMETHODIMP CTxtPara::ClearAllTabs()
  1563. {
  1564. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::ClearAllTabs");
  1565. _PF._bTabCount = 0; // Signal to use default tab
  1566. return FormatSetter(PFM_TABSTOPS);
  1567. }
  1568. /*
  1569. * ITextPara::DeleteTab(tbPos)
  1570. *
  1571. * @mfunc
  1572. * Delete any tab at the displacement tbPos. This displacement is
  1573. * given in floating-point points.
  1574. *
  1575. * @rdesc
  1576. * HRESULT = (if success) ? NOERROR :
  1577. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  1578. */
  1579. STDMETHODIMP CTxtPara::DeleteTab (
  1580. float tbPos) //@parm Displacement at which tab should be deleted
  1581. {
  1582. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::DeleteTab");
  1583. HRESULT hr = UpdateFormat(); // If live Para object, update
  1584. // _PF to current _prg values
  1585. if(hr != NOERROR)
  1586. return hr; // Must be a zombie
  1587. hr = _PF.DeleteTab(FPPTS_TO_TWIPS(tbPos), &_rgxTabs[0]);
  1588. return hr != NOERROR ? hr : FormatSetter(PFM_TABSTOPS);
  1589. }
  1590. /*
  1591. * ITextPara::GetAlignment(long * pValue)
  1592. *
  1593. * @mfunc
  1594. * Property get method that gets the current paragraph
  1595. * alignment value
  1596. *
  1597. * @rdesc
  1598. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1599. */
  1600. STDMETHODIMP CTxtPara::GetAlignment (
  1601. long *pValue) //@parm Out parm to receive paragraph alignment
  1602. {
  1603. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetAlignment");
  1604. if(!pValue)
  1605. return E_INVALIDARG;
  1606. HRESULT hr = UpdateFormat(); // If live Para object, update
  1607. // _PF to current _prg values
  1608. if(_PF._bAlignment > ARRAY_SIZE(g_rgREtoTOMAlign)) // Fix bogus value since
  1609. _PF._bAlignment = 0; // array lookup can't use it
  1610. *pValue = (_dwMask & PFM_ALIGNMENT)
  1611. ? (LONG)g_rgREtoTOMAlign[_PF._bAlignment] : tomUndefined;
  1612. return hr;
  1613. }
  1614. /*
  1615. * ITextPara::GetHyphenation(long *pValue)
  1616. *
  1617. * @mfunc
  1618. * Property get method that gets the tomBool for whether to
  1619. * suppress hyphenation for the paragraph in a range.
  1620. *
  1621. * @rdesc
  1622. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1623. */
  1624. STDMETHODIMP CTxtPara::GetHyphenation (
  1625. long *pValue) //@parm Out parm to receive tomBool
  1626. {
  1627. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetHyphenation");
  1628. if(!pValue)
  1629. return E_INVALIDARG;
  1630. HRESULT hr = EffectGetter(pValue, PFM_DONOTHYPHEN);
  1631. //Oh well, Word inverted meaning after we shipped...
  1632. if(*pValue == tomTrue)
  1633. *pValue = tomFalse;
  1634. else if(*pValue == tomFalse)
  1635. *pValue = tomTrue;
  1636. return hr;
  1637. }
  1638. /*
  1639. * ITextPara::GetDuplicate(ITextPara **ppPara)
  1640. *
  1641. * @mfunc
  1642. * Property get method that gets a clone of this text paragraph
  1643. * format object.
  1644. *
  1645. * @rdesc
  1646. * HRESULT = (!ppPara) ? E_INVALIDARG :
  1647. * (if success) ? NOERROR : S_FALSE
  1648. */
  1649. STDMETHODIMP CTxtPara::GetDuplicate (
  1650. ITextPara **ppPara) //@parm Out parm to receive ITextPara clone
  1651. {
  1652. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetDuplicate");
  1653. if(!ppPara)
  1654. return E_INVALIDARG;
  1655. *ppPara = NULL;
  1656. if(IsZombie())
  1657. return CO_E_RELEASED;
  1658. CTxtPara *pPara = new CTxtPara(NULL); // NULL creates a clone
  1659. if(!pPara) // (its _prg is NULL)
  1660. return E_OUTOFMEMORY;
  1661. if(_prg)
  1662. UpdateFormat();
  1663. *pPara = *this; // Copy value of this object
  1664. pPara->_prg = NULL; // It's not attached to a rg
  1665. *ppPara = pPara; // Return ptr to clone
  1666. return NOERROR;
  1667. }
  1668. /*
  1669. * ITextPara::GetFirstLineIndent(float * pValue)
  1670. *
  1671. * @mfunc
  1672. * Property get method that gets the amount used to indent the
  1673. * first line of a paragraph relative to the left indent, which is used
  1674. * for subsequent lines. The amount is given in floating-point points.
  1675. *
  1676. * @rdesc
  1677. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1678. */
  1679. STDMETHODIMP CTxtPara::GetFirstLineIndent (
  1680. float *pValue) //@parm Out parm to receive first-line indent
  1681. {
  1682. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetFirstLineIndent");
  1683. HRESULT hr = GetParameter(&_PF._dxOffset, PFM_OFFSET, -4, (long *)pValue);
  1684. if(hr == NOERROR && *pValue != tomFloatUndefined)
  1685. *pValue = -*pValue; // Defined as negative of
  1686. return hr; // RichEdit dxOffset
  1687. }
  1688. /*
  1689. * ITextPara::GetKeepTogether(long * pValue)
  1690. *
  1691. * @mfunc
  1692. * Property get method that gets the tomBool for whether to
  1693. * keep the lines in a range together.
  1694. *
  1695. * @rdesc
  1696. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1697. */
  1698. STDMETHODIMP CTxtPara::GetKeepTogether (
  1699. long *pValue) //@parm Out parm to receive tomBool
  1700. {
  1701. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetKeepTogether");
  1702. return EffectGetter(pValue, PFM_KEEP);
  1703. }
  1704. /*
  1705. * ITextPara::GetKeepWithNext(long * pValue)
  1706. *
  1707. * @mfunc
  1708. * Property get method that gets the tomBool for whether to
  1709. * keep the paragraphs in this range together.
  1710. *
  1711. * @rdesc
  1712. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1713. */
  1714. STDMETHODIMP CTxtPara::GetKeepWithNext (
  1715. long *pValue) //@parm Out parm to receive tomBool
  1716. {
  1717. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetKeepWithNext");
  1718. return EffectGetter(pValue, PFM_KEEPNEXT);
  1719. }
  1720. #define PFM_LEFTINDENT (PFM_STARTINDENT + PFM_OFFSET)
  1721. /*
  1722. * ITextPara::GetLeftIndent(float * pValue)
  1723. *
  1724. * @mfunc
  1725. * Property get method that gets the amount used to indent all
  1726. * but the first line of a paragraph. The amount is given in
  1727. * floating-point points and is relative to the left margin.
  1728. *
  1729. * @rdesc
  1730. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1731. *
  1732. * @devnote
  1733. * For the TOM left indent to be defined, both the RichEdit start
  1734. * indent and the offset must be defined (see XOR and AND in *pValue
  1735. * code).
  1736. */
  1737. STDMETHODIMP CTxtPara::GetLeftIndent (
  1738. float *pValue) //@parm Out parm to receive left indent
  1739. {
  1740. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetLeftIndent");
  1741. if(!pValue)
  1742. return E_INVALIDARG;
  1743. HRESULT hr = UpdateFormat(); // If live Para object, update
  1744. // _PF to current _prg values
  1745. *pValue = ((_dwMask ^ PFM_LEFTINDENT) & PFM_LEFTINDENT)
  1746. ? tomFloatUndefined
  1747. : TWIPS_TO_FPPTS(_PF._dxStartIndent + _PF._dxOffset);
  1748. return hr;
  1749. }
  1750. /*
  1751. * ITextPara::GetLineSpacing(float * pValue)
  1752. *
  1753. * @mfunc
  1754. * Property get method that gets the line spacing value, which
  1755. * is given in floating-point points.
  1756. *
  1757. * @rdesc
  1758. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1759. */
  1760. STDMETHODIMP CTxtPara::GetLineSpacing (
  1761. float *pValue) //@parm Out parm to receive line spacing
  1762. {
  1763. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetLineSpacing");
  1764. return GetParameter(&_PF._dyLineSpacing, PFM_LINESPACING, -4,
  1765. (long *)pValue);
  1766. }
  1767. /*
  1768. * ITextPara::GetLineSpacingRule(long * pValue)
  1769. *
  1770. * @mfunc
  1771. * Property get method that gets the line-spacing rule for this range
  1772. *
  1773. * @rdesc
  1774. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1775. */
  1776. STDMETHODIMP CTxtPara::GetLineSpacingRule (
  1777. long *pValue) //@parm Out parm to receive line spacing rule
  1778. {
  1779. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetLineSpacingRule");
  1780. return GetParameter((long *)&_PF._bLineSpacingRule, PFM_LINESPACING,
  1781. 1, pValue);
  1782. }
  1783. /*
  1784. * ITextPara::GetListAlignment(long * pValue)
  1785. *
  1786. * @mfunc
  1787. * Property get method that gets the kind of bullet/numbering text
  1788. * alignment to use with paragraphs.
  1789. *
  1790. * @rdesc
  1791. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1792. */
  1793. STDMETHODIMP CTxtPara::GetListAlignment(
  1794. long * pValue) //@parm Out parm to receive numbering alignment
  1795. {
  1796. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetListAlignment");
  1797. HRESULT hr = GetParameter((long *)&_PF._wNumberingStyle,
  1798. PFM_NUMBERINGSTYLE, 2, pValue);
  1799. if(hr == NOERROR && *pValue != tomUndefined)
  1800. *pValue &= 3; // Kill all but alignment bits
  1801. return hr;
  1802. }
  1803. /*
  1804. * ITextPara::GetListLevelIndex(long * pValue)
  1805. *
  1806. * @mfunc
  1807. * Property get method that gets the list level index to use
  1808. * with paragraphs.
  1809. *
  1810. * @rdesc
  1811. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1812. */
  1813. STDMETHODIMP CTxtPara::GetListLevelIndex(
  1814. long * pValue) //@parm Out parm to receive list level index
  1815. {
  1816. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetListLevelIndex");
  1817. HRESULT hr = GetParameter((long *)&_PF._wNumberingStyle,
  1818. PFM_NUMBERINGSTYLE, 2, pValue);
  1819. if(hr == NOERROR)
  1820. *pValue = (*pValue >> 4) & 0xf; // Kill all but list level index
  1821. return hr;
  1822. }
  1823. /*
  1824. * ITextPara::GetListStart(long * pValue)
  1825. *
  1826. * @mfunc
  1827. * Property get method that gets the numbering start value to use
  1828. * with paragraphs.
  1829. *
  1830. * @rdesc
  1831. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1832. */
  1833. STDMETHODIMP CTxtPara::GetListStart(
  1834. long * pValue) //@parm Out parm to receive numbering start value
  1835. {
  1836. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetListSpace");
  1837. return GetParameter((long *)&_PF._wNumberingStart, PFM_NUMBERINGSTART, 2,
  1838. pValue);
  1839. }
  1840. /*
  1841. * ITextPara::GetListTab(long * pValue)
  1842. *
  1843. * @mfunc
  1844. * Property get method that gets the distance between the first indent
  1845. * and the start of text on the first line.
  1846. *
  1847. * @rdesc
  1848. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1849. */
  1850. STDMETHODIMP CTxtPara::GetListTab(
  1851. float * pValue) //@parm Out parm to receive list tab to text
  1852. {
  1853. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetListTab");
  1854. return GetParameter((long *)&_PF._wNumberingTab, PFM_NUMBERINGTAB, -2,
  1855. (long *)pValue);
  1856. }
  1857. /*
  1858. * ITextPara::GetListType(long * pValue)
  1859. *
  1860. * @mfunc
  1861. * Property get method that gets the type of list to use
  1862. * with paragraphs.
  1863. *
  1864. * @rdesc
  1865. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1866. *
  1867. * @devnote
  1868. * TOM's values are:
  1869. *
  1870. * List Type Value Meaning
  1871. * tomNoList 0 Turn off paragraph numbering
  1872. * tomListBullet 1 default is bullet
  1873. * tomListNumberAsArabic 2 0, 1, 2, ...
  1874. * tomListNumberAsLCLetter 3 a, b, c, ...
  1875. * tomListNumberAsUCLetter 4 A, B, C, ...
  1876. * tomListNumberAsLCRoman 5 i, ii, iii, ...
  1877. * tomListNumberAsUCRoman 6 I, II, III, ...
  1878. * tomListNumberAsSequence 7 ListStart is 1st Unicode to use
  1879. *
  1880. * Nibble 2 of _PF._wNumberingStyle says whether to number with trailing
  1881. * parenthesis, both parentheses, follow by period, or leave plain. This
  1882. * This nibble needs to be returned in nibble 4 of *pValue.
  1883. * The high bit (PFNS_NEWNUMBER) also needs to be returned.
  1884. */
  1885. STDMETHODIMP CTxtPara::GetListType (
  1886. long *pValue) //@parm Out parm to receive type of list
  1887. {
  1888. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetListType");
  1889. HRESULT hr = GetParameter((long *)&_PF._wNumbering,
  1890. PFM_NUMBERING, 2, pValue);
  1891. // OR in Number style bits (see note above)
  1892. if(hr == NOERROR && *pValue != tomUndefined)
  1893. *pValue |= (_PF._wNumberingStyle << 8) & 0x8F0000;
  1894. return hr;
  1895. }
  1896. /*
  1897. * ITextPara::GetNoLineNumber(long * pValue)
  1898. *
  1899. * @mfunc
  1900. * Property get method that gets the tomBool for whether to
  1901. * suppress line numbering for the paragraphs in a range.
  1902. *
  1903. * @rdesc
  1904. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1905. */
  1906. STDMETHODIMP CTxtPara::GetNoLineNumber (
  1907. long *pValue) //@parm Out parm to receive tomBool
  1908. {
  1909. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetNoLineNumber");
  1910. return EffectGetter(pValue, PFM_NOLINENUMBER);
  1911. }
  1912. /*
  1913. * ITextPara::GetPageBreakBefore(long * pValue)
  1914. *
  1915. * @mfunc
  1916. * Property get method that gets the tomBool for whether to
  1917. * eject the page before the paragraphs in this range.
  1918. *
  1919. * @rdesc
  1920. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1921. */
  1922. STDMETHODIMP CTxtPara::GetPageBreakBefore (
  1923. long *pValue) //@parm Out parm to receive tomBool
  1924. {
  1925. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetPageBreakBefore");
  1926. return EffectGetter(pValue, PFM_PAGEBREAKBEFORE);
  1927. }
  1928. /*
  1929. * ITextPara::GetRightIndent(float * pValue)
  1930. *
  1931. * @mfunc
  1932. * Property get method that gets the amount used to indent the
  1933. * right margin of a paragraph relative to the right margin. The
  1934. * amount is given in floating-point points.
  1935. *
  1936. * @rdesc
  1937. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1938. */
  1939. STDMETHODIMP CTxtPara::GetRightIndent (
  1940. float *pValue) //@parm Out parm to receive right indent
  1941. {
  1942. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetRightIndent");
  1943. return GetParameter(&_PF._dxRightIndent, PFM_RIGHTINDENT, -4,
  1944. (long *)pValue);
  1945. }
  1946. /*
  1947. * ITextPara::GetSpaceAfter(float * pValue)
  1948. *
  1949. * @mfunc
  1950. * Property get method that gets the amount used to space vertically
  1951. * after a paragraph. The amount is given in floating-point points.
  1952. *
  1953. * @rdesc
  1954. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1955. */
  1956. STDMETHODIMP CTxtPara::GetSpaceAfter (
  1957. float *pValue) //@parm Out parm to receive space-after value
  1958. {
  1959. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetSpaceAfter");
  1960. return GetParameter(&_PF._dySpaceAfter, PFM_SPACEAFTER, -4,
  1961. (long *)pValue);
  1962. }
  1963. /*
  1964. * ITextPara::GetSpaceBefore(float * pValue)
  1965. *
  1966. * @mfunc
  1967. * Property get method that gets the amount used to space vertically
  1968. * before starting a paragraph. The amount is given in floating-point
  1969. * points.
  1970. *
  1971. * @rdesc
  1972. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1973. */
  1974. STDMETHODIMP CTxtPara::GetSpaceBefore (
  1975. float *pValue) //@parm Out parm to receive space-before value
  1976. {
  1977. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetSpaceBefore");
  1978. return GetParameter(&_PF._dySpaceBefore, PFM_SPACEBEFORE, -4,
  1979. (long *)pValue);
  1980. }
  1981. /*
  1982. * ITextPara::GetStyle(long * pValue)
  1983. *
  1984. * @mfunc
  1985. * Property get method that gets the style handle for the
  1986. * paragraphs in this range.
  1987. *
  1988. * @rdesc
  1989. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  1990. */
  1991. STDMETHODIMP CTxtPara::GetStyle (
  1992. long * pValue) //@parm Out parm to receive paragraph style handle
  1993. {
  1994. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetStyle");
  1995. return GetParameter((long *)&_PF._sStyle, PFM_STYLE, 2, pValue);
  1996. }
  1997. /*
  1998. * ITextPara::GetTab(long iTab, float *ptbPos, long *ptAlign, long *ptbLeader)
  1999. *
  2000. * @mfunc
  2001. * Method that gets tab parameters for the iTab th tab, that
  2002. * is, set *ptbPos, *ptbAlign, and *ptbLeader equal to the iTab th
  2003. * tab's displacement, alignment, and leader style, respectively.
  2004. * iTab has special values defined in the table below. The
  2005. * displacement is given in floating-point points.
  2006. *
  2007. * @rdesc
  2008. * HRESULT = (!pdxptab || !ptbt || !pstyle || no iTab tab) ?
  2009. * E_INVALIDARG : (exists) ? NOERROR : S_FALSE
  2010. */
  2011. STDMETHODIMP CTxtPara::GetTab (
  2012. long iTab, //@parm Index of tab to retrieve info for
  2013. float * ptbPos, //@parm Out parm to receive tab displacement
  2014. long * ptbAlign, //@parm Out parm to receive tab type
  2015. long * ptbLeader) //@parm Out parm to receive tab style
  2016. {
  2017. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetTab");
  2018. if(!ptbPos || !ptbAlign || !ptbLeader)
  2019. return E_INVALIDARG;
  2020. *ptbAlign = *ptbLeader = 0;
  2021. HRESULT hr = UpdateFormat(); // If live Para object, update
  2022. // _PF to current _prg values
  2023. if(!(_dwMask & PFM_TABSTOPS)) // Tabs are undefined (more than
  2024. { // one set of definitions)
  2025. *ptbPos = tomFloatUndefined;
  2026. return hr;
  2027. }
  2028. LONG dxTab = 0; // Default 0 in case GetTab fails
  2029. if(iTab < 0 && iTab >= tomTabBack) // Save *ptbPos if it's supposed
  2030. dxTab = FPPTS_TO_TWIPS(*ptbPos); // be used (in general might get
  2031. // floating-point error)
  2032. hr = _PF.GetTab(iTab, &dxTab, ptbAlign, ptbLeader, &_rgxTabs[0]);
  2033. *ptbPos = TWIPS_TO_FPPTS(dxTab);
  2034. return (hr == NOERROR && !dxTab) ? S_FALSE : hr;
  2035. }
  2036. /*
  2037. * ITextPara::GetTabCount(long * pValue)
  2038. *
  2039. * @mfunc
  2040. * Property get method that gets the tab count.
  2041. *
  2042. * @rdesc
  2043. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  2044. */
  2045. STDMETHODIMP CTxtPara::GetTabCount (
  2046. long * pValue) //@parm Out parm to receive tab count
  2047. {
  2048. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetTabCount");
  2049. return GetParameter((long *)&_PF._bTabCount, PFM_TABSTOPS, 1, pValue);
  2050. }
  2051. /*
  2052. * ITextPara::GetWidowControl(long * pValue)
  2053. *
  2054. * @mfunc
  2055. * Property get method that gets the tomBool for whether to
  2056. * control widows and orphans for the paragraphs in a range.
  2057. *
  2058. * @rdesc
  2059. * HRESULT = (!pValue) ? E_INVALIDARG : NOERROR;
  2060. */
  2061. STDMETHODIMP CTxtPara::GetWidowControl (
  2062. long * pValue) //@parm Out parm to receive tomBool
  2063. {
  2064. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::GetWidowControl");
  2065. return EffectGetter(pValue, PFM_NOWIDOWCONTROL);
  2066. }
  2067. /*
  2068. * ITextPara::IsEqual(ITextPara * pPara, long * pB)
  2069. *
  2070. * @mfunc
  2071. * Method that sets pB = tomTrue if this range has the same
  2072. * properties as *pPara. The IsEqual() method ignores entries for which
  2073. * either para object has a tomUndefined value.
  2074. *
  2075. * @rdesc
  2076. * HRESULT = (equal objects) ? NOERROR : S_FALSE
  2077. */
  2078. STDMETHODIMP CTxtPara::IsEqual (
  2079. ITextPara * pPara, //@parm ITextPara to compare to
  2080. long * pB) //@parm Out parm to receive comparison result
  2081. {
  2082. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::IsEqual");
  2083. if(pB)
  2084. *pB = tomFalse;
  2085. if(!IsSameVtables(this, pPara))
  2086. return S_FALSE;
  2087. HRESULT hr = UpdateFormat(); // Update _PFs in case they are
  2088. if(hr != NOERROR) // attached to ranges
  2089. return hr;
  2090. CTxtPara *pP = (CTxtPara *)pPara;
  2091. hr = pP->UpdateFormat();
  2092. if(hr != NOERROR)
  2093. return hr;
  2094. CParaFormat *pPF = &(pP->_PF);
  2095. DWORD dwMask = pP->_dwMask; // Save mask
  2096. if(_dwMask != dwMask) // The two have to be the same
  2097. return S_FALSE; // for equality
  2098. if((dwMask & PFM_TABSTOPS) && _PF._bTabCount)
  2099. {
  2100. _PF._iTabs = GetTabsCache()->Cache(&_rgxTabs[0], _PF._bTabCount);
  2101. if(pP != this) // If comparing to self,
  2102. { // don't AddRef twice
  2103. pP->_PF._iTabs = GetTabsCache()->Cache(&pP->_rgxTabs[0],
  2104. pPF->_bTabCount);
  2105. }
  2106. }
  2107. if(dwMask & _PF.Delta(pPF, FALSE)) // Any difference?
  2108. hr = S_FALSE; // Yes. *pB set equal to tomFalse above
  2109. else if(pB)
  2110. *pB = tomTrue;
  2111. CheckTabsAddRef();
  2112. pP->CheckTabsAddRef();
  2113. return hr;
  2114. }
  2115. /*
  2116. * ITextPara::Reset(long Value)
  2117. *
  2118. * @mfunc
  2119. * Method that resets the paragraph formatting to the default
  2120. * values to 1) those defined by the RTF \pard control word (Value =
  2121. * tomDefault), and 2) all undefined values (Value = tomUndefined).
  2122. *
  2123. * @rdesc
  2124. * HRESULT = (if success) ? NOERROR :
  2125. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2126. */
  2127. STDMETHODIMP CTxtPara::Reset (
  2128. long Value) //@parm Kind of reset (tomDefault or tomUndefined)
  2129. {
  2130. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::Reset");
  2131. Assert(tomApplyLater == tomApplyNow + 1);
  2132. HRESULT hr = CanChange(NULL);
  2133. if(hr != NOERROR) // Takes care of zombie
  2134. return hr; // and protection
  2135. if(Value == tomDefault)
  2136. {
  2137. if(_prg)
  2138. {
  2139. _PF = *_prg->GetPed()->GetParaFormat(-1);
  2140. if(_PF._iTabs != -1)
  2141. {
  2142. const LONG *prgxTabs = _PF.GetTabs();
  2143. _PF._iTabs = -1;
  2144. for(LONG i = 0; i < _PF._bTabCount; i++)
  2145. _rgxTabs[i] = prgxTabs[i];
  2146. }
  2147. FormatSetter(PFM_ALL2);
  2148. }
  2149. else
  2150. _PF.InitDefault(0);
  2151. _dwMask = PFM_ALL2;
  2152. }
  2153. else if(Value == tomUndefined && // Only applicable for clones
  2154. (!_prg || _fApplyLater)) // or delayed application
  2155. {
  2156. _dwMask = 0;
  2157. }
  2158. else if((Value | 1) == tomApplyLater) // Set-method optimization
  2159. {
  2160. _fApplyLater = Value & 1;
  2161. if(!_fApplyLater) // Apply now
  2162. FormatSetter(_dwMask);
  2163. }
  2164. else if((Value | 1) == tomCacheParms) // Get-method optimization
  2165. {
  2166. _fCacheParms = FALSE;
  2167. if(Value & 1) // Cache parms now, but
  2168. { // don't update on gets
  2169. UpdateFormat();
  2170. _fCacheParms = TRUE;
  2171. }
  2172. }
  2173. else
  2174. return E_INVALIDARG;
  2175. return NOERROR;
  2176. }
  2177. /*
  2178. * ITextPara::SetAlignment(long Value)
  2179. *
  2180. * @mfunc
  2181. * Property put method that sets the paragraph alignment to Value
  2182. *
  2183. * @rdesc
  2184. * HRESULT = (Value > 3) ? E_INVALIDARG :
  2185. * (if success) ? NOERROR :
  2186. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2187. */
  2188. STDMETHODIMP CTxtPara::SetAlignment (
  2189. long Value) //@parm New paragraph alignment
  2190. {
  2191. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetAlignment");
  2192. if(Value == tomUndefined) // NINCH
  2193. return NOERROR;
  2194. if((DWORD)Value >= ARRAY_SIZE(g_rgTOMtoREAlign))
  2195. return E_INVALIDARG;
  2196. _PF._bAlignment = g_rgTOMtoREAlign[Value];
  2197. return FormatSetter(PFM_ALIGNMENT);
  2198. }
  2199. /*
  2200. * ITextPara::SetHyphenation(long Value)
  2201. *
  2202. * @mfunc
  2203. * Property put method that sets the tomBool that controls the
  2204. * suppression of hyphenation for the paragraphs in the range.
  2205. *
  2206. * @rdesc
  2207. * HRESULT = (if success) ? NOERROR :
  2208. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2209. */
  2210. STDMETHODIMP CTxtPara::SetHyphenation (
  2211. long Value) //@parm New tomBool for suppressing hyphenation
  2212. {
  2213. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetHyphenation");
  2214. if(Value == tomTrue) // Invert meaning for RichEdit
  2215. Value = tomFalse; // Word inverted it late in the game...
  2216. else if (Value == tomFalse)
  2217. Value = tomTrue;
  2218. return EffectSetter(Value, PFM_DONOTHYPHEN);
  2219. }
  2220. /*
  2221. * ITextPara::SetDuplicate(ITextPara *pPara)
  2222. *
  2223. * @mfunc
  2224. * Property put method that applies the paragraph formatting of pPara
  2225. * to this para object. Note that tomUndefined values in pPara have
  2226. * no effect (NINCH - NoInputNoCHange).
  2227. *
  2228. * @rdesc
  2229. * HRESULT = (!pPara) ? E_INVALIDARG :
  2230. * (if success) ? NOERROR :
  2231. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2232. */
  2233. STDMETHODIMP CTxtPara::SetDuplicate (
  2234. ITextPara *pPara) //@parm New paragraph formatting
  2235. {
  2236. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetDuplicate");
  2237. DWORD dwMask = 0;
  2238. long iTab;
  2239. CTxtRange * prg;
  2240. long tbAlign;
  2241. long tbLeader;
  2242. float tbPos;
  2243. long Value;
  2244. float x, y, z;
  2245. if(IsZombie()) // Check for range zombie
  2246. return CO_E_RELEASED;
  2247. if(IsSameVtables(this, pPara)) // If pPara belongs to this TOM
  2248. { // engine, cast and copy
  2249. ((CTxtPara *)pPara)->UpdateFormat();// Since this TOM engine, can
  2250. _PF = ((CTxtPara *)pPara)->_PF; // cast to a CTxtPara
  2251. dwMask = ((CTxtPara *)pPara)->_dwMask;// Use this mask in case this
  2252. } // para is active
  2253. else
  2254. { // Need to call pFont for all para
  2255. prg = _prg; // properties
  2256. _prg = NULL; // Turn into clone during transfer
  2257. pPara->GetStyle(&Value);
  2258. SetStyle(Value);
  2259. pPara->GetAlignment(&Value);
  2260. SetAlignment(Value);
  2261. pPara->GetHyphenation(&Value);
  2262. SetHyphenation(Value);
  2263. pPara->GetKeepTogether(&Value);
  2264. SetKeepTogether(Value);
  2265. pPara->GetKeepWithNext(&Value);
  2266. SetKeepWithNext(Value);
  2267. pPara->GetFirstLineIndent(&x);
  2268. pPara->GetLeftIndent (&y);
  2269. pPara->GetRightIndent(&z);
  2270. SetIndents(x, y, z);
  2271. pPara->GetLineSpacingRule(&Value);
  2272. pPara->GetLineSpacing(&y);
  2273. SetLineSpacing(Value, y);
  2274. pPara->GetNoLineNumber(&Value);
  2275. SetNoLineNumber(Value);
  2276. pPara->GetListAlignment(&Value);
  2277. SetListAlignment(Value);
  2278. pPara->GetListLevelIndex(&Value);
  2279. SetListLevelIndex(Value);
  2280. pPara->GetListStart(&Value);
  2281. SetListStart(Value);
  2282. pPara->GetListTab(&x);
  2283. SetListTab(x);
  2284. pPara->GetListType(&Value);
  2285. SetListType(Value);
  2286. pPara->GetPageBreakBefore(&Value);
  2287. SetPageBreakBefore(Value);
  2288. pPara->GetSpaceBefore(&y);
  2289. SetSpaceBefore(y);
  2290. pPara->GetSpaceAfter(&y);
  2291. SetSpaceAfter(y);
  2292. pPara->GetWidowControl(&Value);
  2293. SetWidowControl(Value);
  2294. ClearAllTabs();
  2295. pPara->GetTabCount(&Value);
  2296. for(iTab = 0; iTab < Value; iTab++)
  2297. {
  2298. pPara->GetTab(iTab, &tbPos, &tbAlign, &tbLeader);
  2299. AddTab(tbPos, tbAlign, tbLeader);
  2300. }
  2301. _prg = prg; // Restore original value
  2302. }
  2303. return FormatSetter(dwMask); // Apply it unless !_prg
  2304. }
  2305. /*
  2306. * ITextPara::SetKeepTogether(long Value)
  2307. *
  2308. * @mfunc
  2309. * Property put method that sets the tomBool that controls
  2310. * whether to keep the lines in a range together.
  2311. *
  2312. * @rdesc
  2313. * HRESULT = (if success) ? NOERROR :
  2314. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2315. */
  2316. STDMETHODIMP CTxtPara::SetKeepTogether (
  2317. long Value) //@parm New tomBool for keeping lines together
  2318. {
  2319. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetKeepTogether");
  2320. return EffectSetter(Value, PFM_KEEP);
  2321. }
  2322. /*
  2323. * ITextPara::SetKeepWithNext(long Value)
  2324. *
  2325. * @mfunc
  2326. * Property put method that sets the tomBool that controls
  2327. * whether to keep the paragraphs in a range together.
  2328. *
  2329. * @rdesc
  2330. * HRESULT = (if success) ? NOERROR :
  2331. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2332. */
  2333. STDMETHODIMP CTxtPara::SetKeepWithNext (
  2334. long Value) //@parm New tomBool for keeping paragraphs together
  2335. {
  2336. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetKeepWithNext");
  2337. return EffectSetter(Value, PFM_KEEPNEXT);
  2338. }
  2339. /*
  2340. * ITextPara::SetIndents(float First, float Left, float Right)
  2341. *
  2342. * @mfunc
  2343. * Method that sets the left indent of all but the first line
  2344. * of a paragraph equal to Left and sets the displacement of the first
  2345. * line of a paragraph relative to the left indent equal to First. The
  2346. * left indent value is relative to the left margin. You can also set
  2347. * the right indent by giving the optional Right parameter a value (the
  2348. * (default is tomUndefined). All indents are given in floating-point
  2349. * points.
  2350. *
  2351. * @rdesc
  2352. * HRESULT = (if success) ? NOERROR :
  2353. * (protected) ? E_ACCESSDENIED : E_INVALIDARG
  2354. */
  2355. STDMETHODIMP CTxtPara::SetIndents (
  2356. float First, //@parm New first indent (1st-line offset relative to left indent)
  2357. float Left, //@parm New left indent (left offset of all but 1st line)
  2358. float Right) //@parm New right indent (right offset of all lines)
  2359. {
  2360. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetIndents");
  2361. DWORD dwMask = 0;
  2362. LONG j = (First != tomFloatUndefined) + (Left == tomFloatUndefined);
  2363. if(IsZombie())
  2364. return CO_E_RELEASED;
  2365. if(j < 2) // At least First or Left
  2366. { // defined
  2367. if(j == 1) // Only one defined: need
  2368. UpdateFormat(); // current _PF._dxOffset
  2369. if(First != tomFloatUndefined)
  2370. {
  2371. j = FPPTS_TO_TWIPS(First);
  2372. if(Left == tomFloatUndefined)
  2373. {
  2374. _PF._dxStartIndent += _PF._dxOffset // Cancel current offset
  2375. + j; // and add in new one
  2376. }
  2377. _PF._dxOffset = -j; // Offset for all but 1st
  2378. dwMask = PFM_OFFSET + PFM_STARTINDENT; // line
  2379. }
  2380. if(Left != tomFloatUndefined)
  2381. {
  2382. _PF._dxStartIndent = FPPTS_TO_TWIPS(Left) - _PF._dxOffset;
  2383. dwMask |= PFM_STARTINDENT;
  2384. }
  2385. }
  2386. if(Right != tomFloatUndefined)
  2387. {
  2388. _PF._dxRightIndent = FPPTS_TO_TWIPS(Right);
  2389. dwMask |= PFM_RIGHTINDENT;
  2390. }
  2391. return dwMask ? FormatSetter(dwMask) : NOERROR;
  2392. }
  2393. /*
  2394. * ITextPara::SetLineSpacing(long Rule, float Spacing)
  2395. *
  2396. * @mfunc
  2397. * Method that sets the paragraph line spacing rule to Rule and
  2398. * the line spacing to Spacing. If the line spacing rule treats the
  2399. * Spacing value as a linear dimension, then that dimension is given in
  2400. * floating-point points.
  2401. *
  2402. * @rdesc
  2403. * HRESULT = (if success) ? NOERROR :
  2404. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2405. */
  2406. STDMETHODIMP CTxtPara::SetLineSpacing (
  2407. long Rule, //@parm Value of new line-spacing rule
  2408. float Spacing) //@parm Value of new line spacing
  2409. {
  2410. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetLineSpacing");
  2411. LONG j = (Rule == tomUndefined) + (Spacing == tomFloatUndefined);
  2412. if(j == 2)
  2413. return NOERROR;
  2414. if(j == 1 || (DWORD)Rule > 5 || Spacing < 0)
  2415. return E_INVALIDARG;
  2416. _PF._bLineSpacingRule = (BYTE)Rule; // Default as if both are OK
  2417. _PF._dyLineSpacing = (SHORT)FPPTS_TO_TWIPS(Spacing);
  2418. return FormatSetter(PFM_LINESPACING);
  2419. }
  2420. /*
  2421. * ITextPara::SetListAlignment (long Value)
  2422. *
  2423. * @mfunc
  2424. * Property put method that sets the kind of List alignment to be
  2425. * used for paragraphs.
  2426. *
  2427. * @rdesc
  2428. * HRESULT = (if success) ? NOERROR :
  2429. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2430. */
  2431. STDMETHODIMP CTxtPara::SetListAlignment(
  2432. long Value) //@parm Value of new list alignment
  2433. {
  2434. if(Value == tomUndefined)
  2435. return NOERROR;
  2436. if((unsigned)Value > tomAlignRight)
  2437. return E_INVALIDARG;
  2438. long Style;
  2439. HRESULT hr = GetParameter((long *)&_PF._wNumberingStyle,
  2440. PFM_NUMBERINGSTYLE, 2, &Style);
  2441. if(hr != NOERROR)
  2442. return hr;
  2443. return SetParameter((long *)&_PF._wNumberingStyle, PFM_NUMBERINGSTYLE,
  2444. 2, (Style & ~3) | (Value & 3));
  2445. }
  2446. /*
  2447. * ITextPara::SetListLevelIndex (long Value)
  2448. *
  2449. * @mfunc
  2450. * Property put method that sets the kind of list level index to be
  2451. * used for paragraphs.
  2452. *
  2453. * @rdesc
  2454. * HRESULT = (if success) ? NOERROR :
  2455. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2456. */
  2457. STDMETHODIMP CTxtPara::SetListLevelIndex(
  2458. long Value)
  2459. {
  2460. if(Value == tomUndefined)
  2461. return NOERROR;
  2462. if((unsigned)Value > 15)
  2463. return E_INVALIDARG;
  2464. long Style;
  2465. HRESULT hr = GetParameter((long *)&_PF._wNumberingStyle,
  2466. PFM_NUMBERINGSTYLE, 2, &Style);
  2467. if(hr != NOERROR)
  2468. return hr;
  2469. return SetParameter((long *)&_PF._wNumberingStyle, PFM_NUMBERINGSTYLE,
  2470. 2, (Style & ~0xf0) | (Value << 4));
  2471. }
  2472. /*
  2473. * ITextPara::SetListStart (long Value)
  2474. *
  2475. * @mfunc
  2476. * Property put method that sets the starting number to use for
  2477. * paragraph numbering
  2478. *
  2479. * @rdesc
  2480. * HRESULT = (if success) ? NOERROR :
  2481. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2482. */
  2483. STDMETHODIMP CTxtPara::SetListStart(
  2484. long Value) //@parm New numbering start value
  2485. {
  2486. if(Value == tomUndefined)
  2487. return NOERROR;
  2488. if(Value < 0)
  2489. return E_INVALIDARG;
  2490. return SetParameter((long *)&_PF._wNumberingStart, PFM_NUMBERINGSTART,
  2491. 2, Value);
  2492. }
  2493. /*
  2494. * ITextPara::SetListTab (long Value)
  2495. *
  2496. * @mfunc
  2497. * Property put method that sets the distance between the first indent
  2498. * and the start of text on the first line.
  2499. *
  2500. * @rdesc
  2501. * HRESULT = (if success) ? NOERROR :
  2502. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2503. */
  2504. STDMETHODIMP CTxtPara::SetListTab(
  2505. float Value) //@parm New numbering tab value
  2506. {
  2507. if(Value == tomFloatUndefined)
  2508. return NOERROR;
  2509. if(Value < 0)
  2510. return E_INVALIDARG;
  2511. return SetParameter((long *)&_PF._wNumberingTab, PFM_NUMBERINGTAB,
  2512. -2, *(long *)&Value);
  2513. }
  2514. /*
  2515. * ITextPara::SetListType (long Value)
  2516. *
  2517. * @mfunc
  2518. * Property put method that sets the kind of List to be
  2519. * used for paragraphs.
  2520. *
  2521. * @rdesc
  2522. * HRESULT = (if success) ? NOERROR :
  2523. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2524. */
  2525. STDMETHODIMP CTxtPara::SetListType (
  2526. long Value) //@parm New List code
  2527. {
  2528. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetListType");
  2529. if(Value == tomUndefined)
  2530. return NOERROR;
  2531. if((unsigned)Value > 0xf0000)
  2532. return E_INVALIDARG;
  2533. long Style;
  2534. HRESULT hr = GetParameter((long *)&_PF._wNumberingStyle,
  2535. PFM_NUMBERINGSTYLE, 2, &Style);
  2536. if(hr != NOERROR)
  2537. return hr;
  2538. _PF._wNumbering = (WORD)Value;
  2539. _PF._wNumberingStyle = (WORD)((Style & ~0x8F00) | ((Value >> 8) & 0x8F00));
  2540. return FormatSetter(PFM_NUMBERING | PFM_NUMBERINGSTYLE);
  2541. }
  2542. /*
  2543. * ITextPara::SetNoLineNumber (long Value)
  2544. *
  2545. * @mfunc
  2546. * Property put method that sets the tomBool that controls
  2547. * whether to suppress the numbering of paragraphs in a range.
  2548. *
  2549. * @rdesc
  2550. * HRESULT = (if success) ? NOERROR :
  2551. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2552. */
  2553. STDMETHODIMP CTxtPara::SetNoLineNumber (
  2554. long Value) //@parm New tomBool for suppressing line numbering
  2555. {
  2556. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetNoLineNumber");
  2557. return EffectSetter(Value, PFM_NOLINENUMBER);
  2558. }
  2559. /*
  2560. * ITextPara::SetPageBreakBefore (long Value)
  2561. *
  2562. * @mfunc
  2563. * Property put method that sets the tomBool that controls
  2564. * whether to eject the page before each paragraph in a range.
  2565. *
  2566. * @rdesc
  2567. * HRESULT = (if success) ? NOERROR :
  2568. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2569. */
  2570. STDMETHODIMP CTxtPara::SetPageBreakBefore (
  2571. long Value) //@parm New tomBool for ejecting page before paragraphs
  2572. {
  2573. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetPageBreakBefore");
  2574. return EffectSetter(Value, PFM_PAGEBREAKBEFORE);
  2575. }
  2576. /*
  2577. * ITextPara::SetRightIndent (float Value)
  2578. *
  2579. * @mfunc
  2580. * Property put method that sets the amount to indent the right
  2581. * margin of paragraph equal to Value, which is given in floating-point
  2582. * points.
  2583. *
  2584. * @rdesc
  2585. * HRESULT = (if success) ? NOERROR :
  2586. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2587. */
  2588. STDMETHODIMP CTxtPara::SetRightIndent (
  2589. float Value) //@parm New right indent
  2590. {
  2591. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetRightIndent");
  2592. return SetParameter(&_PF._dxRightIndent, PFM_RIGHTINDENT, -4,
  2593. *(long *)&Value);
  2594. }
  2595. /*
  2596. * ITextPara::SetSpaceAfter(float Value)
  2597. *
  2598. * @mfunc
  2599. * Property put method that sets the amount to space vertically
  2600. * after finishing a paragraph equal to Value, which is given in
  2601. * floating-point points.
  2602. *
  2603. * @rdesc
  2604. * HRESULT = (if success) ? NOERROR :
  2605. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2606. */
  2607. STDMETHODIMP CTxtPara::SetSpaceAfter (
  2608. float Value) //@parm New space-after value
  2609. {
  2610. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetSpaceAfter");
  2611. if(Value == tomFloatUndefined)
  2612. return NOERROR;
  2613. if(Value < 0)
  2614. return E_INVALIDARG;
  2615. return SetParameter(&_PF._dySpaceAfter, PFM_SPACEAFTER, -4,
  2616. *(long *)&Value);
  2617. }
  2618. /*
  2619. * ITextPara::SetSpaceBefore(float Value)
  2620. *
  2621. * @mfunc
  2622. * Property put method that sets the amount to space vertically
  2623. * before starting a paragraph equal to Value, which is given in
  2624. * floating-point points.
  2625. *
  2626. * @rdesc
  2627. * HRESULT = (if success) ? NOERROR :
  2628. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2629. */
  2630. STDMETHODIMP CTxtPara::SetSpaceBefore (
  2631. float Value) //@parm New space-before value
  2632. {
  2633. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetSpaceBefore");
  2634. if(Value == tomFloatUndefined)
  2635. return NOERROR;
  2636. if(Value < 0)
  2637. return E_INVALIDARG;
  2638. return SetParameter(&_PF._dySpaceBefore, PFM_SPACEBEFORE, -4,
  2639. *(long *)&Value);
  2640. }
  2641. /*
  2642. * ITextPara::SetStyle(long Value)
  2643. *
  2644. * @mfunc
  2645. * Property put method that sets the paragraph style handle for
  2646. * the paragraphs in a range. See GetStyle() for further discussion.
  2647. *
  2648. * @rdesc
  2649. * HRESULT = (if success) ? NOERROR :
  2650. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2651. */
  2652. STDMETHODIMP CTxtPara::SetStyle (
  2653. long Value) //@parm New paragraph style handle
  2654. {
  2655. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetStyle");
  2656. if(Value == tomUndefined)
  2657. return NOERROR;
  2658. if(Value < -32768 || Value > 32767)
  2659. return E_INVALIDARG;
  2660. return SetParameter((long *)&_PF._sStyle, PFM_STYLE, 2, Value);
  2661. }
  2662. /*
  2663. * ITextPara::SetWidowControl(long Value)
  2664. *
  2665. * @mfunc
  2666. * Property put method that sets the tomBool that controls the
  2667. * suppression of widows and orphans.
  2668. *
  2669. * @rdesc
  2670. * HRESULT = (if success) ? NOERROR :
  2671. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2672. */
  2673. STDMETHODIMP CTxtPara::SetWidowControl (
  2674. long Value) //@parm New tomBool for suppressing widows and orphans
  2675. {
  2676. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtPara::SetWidowControl");
  2677. return EffectSetter(Value, PFM_NOWIDOWCONTROL);
  2678. }
  2679. //----------------------------- CTxtFont Helpers -------------------------------------
  2680. /*
  2681. * @doc INTERNAL
  2682. *
  2683. * CTxtFont::EffectGetter (ptomBool, dwMask)
  2684. *
  2685. * @mfunc
  2686. * Set *<p ptomBool> = state of bit given by the bit mask <p dwMask>
  2687. *
  2688. * @rdesc
  2689. * HRESULT = (!<p ptomBool>) ? E_INVALIDARG : NOERROR
  2690. */
  2691. HRESULT CTxtFont::EffectGetter (
  2692. long * ptomBool, //@parm Out parm to receive tomBool
  2693. DWORD dwMask) //@parm Bit mask identifying effect to retrieve
  2694. {
  2695. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CTxtFont::EffectGetter");
  2696. if(!ptomBool)
  2697. return E_INVALIDARG;
  2698. HRESULT hr = UpdateFormat(); // If live Font object, update
  2699. // _CF to current _prg values
  2700. *ptomBool = !(_dwMask & dwMask) ? tomUndefined :
  2701. (_CF._dwEffects & dwMask) ? tomTrue : tomFalse;
  2702. return hr;
  2703. }
  2704. /*
  2705. * CTxtFont::EffectSetter (Value, dwMask, dwEffect)
  2706. *
  2707. * @mfunc
  2708. * Mask off this range's effect bits identified by <p dwMask> and set
  2709. * effect bit given by <p dwEffect> equal to value given by <p Value>
  2710. *
  2711. * @rdesc
  2712. * HRESULT = (if success) ? NOERROR : S_FALSE
  2713. */
  2714. HRESULT CTxtFont::EffectSetter (
  2715. long Value, //@parm Value to set effect bit to
  2716. DWORD dwMask, //@parm Bit mask identifying effect(s) to turn off
  2717. DWORD dwEffect) //@parm Effect bit to set
  2718. {
  2719. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CTxtFont::EffectSetter");
  2720. if(Value == tomUndefined) // Do nothing (NINCH)
  2721. return NOERROR;
  2722. if(Value == tomToggle)
  2723. {
  2724. if(_prg) // If live Font object, update
  2725. { // _CF.dwEffects for toggling
  2726. if(_prg->IsZombie())
  2727. return CO_E_RELEASED;
  2728. LONG iFormat = _prg->_iFormat; // Default iFormat for IP
  2729. LONG cch = _prg->GetCch();
  2730. if(cch) // Range is nondegenerate
  2731. {
  2732. CFormatRunPtr rp(_prg->_rpCF);
  2733. if(cch > 0) // Get iFormat at cpFirst
  2734. rp.Move(-cch);
  2735. iFormat = rp.GetFormat();
  2736. }
  2737. _CF._dwEffects = _prg->GetPed()->GetCharFormat(iFormat)->_dwEffects;
  2738. }
  2739. _CF._dwEffects ^= dwEffect; // Toggle effect(s)
  2740. if (dwMask != dwEffect)
  2741. {
  2742. // Need to turn off other bits that are not being toggle
  2743. DWORD dwTurnOff = dwMask ^ dwEffect;
  2744. _CF._dwEffects &= ~dwTurnOff;
  2745. }
  2746. }
  2747. else
  2748. {
  2749. _CF._dwEffects &= ~dwMask; // Default effect(s) off
  2750. if(Value)
  2751. {
  2752. if(Value != tomTrue)
  2753. return E_INVALIDARG;
  2754. _CF._dwEffects |= dwEffect; // Turn an effect on
  2755. }
  2756. }
  2757. return FormatSetter(dwMask);
  2758. }
  2759. /*
  2760. * CTxtFont::FormatSetter (dwMask)
  2761. *
  2762. * @mfunc
  2763. * Set this CCharFormat or _prg's with mask <p dwMask>
  2764. *
  2765. * @rdesc
  2766. * HRESULT = (if success) ? NOERROR : S_FALSE
  2767. * (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
  2768. */
  2769. HRESULT CTxtFont::FormatSetter (
  2770. DWORD dwMask) //@parm Mask for value
  2771. {
  2772. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CTxtFont::FormatSetter");
  2773. if(_prg && !_fApplyLater)
  2774. {
  2775. if (_fApplyToTmp)
  2776. _CF._sTmpDisplayAttrIdx = GetTmpDisplayAttrIdx(_tmpDisplayAttr);
  2777. HRESULT hr = _prg->CharFormatSetter(&_CF, dwMask, _fApplyToTmp ? CFM2_USETMPDISPATTR : 0);
  2778. if(hr != NOERROR)
  2779. return hr;
  2780. }
  2781. _dwMask |= dwMask; // Collect data in font clone
  2782. return NOERROR;
  2783. }
  2784. /*
  2785. * CTxtFont::GetParameter (pParm, dwMask, Type, pValue)
  2786. *
  2787. * @mfunc
  2788. * If _prg is defined (not clone), update _CF to range value.
  2789. * Set *pValue = *pParm unless NINCHed, in which case set it to
  2790. * Type < 0 ? tomFloatUndefined : tomUndefined. |Type| gives
  2791. * the byte length of the pParm field.
  2792. *
  2793. * @rdesc
  2794. * HRESULT = (if success) ? NOERROR : S_FALSE
  2795. */
  2796. HRESULT CTxtFont::GetParameter (
  2797. long * pParm, //@parm Address of _CF member to get
  2798. DWORD dwMask, //@parm _CF member mask for NINCH checking
  2799. long Type, //@parm # bytes of parameter or 0 for float
  2800. long * pValue) //@parm Out parm to receive value
  2801. {
  2802. UpdateFormat(); // If live Font object, update
  2803. // _CF to current _prg values
  2804. return CTxtFormat::GetParameter(pParm, _dwMask & dwMask, Type, pValue);
  2805. }
  2806. /*
  2807. * CTxtFont::SetParameter (pParm, dwMask, Type, Value)
  2808. *
  2809. * @mfunc
  2810. * Set parameter at address pParm with mask big dwMask to the value
  2811. * Value performing type conversions indicated by Type
  2812. *
  2813. * @rdesc
  2814. * HRESULT = (if success) ? NOERROR : S_FALSE
  2815. */
  2816. HRESULT CTxtFont::SetParameter (
  2817. long * pParm, //@parm Address of _CF member to get
  2818. DWORD dwMask, //@parm _CF member mask for NINCH checking
  2819. long Type, //@parm # bytes of parameter or 0 for float
  2820. long Value) //@parm Out parm to receive value
  2821. {
  2822. HRESULT hr = CTxtFormat::SetParameter(pParm, Type, Value);
  2823. return hr == NOERROR ? FormatSetter(dwMask) : hr;
  2824. }
  2825. /*
  2826. * CTxtFont::UpdateFormat ()
  2827. *
  2828. * @mfunc
  2829. * Update format if this font object is attached to a live range.
  2830. * Set _dwMask = 0 if attached to zombied range.
  2831. *
  2832. * @rdesc
  2833. * HRESULT = (attached to zombied range)
  2834. * ? CO_E_RELEASED : NOERROR
  2835. */
  2836. HRESULT CTxtFont::UpdateFormat ()
  2837. {
  2838. if(_prg && !_fCacheParms)
  2839. {
  2840. if(_prg->IsZombie())
  2841. {
  2842. _dwMask = 0; // Nothing defined
  2843. return CO_E_RELEASED;
  2844. }
  2845. _dwMask = _prg->GetCharFormat(&_CF);
  2846. }
  2847. return NOERROR;
  2848. }
  2849. //----------------------------- CTxtPara Helpers -------------------------------------
  2850. /*
  2851. * @doc INTERNAL
  2852. *
  2853. * CTxtPara::EffectGetter (ptomBool, dwMask)
  2854. *
  2855. * @mfunc
  2856. * Set *<p ptomBool> = state of bit given by the bit mask <p dwMask>
  2857. *
  2858. * @rdesc
  2859. * HRESULT = (!<p ptomBool>) ? E_INVALIDARG : NOERROR
  2860. */
  2861. HRESULT CTxtPara::EffectGetter (
  2862. long * ptomBool, //@parm Out parm to receive tomBool
  2863. DWORD dwMask) //@parm Bit mask identifying effect to retrieve
  2864. {
  2865. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CTxtPara::EffectGetter");
  2866. if(!ptomBool)
  2867. return E_INVALIDARG;
  2868. HRESULT hr = UpdateFormat(); // If live Para object, update
  2869. // _PF to current _prg values
  2870. *ptomBool = !(_dwMask & dwMask) ? tomUndefined :
  2871. (_PF._wEffects & (dwMask >> 16)) ? tomTrue : tomFalse;
  2872. return hr;
  2873. }
  2874. /*
  2875. * CTxtPara::EffectSetter (Value, dwMask)
  2876. *
  2877. * @mfunc
  2878. * Set this range's effect bit as given by <p dwMask> equal to value
  2879. * given by <p Value>
  2880. *
  2881. * @rdesc
  2882. * HRESULT = (if success) ? NOERROR : S_FALSE
  2883. *
  2884. * @devnote
  2885. * Note that the mask bits for paragraph effects are in the high word
  2886. * of _dwMask, but the effects are stored in the WORD _wEffects.
  2887. */
  2888. HRESULT CTxtPara::EffectSetter (
  2889. long Value, //@parm Value to set effect bit to
  2890. DWORD dwMask) //@parm Bit mask identifying effect to set
  2891. {
  2892. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CTxtPara::EffectSetter");
  2893. if(Value == tomUndefined) // Do nothing (NINCH)
  2894. return NOERROR;
  2895. DWORD dwEffects = _PF._wEffects << 16; // Move effects over to where
  2896. // mask is
  2897. if(Value == tomToggle)
  2898. {
  2899. if(_prg) // If live Para object, update
  2900. { // _PF._wEffects for toggling
  2901. if(_prg->IsZombie())
  2902. return CO_E_RELEASED;
  2903. _dwMask = _prg->GetParaFormat(&_PF, 0);
  2904. dwEffects = _PF._wEffects << 16;
  2905. _PF._iTabs = -1; // No interest in TABs here
  2906. }
  2907. if(_dwMask & dwMask) // Effect is defined:
  2908. dwEffects ^= dwMask; // toggle it
  2909. else // Effect is NINCHed
  2910. dwEffects &= ~dwMask; // Turn it all off
  2911. }
  2912. else
  2913. {
  2914. dwEffects &= ~dwMask; // Default effect off
  2915. if(Value)
  2916. {
  2917. if(Value != tomTrue)
  2918. return E_INVALIDARG;
  2919. dwEffects |= dwMask; // Turn it on
  2920. }
  2921. }
  2922. _PF._wEffects = (WORD)(dwEffects >> 16);
  2923. return FormatSetter(dwMask);
  2924. }
  2925. /*
  2926. * CTxtPara::FormatSetter (dwMask)
  2927. *
  2928. * @mfunc
  2929. * Set this CParaFormat or _prg's with mask <p dwMask>
  2930. *
  2931. * @rdesc
  2932. * HRESULT = (if success) ? NOERROR : S_FALSE
  2933. */
  2934. HRESULT CTxtPara::FormatSetter (
  2935. DWORD dwMask) //@parm Mask for value
  2936. {
  2937. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CTxtPara::FormatSetter");
  2938. AssertSz(_PF._iTabs < 0,
  2939. "CTxtPara::FormatSetter: illegal tabs index");
  2940. if(_prg && !_fApplyLater)
  2941. {
  2942. if(dwMask & PFM_TABSTOPS)
  2943. _PF._iTabs = GetTabsCache()->Cache(&_rgxTabs[0], _PF._bTabCount);
  2944. HRESULT hr = _prg->ParaFormatSetter(&_PF, dwMask);
  2945. CheckTabsAddRef();
  2946. if(hr != NOERROR)
  2947. return hr;
  2948. }
  2949. _dwMask |= dwMask; // Collect data in para clone
  2950. return NOERROR;
  2951. }
  2952. /*
  2953. * CTxtPara::GetParameter (pParm, dwMask, Type, pValue)
  2954. *
  2955. * @mfunc
  2956. * If _prg is defined (not clone), update _PF to range value.
  2957. * Set *pValue = *pParm unless NINCHed, in which case set it to
  2958. * Type < 0 ? tomFloatUndefined : tomUndefined. |Type| gives
  2959. * the byte length of the pParm field.
  2960. *
  2961. * @rdesc
  2962. * HRESULT = (if success) ? NOERROR : S_FALSE
  2963. */
  2964. HRESULT CTxtPara::GetParameter (
  2965. long * pParm, //@parm Address of _PF member to get
  2966. DWORD dwMask, //@parm _PF member mask for NINCH checking
  2967. long Type, //@parm # bytes of parameter or 0 for float
  2968. long * pValue) //@parm Out parm to receive value
  2969. {
  2970. UpdateFormat(); // If live Para object, update
  2971. // _PF to current _prg values
  2972. return CTxtFormat::GetParameter(pParm, _dwMask & dwMask, Type, pValue);
  2973. }
  2974. /*
  2975. * CTxtPara::SetParameter (pParm, dwMask, Type, Value)
  2976. *
  2977. * @mfunc
  2978. * Set parameter at address pParm with mask big dwMask to the value
  2979. * Value performing type conversions indicated by Type
  2980. *
  2981. * @rdesc
  2982. * HRESULT = (if success) ? NOERROR : S_FALSE
  2983. */
  2984. HRESULT CTxtPara::SetParameter (
  2985. long * pParm, //@parm Address of _PF member to get
  2986. DWORD dwMask, //@parm _PF member mask for NINCH checking
  2987. long Type, //@parm # bytes of parameter or 0 for float
  2988. long Value) //@parm Out parm to receive value
  2989. {
  2990. HRESULT hr = CTxtFormat::SetParameter(pParm, Type, Value);
  2991. return hr == NOERROR ? FormatSetter(dwMask) : hr;
  2992. }
  2993. /*
  2994. * CTxtPara::CheckTabsAddRef ()
  2995. *
  2996. * @mfunc
  2997. * Release Tabs reference
  2998. */
  2999. void CTxtPara::CheckTabsAddRef()
  3000. {
  3001. if(_PF._iTabs >= 0)
  3002. {
  3003. GetTabsCache()->Release(_PF._iTabs);
  3004. _PF._iTabs = -1;
  3005. }
  3006. }
  3007. /*
  3008. * CTxtPara::UpdateFormat ()
  3009. *
  3010. * @mfunc
  3011. * Update format if this para object is attached to a live range.
  3012. * Set _dwMask = 0 if attached to zombied range.
  3013. *
  3014. * @rdesc
  3015. * HRESULT = (attached to zombied range)
  3016. * ? CO_E_RELEASED : NOERROR
  3017. */
  3018. HRESULT CTxtPara::UpdateFormat ()
  3019. {
  3020. if(_prg && !_fCacheParms)
  3021. {
  3022. if(_prg->IsZombie())
  3023. {
  3024. _dwMask = 0; // Nothing defined
  3025. return CO_E_RELEASED;
  3026. }
  3027. _dwMask = _prg->GetParaFormat(&_PF, 0);
  3028. if(_PF._iTabs >= 0)
  3029. {
  3030. if(_PF.IsTableRowDelimiter())
  3031. _PF._bTabCount = 0;
  3032. else
  3033. CopyMemory(_rgxTabs, GetTabsCache()->Deref(_PF._iTabs),
  3034. _PF._bTabCount*sizeof(LONG));
  3035. _PF._iTabs = -1;
  3036. }
  3037. }
  3038. return NOERROR;
  3039. }
  3040. //---------------------------- CTxtFormat Methods --------------------------------
  3041. /*
  3042. * CTxtFormat::CTxtFormat(prg)
  3043. *
  3044. * @mfunc
  3045. * Constructor
  3046. */
  3047. CTxtFormat::CTxtFormat(CTxtRange *prg)
  3048. {
  3049. _cRefs = 1;
  3050. _prg = prg; // NULL for clone
  3051. if(prg)
  3052. prg->AddRef();
  3053. }
  3054. /*
  3055. * CTxtFormat::~CTxtFormat()
  3056. *
  3057. * @mfunc
  3058. * Destructor
  3059. */
  3060. CTxtFormat::~CTxtFormat()
  3061. {
  3062. if(_prg)
  3063. _prg->Release();
  3064. }
  3065. /*
  3066. * CTxtFormat::CanChange (pbCanChange)
  3067. *
  3068. * @func
  3069. * Set *<p pbCanChange> = tomTRUE iff this format object can be changed
  3070. *
  3071. * @rdesc
  3072. * HRESULT = (can change format) ? NOERROR : S_FALSE
  3073. *
  3074. * @devnote
  3075. * This method is shared by ITextFont and ITextPara. If pRange is NULL,
  3076. * the object is a clone, i.e., unattached to a CTxtRange
  3077. */
  3078. HRESULT CTxtFormat::CanChange (
  3079. long *pbCanChange, //@parm Out parm to receive boolean value
  3080. BOOL fPara) //@parm If TRUE, formatting is paragraphs
  3081. {
  3082. TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtFormat::CanChange");
  3083. LONG fCanChange = tomTrue;
  3084. if(_prg)
  3085. {
  3086. HRESULT hr = _prg->CanEdit(pbCanChange);
  3087. if(hr != NOERROR) // S_FALSE or CO_E_RELEASED
  3088. return hr;
  3089. if(!_prg->GetPed()->IsRich() && fPara)
  3090. fCanChange = tomFalse;
  3091. }
  3092. if(pbCanChange)
  3093. *pbCanChange = fCanChange;
  3094. return fCanChange ? NOERROR : S_FALSE;
  3095. }
  3096. /*
  3097. * CTxtFormat::GetParameter (pParm, fDefined, Type, pValue)
  3098. *
  3099. * @mfunc
  3100. * Set *pValue = *pLong unless NINCHed. Perform conversions specified by
  3101. * Type. If Type > 0, it is treated as length of an unsigned integer,
  3102. * i.e., 1, 2, or 4 bytes. If it is negative, the output is a float
  3103. * and the input has a length given by |Type|, so -2 converts a WORD
  3104. * into a float, unless dwMask = CFM_SPACING, in which case it converts
  3105. * a short into a float. -4 converts a long into a float.
  3106. *
  3107. * @rdesc
  3108. * HRESULT = (if success) ? NOERROR : S_FALSE
  3109. */
  3110. HRESULT CTxtFormat::GetParameter (
  3111. long * pParm, //@parm Ptr to _CF or _PF member to get
  3112. DWORD dwMask, //@parm Nonzero iff defined
  3113. long Type, //@parm # bytes of integer parameter or 0 for float
  3114. long * pValue) //@parm Out parm to receive value
  3115. {
  3116. if(!pValue)
  3117. return E_INVALIDARG;
  3118. Assert(pParm && sizeof(long) == 4 && sizeof(float) == 4);
  3119. HRESULT hr = NOERROR;
  3120. if(IsZombie()) // Check if attached to zombied
  3121. { // range
  3122. dwMask = 0; // Nothing defined
  3123. hr = CO_E_RELEASED; // Setup return for following if
  3124. }
  3125. if(!dwMask) // Parameter isn't defined
  3126. {
  3127. if(Type < 0)
  3128. *(float *)pValue = tomFloatUndefined;
  3129. else
  3130. *pValue = tomUndefined;
  3131. return hr;
  3132. }
  3133. *pValue = 0;
  3134. switch(Type) // Handle other cases
  3135. {
  3136. case 1: // BYTE quantity
  3137. *pValue = *(BYTE *)pParm;
  3138. break;
  3139. case 2: // WORD quantity
  3140. if(dwMask & (CFM_STYLE | PFM_STYLE))
  3141. *pValue = *(SHORT *)pParm; // Styles need sign extension
  3142. else
  3143. *pValue = *(WORD *)pParm;
  3144. break;
  3145. case -2: // float from WORD or SHORT
  3146. if(dwMask & (CFM_SPACING | CFM_SIZE // Need sign extension for these
  3147. | CFM_OFFSET)) // (in high word, so don't
  3148. *pValue = *(SHORT *)pParm; // conflict with PFM_xxx)
  3149. else
  3150. *pValue = *(WORD *)pParm;
  3151. goto TO_FLOAT;
  3152. case -4: // float from LONG
  3153. *pValue = *pParm;
  3154. TO_FLOAT:
  3155. *(float *)pValue = TWIPS_TO_FPPTS(*pValue);
  3156. break;
  3157. case 4:
  3158. *pValue = *pParm;
  3159. break;
  3160. #ifdef DEBUG
  3161. default:
  3162. AssertSz(FALSE, "CTxtFormat::GetParameter:: Unknown Type");
  3163. break;
  3164. #endif
  3165. }
  3166. return NOERROR;
  3167. }
  3168. /*
  3169. * CTxtFormat::SetParameter (pParm, fDefined, Type, Value)
  3170. *
  3171. * @mfunc
  3172. * Set *pParm = Value unless NINCHed. Perform conversions specified by
  3173. * Type. If Type > 0, it is treated as length of an unsigned integer,
  3174. * i.e., 1, 2, or 4 bytes. If it is negative, the output is a float
  3175. * and the input has a length given by |Type|, so -2 converts a WORD
  3176. * into a float, unless dwMask = CFM_SPACING, in which case it converts
  3177. * a short into a float. -4 converts a long into a float.
  3178. *
  3179. * @rdesc
  3180. * HRESULT = (if success) ? NOERROR : S_FALSE
  3181. */
  3182. HRESULT CTxtFormat::SetParameter (
  3183. long * pParm, //@parm Ptr to _CF or _PF member to set
  3184. long Type, //@parm # bytes of integer parameter or < 0 for float
  3185. long Value) //@parm New value for *pParm
  3186. {
  3187. Assert(pParm);
  3188. if(IsZombie()) // Check if attached to
  3189. return CO_E_RELEASED; // zombied range
  3190. if(Type > 0 && Value == tomUndefined) // Undefined parameter
  3191. return NOERROR; // NINCH
  3192. if(Type < 0) // Value is a float
  3193. {
  3194. if(*(float *)&Value == tomFloatUndefined) // Undefined parameter
  3195. return NOERROR; // NINCH
  3196. Type = -Type;
  3197. Value = FPPTS_TO_TWIPS(*(float *)&Value); // Convert to a long
  3198. }
  3199. if(Type == 1)
  3200. {
  3201. if((DWORD)Value > 255)
  3202. return E_INVALIDARG;
  3203. *(BYTE *)pParm = (BYTE)Value;
  3204. }
  3205. else if(Type == 2)
  3206. {
  3207. if(Value < -32768 || Value > 65535)
  3208. return E_INVALIDARG; // Doesn't fit in 16 bits
  3209. *(WORD *)pParm = (WORD)Value;
  3210. }
  3211. else
  3212. *pParm = Value;
  3213. return NOERROR;
  3214. }
  3215. /*
  3216. * CTxtFormat::IsTrue (f, pB)
  3217. *
  3218. * @mfunc
  3219. * Return *<p pB> = tomTrue iff <p f> is nonzero and pB isn't NULL
  3220. *
  3221. * @rdesc
  3222. * HRESULT = (f) ? NOERROR : S_FALSE
  3223. */
  3224. HRESULT CTxtFormat::IsTrue(BOOL f, long *pB)
  3225. {
  3226. if(pB)
  3227. *pB = tomFalse;
  3228. if(IsZombie()) // Check if attached to
  3229. return CO_E_RELEASED; // zombied range
  3230. if(f)
  3231. {
  3232. if(pB)
  3233. *pB = tomTrue;
  3234. return NOERROR;
  3235. }
  3236. return S_FALSE;
  3237. }