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

154 lines
3.8 KiB

  1. #include "lsidefs.h"
  2. #include "lstfset.h"
  3. // %%Function: LsPointUV2FromPointUV1
  4. // %%Contact: victork
  5. //
  6. LSERR WINAPI LsPointUV2FromPointUV1(LSTFLOW lstflow1, /* IN: text flow 1 */
  7. PCPOINTUV pptStart, /* IN: start input point (TF1) */
  8. PCPOINTUV pptEnd, /* IN: end input point (TF1) */
  9. LSTFLOW lstflow2, /* IN: text flow 2 */
  10. PPOINTUV pptOut) /* OUT: vector in TF2 */
  11. {
  12. Assert(lstflowES == 0);
  13. Assert(lstflowEN == 1);
  14. Assert(lstflowSE == 2);
  15. Assert(lstflowSW == 3);
  16. Assert(lstflowWS == 4);
  17. Assert(lstflowWN == 5);
  18. Assert(lstflowNE == 6);
  19. Assert(lstflowNW == 7);
  20. // The three bits that constitute lstflow happens to have well defined meanings.
  21. //
  22. // Middle bit: on for vertical writing, off for horizontal.
  23. // First (low value) bit: "on" means v-axis points right or down (positive).
  24. // Third bit: "off" means u-axis points right or down (positive).
  25. //
  26. // So the algorithm of covertion (u1,v1) in lstflow1 to (u2,v2) in lstflow2 is:
  27. //
  28. // fHorizontalOrVertical1 = lstflow1 & fUVertical;
  29. // fUPositive1 = !(lstflow1 & fUDirection);
  30. // fVPositive1 = lstflow1 & fVDirection;
  31. // fHorizontalOrVertical2 = lstflow2 & fUVertical;
  32. // fUPositive2 = !(lstflow2 & fUDirection);
  33. // fVPositive2 = lstflow2 & fVDirection;
  34. //
  35. //
  36. // if (fHorizontalOrVertical1 == fHorizontalOrVertical2)
  37. // {
  38. // if (fUPositive1 == fUPositive2)
  39. // {
  40. // u2 = u1;
  41. // }
  42. // else
  43. // {
  44. // u2 = -u1;
  45. // }
  46. // if (fVPositive1 == fVPositive2)
  47. // {
  48. // v2 = v1;
  49. // }
  50. // else
  51. // {
  52. // v2 = -v1;
  53. // }
  54. // }
  55. // else
  56. // {
  57. // if (fUPositive1 == fVPositive2)
  58. // {
  59. // u2 = v1;
  60. // }
  61. // else
  62. // {
  63. // u2 = -v1;
  64. // }
  65. // if (fVPositive1 == fUPositive2)
  66. // {
  67. // v2 = u1;
  68. // }
  69. // else
  70. // {
  71. // v2 = -u1;
  72. // }
  73. // }
  74. //
  75. // Actual code is a little bit more compact.
  76. //
  77. // A hack (?): (!a == !b) is used instead of (((a==0) && (b==0)) || ((a!=0) && (b!=0)))
  78. if ((lstflow1 ^ lstflow2) & fUVertical) // one is vertical, another is horizontal
  79. {
  80. pptOut->u = (pptEnd->v - pptStart->v) *
  81. ((!(lstflow2 & fUDirection) == !(lstflow1 & fVDirection)) ? -1 : 1);
  82. pptOut->v = (pptEnd->u - pptStart->u) *
  83. ((!(lstflow2 & fVDirection) == !(lstflow1 & fUDirection)) ? -1 : 1);
  84. }
  85. else
  86. {
  87. pptOut->u = (pptEnd->u - pptStart->u) *
  88. (((lstflow1 ^ lstflow2) & fUDirection) ? -1 : 1);
  89. pptOut->v = (pptEnd->v - pptStart->v) *
  90. (((lstflow1 ^ lstflow2) & fVDirection) ? -1 : 1);
  91. }
  92. return lserrNone;
  93. }
  94. // %%Function: LsPointXYFromPointUV
  95. // %%Contact: victork
  96. //
  97. /* returns (x,y) point given (x,y) point and (u,v) vector */
  98. LSERR WINAPI LsPointXYFromPointUV(const POINT* pptXY, /* IN: input point (x,y) */
  99. LSTFLOW lstflow, /* IN: text flow for */
  100. PCPOINTUV pptUV, /* IN: vector in (u,v) */
  101. POINT* pptXYOut) /* OUT: point (x,y) */
  102. {
  103. switch (lstflow)
  104. {
  105. case lstflowES: /* latin */
  106. pptXYOut->x = pptXY->x + pptUV->u;
  107. pptXYOut->y = pptXY->y - pptUV->v;
  108. return lserrNone;
  109. case lstflowSW: /* vertical FE */
  110. pptXYOut->x = pptXY->x + pptUV->v;
  111. pptXYOut->y = pptXY->y + pptUV->u;
  112. return lserrNone;
  113. case lstflowWS: /* BiDi */
  114. pptXYOut->x = pptXY->x - pptUV->u;
  115. pptXYOut->y = pptXY->y - pptUV->v;
  116. return lserrNone;
  117. case lstflowEN:
  118. pptXYOut->x = pptXY->x + pptUV->u;
  119. pptXYOut->y = pptXY->y + pptUV->v;
  120. return lserrNone;
  121. case lstflowSE:
  122. pptXYOut->x = pptXY->x - pptUV->v;
  123. pptXYOut->y = pptXY->y + pptUV->u;
  124. return lserrNone;
  125. case lstflowWN:
  126. pptXYOut->x = pptXY->x - pptUV->u;
  127. pptXYOut->y = pptXY->y + pptUV->v;
  128. return lserrNone;
  129. case lstflowNE:
  130. pptXYOut->x = pptXY->x - pptUV->v;
  131. pptXYOut->y = pptXY->y - pptUV->u;
  132. return lserrNone;
  133. case lstflowNW:
  134. pptXYOut->x = pptXY->x + pptUV->v;
  135. pptXYOut->y = pptXY->y - pptUV->u;
  136. return lserrNone;
  137. default:
  138. NotReached();
  139. return lserrInvalidParameter;
  140. }
  141. }