cdrapp.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include "cdrapp.h"
  2. #include <stdio.h>
  3. #define _USE_MATH_DEFINES
  4. #include <math.h> // C++ 在 math.h 中定义 M_PI 需要 _USE_MATH_DEFINES 宏
  5. void BeginOpt(corel *cdr) {
  6. auto name = _bstr_t("Undo");
  7. cdr->EventsEnabled = false;
  8. cdr->ActiveDocument->BeginCommandGroup(name);
  9. cdr->ActiveDocument->Unit = cdrMillimeter;
  10. cdr->Optimization = true;
  11. }
  12. void EndOpt(corel *cdr) {
  13. cdr->EventsEnabled = true;
  14. cdr->Optimization = false;
  15. cdr->EventsEnabled = true;
  16. cdr->ActiveDocument->ReferencePoint = cdrBottomLeft;
  17. cdr->Application->Refresh();
  18. cdr->ActiveDocument->EndCommandGroup();
  19. }
  20. bool isDPCurve(IVGShapePtr s) {
  21. auto dpc = (s->Type == cdrRectangleShape) || (s->Type == cdrEllipseShape) ||
  22. (s->Type == cdrCurveShape) || (s->Type == cdrPolygonShape) ||
  23. (s->Type == cdrBitmapShape);
  24. return dpc;
  25. }
  26. IVGShapePtr CreateBoundary(corel *cdr, IVGShapePtr s) {
  27. auto scp = s->CreateBoundary(0, 0, true, false);
  28. // 这个 API X7 以上才支持,所以现在直接画矩形
  29. // BoundingBox box;
  30. // s->GET_BOUNDING_BOX(box);
  31. // auto scp = cdr->ActiveLayer->CreateRectangle2(box.x, box.y, box.w, box.h,
  32. // ZERO_4PC);
  33. return scp;
  34. }
  35. // 从矩形边界坐标 获得中心坐标
  36. void calculate_center(const BoundingBox *box, double *center_x,
  37. double *center_y) {
  38. *center_x = box->x + (box->w / 2);
  39. *center_y = box->y + (box->h / 2);
  40. }
  41. // VGCore::cdrPositionOfPointOverShape VGCore::IVGShape::IsOnShape ( double x,
  42. // double y, double HotArea ); VGCore::cdrPositionOfPointOverShape
  43. // VGCore::IVGCurve::IsOnCurve ( double x, double y, double HotArea );
  44. bool BoundaryGroup(corel *cdr, IVGShapeRange *sr, IVGShapeRange *srs) {
  45. if (sr->Count < 2)
  46. return false;
  47. BoundingBox box;
  48. double x, y;
  49. int OnSh = 0;
  50. auto bounds = sr->CreateBoundary(0, 0, true, false); // 建立异性边界物件
  51. bounds->Fill->UniformColor->RGBAssign(255, 0, 0); // 填充红色
  52. auto sbox = bounds->BreakApartEx(); // 把边界 拆分为多个边界 用来分组
  53. auto srgp = cdr->CreateShapeRange();
  54. for (int k = 0; k < sbox->Count; k++) {
  55. for (int i = 0; i < sr->Count; i++) {
  56. auto sh = sr->Shapes->Item[i + 1];
  57. sh->GET_BOUNDING_BOX(box); // 获得物件矩形边界坐标
  58. calculate_center(&box, &x, &y); // 获得物件中心坐标
  59. OnSh = sbox->Shapes->Item[k + 1]->IsOnShape(x, y, -1);
  60. if (OnSh) {
  61. srgp->Add(sh);
  62. } else if (isIntWith(cdr, sbox->Shapes->Item[k + 1], sh)) {
  63. srgp->Add(sh);
  64. }
  65. }
  66. // 从Range中移除已分组的图形
  67. sr->RemoveRange(srgp);
  68. srs->Add(srgp->Group());
  69. srgp->RemoveAll();
  70. }
  71. sbox->Delete();
  72. return true;
  73. }
  74. void test_IsOnShape(corel *cdr) {
  75. BeginOpt(cdr);
  76. auto sr = cdr->ActiveSelectionRange;
  77. auto srs = cdr->CreateShapeRange();
  78. BoundaryGroup(cdr, sr, srs);
  79. srs->CreateSelection();
  80. EndOpt(cdr);
  81. }
  82. // VGCore::IVGShapePtr VGCore::IVGShape::CreateBoundary ( double x, double y,
  83. // VARIANT_BOOL PlaceOnTop, VARIANT_BOOL DeleteSource ); VGCore::IVGShapePtr
  84. // VGCore::IVGShapeRange::CreateBoundary ( double x, double y, VARIANT_BOOL
  85. // PlaceOnTop, VARIANT_BOOL DeleteSource ); VARIANT_BOOL
  86. // VGCore::IVGCurve::IntersectsWith ( struct IVGCurve * Curve )
  87. bool isIntWith(corel *cdr, IVGShape *s1, IVGShape *s2) {
  88. bool isIn = false;
  89. if (isDPCurve(s1) && isDPCurve(s2)) {
  90. isIn = s1->GetDisplayCurve()->IntersectsWith(s2->GetDisplayCurve());
  91. } else if (isDPCurve(s1)) {
  92. // 群组文字和OLE等其他类型,创建一个临时边界范围
  93. auto scp = CreateBoundary(cdr, s2);
  94. isIn = s1->GetDisplayCurve()->IntersectsWith(scp->GetDisplayCurve());
  95. scp->Delete();
  96. } else if (isDPCurve(s2)) {
  97. auto scp = CreateBoundary(cdr, s1);
  98. isIn = scp->GetDisplayCurve()->IntersectsWith(s2->GetDisplayCurve());
  99. scp->Delete();
  100. } else {
  101. auto scp = CreateBoundary(cdr, s1);
  102. auto scp2 = CreateBoundary(cdr, s2);
  103. isIn = scp->GetDisplayCurve()->IntersectsWith(scp2->GetDisplayCurve());
  104. scp->Delete();
  105. scp2->Delete();
  106. }
  107. return isIn;
  108. }
  109. bool Test_Intersect(corel *cdr) {
  110. cdr->ActiveDocument->Unit = cdrInch;
  111. IVGShapePtr s[3];
  112. IVGShapePtr si[3];
  113. IVGShapePtr sm;
  114. double x, y, radius = 1.5;
  115. int r, g, b;
  116. // 通过将 i 乘以 2.09439507 (120度的弧度),可以将三个椭圆均匀地分布在一个圆上。
  117. // radius = 1.5 则是决定椭圆的大小。 这个数字控制椭圆的半径,也就是椭圆的大小。
  118. // // 创建3个椭圆, 填色 RGB:
  119. for (int i = 0; i != 3; i++) {
  120. x = cdr->ActivePage->SizeWidth / 2 + 1 * cos(i * M_PI * 2.0 / 3.0);
  121. y = cdr->ActivePage->SizeHeight / 2 + 1 * sin(i * M_PI * 2.0 / 3.0);
  122. s[i] = MakeEllipse(cdr, x, y, radius);
  123. r = 255 * (i == 0);
  124. g = 255 * (i == 1);
  125. b = 255 * (i == 2);
  126. s[i]->Fill->UniformColor->RGBAssign(r, g, b);
  127. }
  128. // 创建3个相交物件, IVGShape::Intersect 函数原型
  129. // IVGShapePtr IVGShape::Intersect ( struct IVGShape * TargetShape,
  130. // VARIANT_BOOL LeaveSource, VARIANT_BOOL LeaveTarget );
  131. for (int i = 0; i != 3; i++) {
  132. int n = (i + 1) % 3;
  133. si[i] = s[i]->Intersect(s[n], true, true);
  134. auto c1 = s[i]->Fill->UniformColor;
  135. auto c2 = s[n]->Fill->UniformColor;
  136. r = c1->RGBRed + c2->RGBRed;
  137. g = c1->RGBGreen + c2->RGBGreen;
  138. b = c1->RGBBlue + c2->RGBBlue;
  139. si[i]->Fill->UniformColor->RGBAssign(r, g, b);
  140. }
  141. // 建立相交物件,填充白色
  142. sm = si[1]->Intersect(si[2], true, true);
  143. auto c3 = cdr->CreateRGBColor(255, 255, 255);
  144. sm->Fill->UniformColor = c3;
  145. return true;
  146. }
  147. bool polygon_gravity_dot(corel *cdr) {
  148. cdr->ActiveDocument->Unit = cdrMillimeter;
  149. double x, y;
  150. // IVGShapePtr ActiveShape; // 获取当前选中的图形 函数原型
  151. auto s = cdr->ActiveShape;
  152. // IVGShapeRangePtr IVGApplication::CreateShapeRange ( );
  153. auto srs = cdr->CreateShapeRange();
  154. // 获取节点函数原型
  155. // IVGNodePtr IVGNodes::GetItem ( long Index );
  156. // IVGNodePtr IVGNodeRange::GetItem ( long Index );
  157. for (auto i = 0; i < s->DisplayCurve->Nodes->Count; i++) {
  158. auto n = s->DisplayCurve->Nodes->Item[i + 1];
  159. x = n->PositionX;
  160. y = n->PositionY;
  161. printf("%f, %f\n", x, y);
  162. // auto sy = MakeEllipse(cdr, x, y, 5);
  163. // sy->Outline->Color->RGBAssign(255, 0, 0);
  164. // auto sj = MakeRectangle(cdr, x, y, 10, 10);
  165. // sj->Outline->Color->RGBAssign(0, 255, 0);
  166. auto l = DrawLine(cdr, x, y, s->CenterX, s->CenterY);
  167. srs->Add(l);
  168. }
  169. // HRESULT IVGShapeRange::CreateSelection ( );
  170. srs->CreateSelection();
  171. return true;
  172. }
  173. // 建立矩形和圆形函数原型
  174. // IVGShapePtr IVGLayer::CreateRectangle2 ( double x, double y, double Width,
  175. // double Height,
  176. // double RadiusUL, double RadiusUR, double RadiusLR,
  177. // double RadiusLL );
  178. // IVGShapePtr IVGLayer::CreateEllipse2 ( double CenterX, double CenterY,
  179. // double Radius1,
  180. // double Radius2, double StartAngle, double EndAngle,
  181. // VARIANT_BOOL Pie );
  182. IVGShapePtr MakeEllipse(corel *cdr, double x, double y, double r) {
  183. return cdr->ActiveLayer->CreateEllipse2(x, y, r, ZERO_4PC);
  184. }
  185. IVGShapePtr MakeEllipse(corel *cdr, IVGShapePtr s, double r) {
  186. double x, y;
  187. x = s->CenterX;
  188. y = s->CenterY;
  189. return cdr->ActiveLayer->CreateEllipse2(x, y, r, ZERO_4PC);
  190. }
  191. IVGShapePtr MakeRectangle(corel *cdr, double x, double y, double w, double h) {
  192. auto sj = cdr->ActiveLayer->CreateRectangle2(x, y, w, h, ZERO_4PC);
  193. sj->PutCenterX(x);
  194. sj->PutCenterY(y);
  195. return sj;
  196. }
  197. IVGShapePtr MakeRectangle(corel *cdr, IVGShapePtr s, double w, double h) {
  198. double x, y;
  199. x = s->CenterX;
  200. y = s->CenterY;
  201. auto sj = cdr->ActiveLayer->CreateRectangle2(x, y, w, h, ZERO_4PC);
  202. sj->PutCenterX(x);
  203. sj->PutCenterY(y);
  204. return sj;
  205. }
  206. // IVGShapePtr IVGLayer::CreateLineSegment ( double StartX, double StartY,
  207. // double EndX, double EndY ); 画一条线,设置轮廓色 M100
  208. IVGShapePtr DrawLine(corel *cdr, double x1, double y1, double x2, double y2) {
  209. auto line = cdr->ActiveLayer->CreateLineSegment(x1, y1, x2, y2);
  210. line->Outline->Color->CMYKAssign(0, 100, 0, 0);
  211. return line;
  212. }
  213. // IVGShapePtr IVGLayer::FindShape ( _bstr_t Name, enum cdrShapeType Type, long
  214. // StaticID, VARIANT_BOOL Recursive );
  215. // IVGShapePtr IVGLayer::CreateCurveSegment ( double StartX, double StartY,
  216. // double EndX, double EndY, double StartingControlPointLength,
  217. // double StartingControlPointAngle, double
  218. // EndingControlPointLength, double
  219. // EndingControlPointAngle );
  220. // IVGShapePtr IVGLayer::CreateCurveSegment2 ( double x1, double y1, double
  221. // StartingControlPointX, double StartingControlPointY,
  222. // double EndingControlPointX, double
  223. // EndingControlPointY, double x2,
  224. // double y2 );