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.

456 lines
10 KiB

  1. //// Style - simple character styles for formatted text
  2. //
  3. // Provides a simple style selection mechanism for demostrating
  4. // formatted text.
  5. #include "precomp.hxx"
  6. #include "global.h"
  7. #include <tchar.h>
  8. /*
  9. void SetLogFont(
  10. PLOGFONTA plf,
  11. int iHeight,
  12. int iWeight,
  13. int iItalic,
  14. int iUnderline,
  15. char *pcFaceName) {
  16. memset(plf, 0, sizeof(LOGFONTA));
  17. plf->lfCharSet = DEFAULT_CHARSET;
  18. plf->lfHeight = iHeight;
  19. plf->lfWeight = iWeight;
  20. plf->lfItalic = (BYTE) iItalic;
  21. plf->lfUnderline = (BYTE) iUnderline;
  22. lstrcpy(plf->lfFaceName, pcFaceName);
  23. plf->lfOutPrecision = OUT_STROKE_PRECIS;
  24. plf->lfClipPrecision = CLIP_STROKE_PRECIS;
  25. plf->lfQuality = DRAFT_QUALITY;
  26. plf->lfPitchAndFamily = VARIABLE_PITCH;
  27. plf->lfEscapement = 0;
  28. plf->lfOrientation = 0;
  29. }
  30. */
  31. void FreeStyle(int iStyle) {
  32. /*
  33. if (g_style[iStyle].hf) {
  34. DeleteObject(g_style[iStyle].hf);
  35. }
  36. if (g_style[iStyle].sc) {
  37. ScriptFreeCache(&g_style[iStyle].sc);
  38. }
  39. */
  40. }
  41. void SetStyle(
  42. int iStyle,
  43. int iHeight,
  44. int iWeight,
  45. int iItalic,
  46. int iUnderline,
  47. int iStrikeout,
  48. TCHAR *pcFaceName) {
  49. LOGFONTA lf;
  50. FreeStyle(iStyle);
  51. //SetLogFont(&lf, iHeight, iWeight, iItalic, iUnderline, pcFaceName);
  52. //g_style[iStyle].hf = CreateFontIndirect(&lf);
  53. //g_style[iStyle].sc = NULL;
  54. g_style[iStyle].emSize = REAL(iHeight);
  55. for (UINT i=0; i<_tcslen(pcFaceName); i++)
  56. {
  57. g_style[iStyle].faceName[i] = pcFaceName[i];
  58. }
  59. g_style[iStyle].faceName[_tcslen(pcFaceName)] = 0;
  60. g_style[iStyle].style =
  61. (iWeight >= 700 ? FontStyleBold : 0)
  62. + (iItalic ? FontStyleItalic : 0)
  63. + (iUnderline ? FontStyleUnderline : 0)
  64. + (iStrikeout ? FontStyleStrikeout : 0);
  65. }
  66. void InitStyles() {
  67. memset(g_style, 0, sizeof(g_style));
  68. }
  69. void FreeStyles() {
  70. int i;
  71. for (i=0; i<5; i++) {
  72. FreeStyle(i);
  73. }
  74. }
  75. //// StyleCheckRange - dir use in ASSERTs
  76. //
  77. // Returns TRUE if style length matches text length
  78. BOOL StyleCheckRange() {
  79. int iFormatPos;
  80. RUN *pFormatRider;
  81. // Check that style length is same as text length
  82. pFormatRider = g_pFirstFormatRun;
  83. iFormatPos = 0;
  84. while (pFormatRider != NULL) {
  85. iFormatPos += pFormatRider->iLen;
  86. pFormatRider = pFormatRider->pNext;
  87. }
  88. return iFormatPos == g_iTextLen;
  89. }
  90. ///// Style range manipulation
  91. //
  92. // StyleDeleteRange
  93. // StyleExtendRange
  94. // StyleSetRange
  95. //
  96. // The style list is a linked list of RUNs (see global.h) that
  97. // covers the entire text buffer.
  98. //
  99. // Each run has a length, and a style number (an index to g_Style[])
  100. // (The analysis field in the run is not used by the style list.)
  101. //
  102. // StyleDeleteRange and StyleExtendRange are called as part of text
  103. // insertion/deletion to maintain the style list.
  104. //
  105. // StyleSetRange is called to change the style of the current selection
  106. // when the user clicks on one the of the numbered style buttons.
  107. /// StyleDeleteRange - delete range of style information
  108. //
  109. //
  110. void StyleDeleteRange(
  111. int iDelPos,
  112. int iDelLen) {
  113. int iFormatPos;
  114. RUN *pFormatRider;
  115. RUN *pPrevRun;
  116. RUN *pDelRun; // Run to be deleted
  117. if (iDelLen <= 0) return;
  118. // Find first run affected by the deletion
  119. iFormatPos = 0;
  120. pFormatRider = g_pFirstFormatRun;
  121. pPrevRun = NULL;
  122. while (iFormatPos + pFormatRider->iLen <= iDelPos) {
  123. iFormatPos += pFormatRider->iLen;
  124. pPrevRun = pFormatRider;
  125. pFormatRider = pFormatRider->pNext;
  126. ASSERT(pFormatRider);
  127. }
  128. // Delete from end of first run
  129. if (iDelPos + iDelLen > iFormatPos + pFormatRider->iLen) {
  130. // Delete all the way from iDelPos to the end of the first affected run
  131. iDelLen = iDelPos + iDelLen - (iFormatPos + pFormatRider->iLen); // Amount that will remain to be deleted
  132. pFormatRider->iLen = iDelPos - iFormatPos;
  133. } else {
  134. // Deletion is entirely in the first affected run
  135. pFormatRider->iLen -= iDelLen;
  136. iDelLen = 0;
  137. }
  138. // First affected run now contains no range to be deleted
  139. // If it's empty, remove it, otherwise step over it
  140. if (pFormatRider->iLen == 0) {
  141. // Remove redundant run
  142. if (pFormatRider->pNext) {
  143. // Replace this run by the next one
  144. pDelRun = pFormatRider->pNext;
  145. *pFormatRider = *pDelRun; // Copy content of next run over this one
  146. delete pDelRun;
  147. } else {
  148. // No runs following this one
  149. if (pPrevRun) {
  150. ASSERT(iDelLen == 0);
  151. delete pFormatRider;
  152. pPrevRun->pNext = NULL;
  153. } else {
  154. // No runs left at all
  155. ASSERT(iDelLen == 0);
  156. delete pFormatRider;
  157. g_pFirstFormatRun = NULL;
  158. }
  159. }
  160. } else {
  161. // Current run now contains no text to be deleted, so advance to next run
  162. iFormatPos += pFormatRider->iLen;
  163. pPrevRun = pFormatRider;
  164. pFormatRider = pFormatRider->pNext;
  165. }
  166. // Delete from start of any remaining runs
  167. while (iDelLen > 0) {
  168. if (pFormatRider->iLen <= iDelLen) {
  169. // This entire run must go
  170. ASSERT(pFormatRider->pNext);
  171. iDelLen -= pFormatRider->iLen;
  172. pDelRun = pFormatRider->pNext;
  173. *pFormatRider = *pDelRun;
  174. delete pDelRun;
  175. } else {
  176. // Last run is deleted in part only
  177. pFormatRider->iLen -= iDelLen;
  178. iDelLen = 0;
  179. }
  180. }
  181. // Check whether current run (which immediately follows deletion) can
  182. // now be collapsed into the previous run
  183. if (pPrevRun && pFormatRider && pPrevRun->iStyle == pFormatRider->iStyle) {
  184. pPrevRun->iLen += pFormatRider->iLen;
  185. pPrevRun->pNext = pFormatRider->pNext;
  186. delete pFormatRider;
  187. }
  188. }
  189. /// StyleExtendRange - Extend style immediately preceeding iPos by iLen characters
  190. //
  191. //
  192. void StyleExtendRange(
  193. int iExtPos,
  194. int iExtLen) {
  195. int iFormatPos;
  196. RUN *pFormatRider;
  197. const SCRIPT_ANALYSIS nullAnalysis = {0};
  198. if (g_pFirstFormatRun == NULL) {
  199. // Starting from no text at all
  200. ASSERT(iExtPos == 0);
  201. g_pFirstFormatRun = new RUN;
  202. g_pFirstFormatRun->iLen = iExtLen;
  203. g_pFirstFormatRun->iStyle = 1;
  204. g_pFirstFormatRun->pNext = NULL;
  205. g_pFirstFormatRun->analysis = nullAnalysis;
  206. } else {
  207. // Find run containing character immediately prior to iExtPos
  208. iFormatPos = 0;
  209. pFormatRider = g_pFirstFormatRun;
  210. while (iFormatPos + pFormatRider->iLen < iExtPos) {
  211. iFormatPos += pFormatRider->iLen;
  212. pFormatRider = pFormatRider->pNext;
  213. }
  214. pFormatRider->iLen += iExtLen;
  215. }
  216. }
  217. //// StyleSetRange - Change style for a given range
  218. //
  219. //
  220. void StyleSetRange(
  221. int iSetStyle,
  222. int iSetPos,
  223. int iSetLen) {
  224. int iFormatPos;
  225. RUN *pFormatRider;
  226. RUN *pNewRun;
  227. if (iSetLen <= 0) return;
  228. // Remove existing style for the range
  229. StyleDeleteRange(iSetPos, iSetLen);
  230. if (g_pFirstFormatRun == NULL) {
  231. // Replace style on entire text
  232. g_pFirstFormatRun = new RUN;
  233. g_pFirstFormatRun->pNext = NULL;
  234. g_pFirstFormatRun->iLen = iSetLen;
  235. g_pFirstFormatRun->iStyle = iSetStyle;
  236. } else {
  237. // Find first run affected by the change
  238. iFormatPos = 0;
  239. pFormatRider = g_pFirstFormatRun;
  240. while (iFormatPos + pFormatRider->iLen < iSetPos) {
  241. iFormatPos += pFormatRider->iLen;
  242. pFormatRider = pFormatRider->pNext;
  243. ASSERT(pFormatRider);
  244. }
  245. // New style starts after beginning of this run or at beginning of next run
  246. if (pFormatRider->iStyle == iSetStyle) {
  247. // Already the same style - just increase length
  248. pFormatRider->iLen += iSetLen;
  249. } else {
  250. if (iFormatPos + pFormatRider->iLen > iSetPos) {
  251. // New style is within this run
  252. // Split this run around the new run
  253. pNewRun = new RUN; // Create second part of existing run
  254. *pNewRun = *pFormatRider;
  255. pNewRun->iLen -= iSetPos - iFormatPos;
  256. pFormatRider->iLen = iSetPos - iFormatPos;
  257. pFormatRider->pNext = pNewRun;
  258. pNewRun = new RUN; // Create inserted run
  259. *pNewRun = *pFormatRider;
  260. pNewRun->iLen = iSetLen;
  261. pNewRun->iStyle = iSetStyle;
  262. pFormatRider->pNext = pNewRun;
  263. } else {
  264. // New style is between this run and the next run
  265. if ( pFormatRider->pNext
  266. && pFormatRider->pNext->iStyle == iSetStyle) {
  267. // New style is same as adjacent following run
  268. pFormatRider->pNext->iLen += iSetLen;
  269. } else {
  270. // Create new run between current run and next run
  271. pNewRun = new RUN;
  272. *pNewRun = *pFormatRider;
  273. pNewRun->iStyle = iSetStyle;
  274. pNewRun->iLen = iSetLen;
  275. pFormatRider->pNext = pNewRun;
  276. }
  277. }
  278. }
  279. }
  280. }