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.

361 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. polytext.cpp
  5. Abstract:
  6. This file implements the CPolyText Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "globals.h"
  13. #include "polytext.h"
  14. #include "fontlink.h"
  15. //+---------------------------------------------------------------------------
  16. //
  17. // CPolyText::SplitPolyStringAndAttr
  18. //
  19. //+---------------------------------------------------------------------------
  20. HRESULT
  21. CPolyText::SplitPolyStringAndAttr(
  22. IMCLock& imc,
  23. HDC hDC,
  24. POLYTEXTW poly_text,
  25. PBYTE pbAttrPtr,
  26. CCompClauseStore *compclause)
  27. {
  28. BYTE attr = *pbAttrPtr;
  29. PBYTE p = pbAttrPtr;
  30. UINT n = poly_text.n;
  31. UINT str_len = 0;
  32. //
  33. // Find different attribute
  34. //
  35. while (n)
  36. {
  37. if (compclause->IsAtFirstBoundary(str_len))
  38. {
  39. Assert(str_len);
  40. break;
  41. }
  42. --n;
  43. ++p;
  44. ++str_len;
  45. }
  46. CCompClauseStore compclauseTmp;
  47. compclauseTmp.Copy(compclause);
  48. compclauseTmp.Shift(str_len);
  49. INT_PTR index = m_poly_text.GetSize();
  50. if (n == 0)
  51. {
  52. if (poly_text.n)
  53. {
  54. SIZE size;
  55. FLGetTextExtentPoint32(hDC, poly_text.lpstr, poly_text.n, &size);
  56. if (!imc.UseVerticalCompWindow())
  57. {
  58. poly_text.rcl.right = poly_text.rcl.left + size.cx;
  59. }
  60. else
  61. {
  62. RotateSize(&size);
  63. poly_text.rcl.bottom = poly_text.rcl.top + size.cy;
  64. }
  65. }
  66. m_poly_text.SetAtGrow(index, poly_text);
  67. TfGuidAtom atom = TF_INVALID_GUIDATOM;
  68. CtfImeGetGuidAtom((HIMC)imc, *pbAttrPtr, &atom);
  69. m_TfGuidAtom.SetAtGrow(index, atom);
  70. }
  71. else
  72. {
  73. POLYTEXTW merge_poly = poly_text;
  74. n = poly_text.n;
  75. poly_text.n = str_len;
  76. SIZE size;
  77. FLGetTextExtentPoint32(hDC, poly_text.lpstr, poly_text.n, &size);
  78. if (!imc.UseVerticalCompWindow())
  79. {
  80. poly_text.rcl.right = poly_text.rcl.left + size.cx;
  81. }
  82. else
  83. {
  84. RotateSize(&size);
  85. poly_text.rcl.bottom = poly_text.rcl.top + size.cy;
  86. }
  87. m_poly_text.SetAtGrow(index, poly_text);
  88. TfGuidAtom atom = TF_INVALID_GUIDATOM;
  89. CtfImeGetGuidAtom((HIMC)imc, *pbAttrPtr, &atom);
  90. m_TfGuidAtom.SetAtGrow(index, atom);
  91. if (!imc.UseVerticalCompWindow())
  92. {
  93. merge_poly.x += size.cx;
  94. merge_poly.rcl.left += size.cx;
  95. }
  96. else
  97. {
  98. merge_poly.y += size.cy;
  99. merge_poly.rcl.top += size.cy;
  100. }
  101. merge_poly.n = n - str_len;
  102. merge_poly.lpstr = poly_text.lpstr + str_len;
  103. return SplitPolyStringAndAttr(imc, hDC, merge_poly, p, &compclauseTmp);
  104. }
  105. return S_OK;
  106. }
  107. //+---------------------------------------------------------------------------
  108. //
  109. // CPolyText::SplitPolyStringAndAttr
  110. //
  111. //+---------------------------------------------------------------------------
  112. HRESULT
  113. CPolyText::SplitPolyStringAndAttr(
  114. IMCLock& imc,
  115. HDC hDC,
  116. POLYTEXTW poly_text)
  117. {
  118. INT_PTR index = m_poly_text.GetSize();
  119. m_poly_text.SetAtGrow(index, poly_text);
  120. return S_OK;
  121. }
  122. //+---------------------------------------------------------------------------
  123. //
  124. // CPolyText::RemoveLastLine
  125. //
  126. //+---------------------------------------------------------------------------
  127. HRESULT
  128. CPolyText::RemoveLastLine(BOOL fVert)
  129. {
  130. INT_PTR n = m_poly_text.GetSize();
  131. if (n == 0)
  132. {
  133. return S_FALSE;
  134. }
  135. POLYTEXTW last_poly = m_poly_text.GetAt(n-1);
  136. //
  137. // Find the same Y line.
  138. //
  139. for (int index = 0; index < n; index++)
  140. {
  141. POLYTEXTW poly = m_poly_text.GetAt(index);
  142. if (!fVert && (poly.y == last_poly.y))
  143. break;
  144. else if (fVert && (poly.x == last_poly.x))
  145. break;
  146. }
  147. if (index >= n)
  148. {
  149. return E_FAIL;
  150. }
  151. m_poly_text.RemoveAt(index, (int)(n - index));
  152. m_TfGuidAtom.RemoveAt(index, (int)(n - index));
  153. return S_OK;
  154. }
  155. //+---------------------------------------------------------------------------
  156. //
  157. // CPolyText::ShiftPolyText
  158. //
  159. //+---------------------------------------------------------------------------
  160. HRESULT
  161. CPolyText::ShiftPolyText(int dx, int dy)
  162. {
  163. INT_PTR n = m_poly_text.GetSize();
  164. POLYTEXTW *ppoly_text = m_poly_text.GetData();
  165. INT_PTR i;
  166. for (i = 0; i < n; i++)
  167. {
  168. ppoly_text[i].x += dx;
  169. ppoly_text[i].y += dy;
  170. ppoly_text[i].rcl.left += dx;
  171. ppoly_text[i].rcl.right += dx;
  172. ppoly_text[i].rcl.top += dy;
  173. ppoly_text[i].rcl.bottom += dy;
  174. }
  175. return S_OK;
  176. }
  177. //+---------------------------------------------------------------------------
  178. //
  179. // CPolyText::GetPolyTextExtent
  180. //
  181. //+---------------------------------------------------------------------------
  182. HRESULT
  183. CPolyText::GetPolyTextExtent(POINT pt,
  184. HDC hDC,
  185. BOOL fVert,
  186. ULONG *puEdge,
  187. ULONG *puQuadrant)
  188. {
  189. INT_PTR n = m_poly_text.GetSize();
  190. POLYTEXTW *ppoly_text = m_poly_text.GetData();
  191. INT_PTR i;
  192. ULONG j;
  193. DWORD dwCount = 0;
  194. for (i = 0; i < n; i++)
  195. {
  196. if (ppoly_text[i].n && PtInRect(&ppoly_text[i].rcl, pt))
  197. {
  198. INT cxPoint;
  199. SIZE sizePrev = {0};
  200. if (!fVert)
  201. cxPoint = pt.x - ppoly_text[i].rcl.left;
  202. else
  203. cxPoint = pt.y - ppoly_text[i].rcl.top;
  204. for (j = 1; j <= ppoly_text[i].n; j++)
  205. {
  206. SIZE size;
  207. FLGetTextExtentPoint32(hDC,
  208. ppoly_text[i].lpstr,
  209. j,
  210. &size);
  211. if (cxPoint < size.cx)
  212. {
  213. DWORD dwOneCharWidth = size.cx - sizePrev.cx;
  214. ULONG uOneCharDist = cxPoint - sizePrev.cx;
  215. //
  216. // Calc Edge.
  217. //
  218. *puEdge += dwCount;
  219. if (uOneCharDist * 2 > dwOneCharWidth)
  220. (*puEdge)++;
  221. //
  222. // Calc Quadrant.
  223. //
  224. if (uOneCharDist)
  225. uOneCharDist--;
  226. *puQuadrant = ((uOneCharDist * 4 / dwOneCharWidth) + 2) % 4;
  227. return S_OK;
  228. }
  229. sizePrev = size;
  230. dwCount++;
  231. }
  232. }
  233. dwCount += ppoly_text[i].n;
  234. }
  235. *puEdge += dwCount;
  236. return S_FALSE;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // CPolyText::GetPolyTextExtentRect
  241. //
  242. //+---------------------------------------------------------------------------
  243. HRESULT
  244. CPolyText::GetPolyTextExtentRect(DWORD &ach,
  245. HDC hDC,
  246. BOOL fVert,
  247. BOOL fGetLastPoint,
  248. RECT *prc)
  249. {
  250. INT_PTR n = m_poly_text.GetSize();
  251. POLYTEXTW *ppoly_text = m_poly_text.GetData();
  252. INT_PTR i;
  253. ULONG j;
  254. DWORD dwCount = 0;
  255. for (i = 0; i < n; i++)
  256. {
  257. BOOL fTry = FALSE;
  258. if (!fGetLastPoint)
  259. {
  260. if ((ach >= dwCount) && (ach < dwCount + ppoly_text[i].n))
  261. fTry = TRUE;
  262. }
  263. else
  264. {
  265. if ((ach >= dwCount) && (ach <= dwCount + ppoly_text[i].n))
  266. fTry = TRUE;
  267. }
  268. if (fTry)
  269. {
  270. SIZE size;
  271. if (ach - dwCount)
  272. {
  273. FLGetTextExtentPoint32(hDC,
  274. ppoly_text[i].lpstr,
  275. ach - dwCount,
  276. &size);
  277. }
  278. else
  279. {
  280. size.cx = 0;
  281. size.cy = 0;
  282. }
  283. if (!fVert)
  284. {
  285. prc->left = ppoly_text[i].rcl.left + size.cx;
  286. prc->right = ppoly_text[i].rcl.left + size.cx;
  287. prc->top = ppoly_text[i].rcl.top;
  288. prc->bottom = ppoly_text[i].rcl.bottom;
  289. }
  290. else
  291. {
  292. prc->left = ppoly_text[i].rcl.left;
  293. prc->right = ppoly_text[i].rcl.right;
  294. prc->top = ppoly_text[i].rcl.top + size.cx;
  295. prc->bottom = ppoly_text[i].rcl.top + size.cx;
  296. }
  297. return S_OK;
  298. }
  299. dwCount += ppoly_text[i].n;
  300. }
  301. ach -= dwCount;
  302. return S_FALSE;
  303. }