Leaked source code of windows server 2003
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.

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